Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 51

ASP.NET ViewState Güvenliği: Deserialization ve MAC Atlatma

Recommended resources

Merhaba! Önceki dersimizde, Java ekosistemindeki ifade dillerinin (SpEL, OGNL) gücünü ve bu gücün, güvenilmeyen girdilerle birleştiğinde nasıl yıkıcı Uzaktan Kod Çalıştırma (RCE) zafiyetlerine dönüştüğünü derinlemesine inceledik. Ana temamız, uygulamanın, bir string ifadeyi yorumlayarak "çalıştırdığı" noktalardaki tehlikeydi. Güvenilmeyen bir veriyi işleyip onu bir nesneye veya komuta dönüştürme problemi, platformlar arası ortak bir güvenlik açığıdır.

Bu dersimizde, bu temel sorunun .NET ekosistemindeki en klasik yansımalarından birine odaklanacağız. Bu dersin amacı, ASP.NET ViewState deserialization zafiyetlerini ve MAC (Message Authentication Code) koruması atlatma tekniklerini analiz etmektir. Java'daki ifade enjeksiyonu gibi, ViewState deserializasyonu da sunucuyu, istemciden gelen bir veri bloğunu güvenerek yorumlamaya ve işlemeye ikna etme üzerine kuruludur. Ancak burada mekanizma, bir ifade dilini yorumlamak yerine, serileştirilmiş bir nesne grafiğini "canlandırmaktır". Bu sürecin nasıl istismar edildiğini, koruma mekanizmalarını ve bu mekanizmaların nasıl aşıldığını kod ve konfigürasyon seviyesinde inceleyeceğiz.

ViewState: Web Formlarının Hafızası

Klasik ASP.NET Web Forms mimarisini anlamak için önce HTTP'nin durumsuz (stateless) doğasını hatırlamalıyız. Her HTTP isteği bir öncekinden bağımsızdır. Ancak bir web formunda, kullanıcı bir butona tıkladığında veya bir dropdown'dan seçim yaptığında, sayfanın diğer kontrollerinin (metin kutuları, checkbox'lar vb.) durumlarının korunması gerekir.

ASP.NET, bu sorunu ViewState ile çözer. ViewState, bir sayfanın ve kontrollerinin durumunu (değerleri, özellikleri vb.) temsil eden bir nesne ağacını serileştirir. Bu serileştirilmiş veri, genellikle Base64 ile kodlanarak __VIEWSTATE adlı gizli bir form alanına gömülür ve istemciye gönderilir. Kullanıcı sayfada bir eylem yaptığında (postback), tarayıcı bu __VIEWSTATE verisini sunucuya geri gönderir. Sunucu bu veriyi deserialize ederek sayfanın durumunu bir önceki adımdaki haline geri yükler ve ardından yeni isteği işler.

Bu mekanizma, geliştiriciler için durumu yönetmeyi kolaylaştırsa da, güvenlik açısından bariz bir soruyu gündeme getirir: Sunucu, istemciden gelen ve potansiyel olarak değiştirilmiş bu veri bloğuna nasıl güvenebilir?


Güvensiz Deserialization: Temel Zafiyet

ViewState'in temelindeki güvenlik riski, "Insecure Deserialization" olarak bilinen daha genel bir zafiyet sınıfından kaynaklanır. Bu konsepti daha geniş bir çerçevede anlamak için aşağıdaki kaynağı inceleyebilirsiniz.

Insecure Deserialization Zafiyeti: Nedir, Nasıl Çalışır ve Korunma ...

Bu makale, güvensiz deserialization zafiyetinin ne olduğunu, neden tehlikeli olduğunu ve genel etkilerini kapsamlı bir şekilde açıklıyor. ViewState'i anlamadan önce bu temel kavramları tazelemek faydalı olacaktır.

Makaleyi gözden geçirerek Giriş bölümünü okuyun. Ardından, "Mekanik" bölümünü inceleyerek serileştirme formatları arasındaki farklara dikkat edin. Son olarak, "Zafiyet" ve "Etkileri" bölümlerini okuyarak bir saldırganın bu güven varsayımını nasıl kırdığını ve RCE gibi sonuçlara nasıl ulaştığını anlayın.

Okuduğunuz gibi, bir uygulama güvenilmeyen bir kaynaktan gelen veriyi doğrulamadan deserialize ettiğinde, saldırganlar uygulamanın beklemediği türden nesneleri enjekte edebilirler. ViewState bağlamında bu, bir saldırganın, normal bir sayfa durumu nesnesi yerine, deserialize edildiğinde sunucuda kod çalıştıracak şekilde özel olarak hazırlanmış bir nesne gönderebileceği anlamına gelir.


ViewState Koruması: MAC ve machineKey

Elbette ASP.NET framework'ünü geliştirenler bu riskin farkındaydı. ViewState verisinin istemci tarafında değiştirilmesini önlemek için bir bütünlük ve kimlik doğrulama mekanizması geliştirdiler: Message Authentication Code (MAC).

Süreç şöyle işler:

  1. Sunucu, ViewState verisini oluşturduktan sonra, Web.config dosyasında tanımlı olan gizli bir anahtar (validationKey) kullanarak bu verinin kriptografik bir özetini (MAC) hesaplar.
  2. Bu MAC değeri, Base64 ile kodlanmış ViewState verisinin sonuna eklenir.
  3. İstek sunucuya geri geldiğinde, sunucu önce gelen ViewState verisinden MAC'i ayırır.
  4. Ardından, kalan veri ve gizli anahtarı kullanarak MAC'i yeniden hesaplar.
  5. Eğer sunucunun hesapladığı MAC ile istemciden gelen MAC eşleşirse, verinin değiştirilmediği ve aynı sunucu tarafından oluşturulduğu varsayılır. Eşleşmezse, istek bir hata ile reddedilir.

Bu korumanın tamamı, Web.config dosyasındaki <machineKey> elementinde tanımlanan validationKey ve (eğer şifreleme de aktifse) decryptionKey anahtarlarının gizliliğine dayanır.

<configuration>
  <system.web>
    <machineKey 
      validationKey="A2A06DE1343846435452182569B373A374438597988B46571199360F6234253A3587C81F020253D315438843E5115935F64993175442A27B32525547E975A9CB" 
      decryptionKey="C45B6A838C5AF158586A5E5B842183296234567890123456" 
      validation="SHA1" 
      decryption="AES" />
  </system.web>
</configuration>

MAC Korumasını Atlatma Teknikleri

Güvenliğin tamamen machineKey'in gizliliğine bağlı olması, saldırganların hedefini netleştirir: Bu anahtarı ele geçirmek veya korumanın devre dışı bırakıldığı bir durum bulmak.

1. MAC Korumasının Devre Dışı Bırakılması

Bu nadir görülen bir durum olsa da, geliştiriciler performans veya uyumluluk nedenleriyle MAC doğrulamasını manuel olarak kapatabilirler. Bu, bir kod denetimi sırasında aranması gereken kritik bir "smoking gun" (kesin kanıt) işaretidir.

  • ASPX Sayfa Direktifinde: <%@ Page EnableViewStateMac="false" %>
  • Web.config'de: <pages enableViewStateMac="false" />

Aşağıdaki görsel, bir web proxy aracının (örneğin Burp Suite) MAC korumasının etkin olmadığını nasıl tespit ettiğini göstermektedir. Bu, saldırgan için bir davetiyedir.

Bir web proxy arayüzünde, ViewState verisi incelendiğinde "[MAC is not enabled]" uyarısının görünmesi. Bu, sunucunun gönderilen ViewState'in bütünlüğünü doğrulamadığını ve manipülasyona açık olduğunu gösterir.

2. machineKey Sızıntısı ve İstismarı

Daha yaygın ve sofistike olan senaryo, MAC korumasının aktif olduğu ancak machineKey'in bir şekilde saldırgan tarafından ele geçirildiği durumdur. Anahtar sızdırıldığında, MAC koruması tamamen anlamsız hale gelir. Saldırgan artık kendi kötü niyetli ViewState payload'unu oluşturabilir, bunu sızdırılmış anahtarla imzalayabilir ve sunucuya gönderebilir. Sunucu, imza geçerli olduğu için payload'u güvenilir kabul edecektir.

Anahtar nasıl sızdırılabilir?

  • Zayıf veya Varsayılan Anahtarlar: Geliştiricilerin internetteki blog yazılarından veya dökümanlardan kopyaladığı statik anahtarlar. Saldırganlar bu bilinen anahtarları deneyebilir.
  • Konfigürasyon Dosyası Okuma Zafiyetleri: Bu, en tehlikeli senaryolardan biridir ve "exploit chaining" için harika bir örnektir. Örneğin, bir Yerel Dosya Dahil Etme (LFI) veya Dizin Geçişi (Path Traversal) zafiyeti, saldırganın Web.config dosyasını okumasına olanak tanıyabilir.

Aşağıdaki LinkedIn makalesi, tam olarak bu senaryoyu anlatan gerçek bir zafiyet zincirini analiz ediyor.

ECHO Haftalık Siber Tehdit Bülteni (13.10.2025) - LinkedIn

Bu bülten, bir LFI zafiyetinin, ViewState deserialization yoluyla RCE'ye nasıl zincirlendiğini gösteren mükemmel bir vaka çalışması sunuyor. Bu, konumuzun pratik uygulamasını anlamak için çok değerli bir örnek.

Makalede, "Haftanın LFI'dan RCE'ye Zinciri" bölümünü okuyun. Saldırının ilk adımı olarak CVE-2025-11371 (LFI) zafiyetinin, Web.config dosyasını okumak için nasıl kullanıldığına dikkat edin. Ardından, Teknik Detay bölümündeki adımları takip edin. Bu bölüm, sızdırılan machineKey'in, CVE-2025-30406 (ViewState Deserialization) zafiyetini tetiklemek için nasıl kullanıldığını net bir şekilde açıklıyor. Son olarak, "Zafiyetin Kodları Fonksiyonları" altındaki açıklamayı okuyarak, .NET'in ObjectStateFormatter sınıfının bu saldırıdaki rolünü öğrenin.

Bu vaka çalışmasının gösterdiği gibi, bir saldırgan machineKey'i ele geçirdiğinde, oyunun son aşamasına geçebilir: Kötü niyetli bir payload oluşturmak.


Payload Oluşturma ve RCE

Tıpkı Java dünyasında ysoserial aracının bilinen gadget zincirlerini kullanarak RCE payload'ları oluşturması gibi, .NET ekosisteminde de ysoserial.net adlı bir araç aynı işlevi görür.

Saldırgan, sızdırdığı decryptionKey ve validationKey'i ysoserial.net'e vererek, belirli bir "gadget chain" (örneğin, WindowsIdentity veya TextFormattingRunProperties) kullanarak komut çalıştıracak bir ViewState payload'u oluşturur.

Aşağıdaki görsel, bu sürecin bir parçasını özetlemektedir: Bir araç kullanılarak machineKey'lerin elde edilmesi ve ardından ysoserial.net ile bir payload oluşturma talimatı.

Bir komut satırı aracının çıktısı. Araç, şifrelenmiş bir veriden `DecryptionKey` ve `ValidationKey`'i başarıyla bulduğunu gösteriyor. Son adım olarak, bulunan bu anahtarları kullanarak `ysoserial.net` ile bir deserialization payload'u oluşturulmasını tavsiye ediyor.

Saldırgan bu payload'u oluşturduktan sonra, onu Base64 ile kodlar, __VIEWSTATE parametresine yerleştirir ve hedef uygulamaya bir istek gönderir. Sunucu bu isteği aldığında:

  1. MAC'i doğrular (başarılı olur, çünkü saldırgan doğru anahtarı kullandı).
  2. Payload'u deserialize eder.
  3. Deserialization işlemi sırasında, ysoserial.net tarafından oluşturulan gadget zinciri tetiklenir ve gömülü komut (whoami, reverse shell vb.) w3wp.exe işlemi bağlamında çalıştırılır.

Kod Denetimi Perspektifi

Bir kod denetçisi olarak ViewState deserializasyon risklerini ararken odaklanmanız gerekenler:

  1. Web.config Analizi:
    • <machineKey> elementi var mı? Anahtarlar sabit kodlanmış mı? Zayıf veya internetten alınmış gibi görünüyorlar mı?
    • <pages enableViewStateMac="..." /> veya <@ Page EnableViewStateMac="..." %> direktifleri false olarak ayarlanmış mı?
    • Uygulamanın Web.config dosyasını okuyabilecek herhangi bir LFI/Path Traversal zafiyeti var mı? Bu, anahtar sızıntısı riskini artırır.
  2. ObjectStateFormatter Kullanımı: Genellikle ViewState'in işlenmesi framework tarafından örtük olarak yapılır. Ancak, bir geliştirici manuel olarak ObjectStateFormatter sınıfını kullanarak bir yerden gelen veriyi deserialize ediyorsa, bu doğrudan bir zafiyet noktasıdır ve girdi kaynağının güvenilirliği sorgulanmalıdır.

Özet ve Sonraki Adımlar

Bu dersimizde, ASP.NET'in durum yönetimi mekanizması olan ViewState'in, temelinde bir deserialization işlemi olduğunu ve bu nedenle güvensiz deserialization zafiyetlerine açık olabileceğini gördük.

Anahtar Çıkarımlar:

  • ViewState Bir Güven Sınırıdır: İstemciden gelen __VIEWSTATE verisi, güvenilmeyen bir girdidir.
  • MAC Koruması Kritik Öneme Sahiptir: ViewState'in güvenliği, bütünlüğünü sağlayan MAC mekanizmasına bağlıdır.
  • Anahtar Her Şeydir: MAC mekanizmasının güvenliği, machineKey'in gizliliğine bağlıdır. Bu anahtarın sızdırılması, korumayı tamamen etkisiz hale getirir.
  • Zincirleme Saldırılar: ViewState istismarı, genellikle LFI gibi başka bir zafiyetle Web.config dosyasının okunması sonucu elde edilen machineKey ile gerçekleştirilir. Bu, bulguları birleştirmenin gücünü gösterir.
  • Araçlar: ysoserial.net, bilinen anahtarlarla RCE payload'ları oluşturmak için standart bir araçtır.

Java'da SpEL/OGNL enjeksiyonlarını ve şimdi de .NET'te ViewState deserializasyonunu inceledik. Farklı platformlar, farklı mekanizmalar, ancak temel sorun aynı: Güvenilmeyen veriyi tehlikeli bir şekilde yorumlamak.

Bir sonraki dersimizde, tekrar Java ve Spring ekosistemine döneceğiz. Ancak bu kez, doğrudan bir enjeksiyon veya deserialization zafiyetine değil, modern uygulamaların temel taşlarından biri olan güvenlik framework'lerinin yanlış yapılandırılmasına odaklanacağız. Spring Security konfigürasyonlarında yanlış yapılandırılmış filtre zincirleri üzerinden kimlik doğrulama ve yetkilendirme atlatmalarını analiz edeceğiz. Bu konu, Web.config gibi konfigürasyon dosyalarının güvenliği nasıl etkilediğiyle ilgili bu derste edindiğimiz bakış açısını daha da ileri taşıyacak.