Her HTTP isteğinin içinde küçük bir satır var. “Host” başlığı.
Tarayıcın bir siteye giderken sunucuya “ben şuraya geldim” diyor. Tek bir sunucuda yüzlerce site barınabildiği için sunucu hangisini istediğini bu satırdan anlıyor.
Ama bazı uygulamalar bu başlığa fazla güveniyor.
Host başlığı tamamen kullanıcının kontrolünde. İstersen oraya kendi domainini yazarsın sunucu da onu doğru sanıp kullanır. İşte Host Header Injection tam burada başlıyor.
Peki uygulama bu başlığı nerede kullanırsa tehlikeye girer derseniz en klasik yer parola sıfırlama.
Şifreni unuttun “parolamı sıfırla” diyorsun. Sunucu sana bir mail atıyor içinde bir link var. O linkin domainini nereden alıyor? Bazı uygulamalar kendi adresini Host başlığından çekiyor.
Saldırgan Host’u kendi sunucusuna çevirirse sıfırlama linki de onun sunucusuna gider.
Bu açığı görmek için Burp Suite yeter. PortSwigger Web Security Academy’nin Basic password reset poisoning lab’ında göstereceğim.

Lab’da kurbanımız “carlos”. Görev onun hesabını ele geçirmek. Bir de yanında “exploit server” veriyor.
Önce login sayfasına gidip “Forgot password?” diyorsun. carlos’un kullanıcı adını yazıp isteği gönderiyorsun.

Burp bu isteği yakalıyor.

İsteği Repeater’a atıyorsun. Çünkü orada Host başlığını rahatça değiştirip tekrar tekrar deneyebiliyorsun.
Host satırını buluyorsun. Lab’ın kendi adresi yazıyor.

Burada küçük bir tuzak var. Modern lab’lar isteği HTTP/2 olarak gönderiyor. HTTP/2’de host bilgisi normal Host: satırında değil gizli :authority alanında duruyor. O yüzden sadece Host satırını değiştirirsen Host header not present diye 400 dönebilir.
Repeater’da isteğin sağ üstündeki ayar ikonundan HTTP versiyonunu HTTP/1 yap. Artık Host satırı normal çalışıyor.
Bir uyarı daha Host değerine sadece hostname yaz. Başına “https://” sonuna “/exploit” gibi şeyler ekleme yoksa yine geçersiz sayılıyor.
Host satırını silip exploit server’ın adresini yazıyorsun.
Host: SENIN-ID.exploit-server.net
Send’e basıyorsun.

Sunucu 200 dönüyor. İsteği kabul etti.
Arka planda ne oluyor? Sunucu carlos kullanıcısına sıfırlama maili atıyor ve linkin domainini bizim yazdığımız Host’tan alıyor. Yani link artık bizim exploit server’ı gösteriyor.
carlos o maili açıp linke tıklıyor (lab bunu otomatik simüle ediyor). Tıkladığı an sıfırlama token’ı bizim sunucumuza düşüyor.
Token’ı nerede görüyoruz? Exploit server’ın access log kısmında.

Log’da carlos’un GET isteğini ve içindeki token’ı görüyorsun. Bu token sıfırlama sayfasının anahtarı.
Şimdi o token’ı alıp normal sıfırlama linkine yapıştırıyorsun. Açılan formda carlos’un şifresini değiştirebilirsin.

Token işe yaradı ve şifre değiştirildi.

“Congratulations, you solved the lab”
Tespit kısmı bu kadar aslında. Tek yaptığın Host başlığını değiştirip yanıtın ya da uygulamanın davranışının değişip değişmediğine bakmak. Sayfada görünüyorsa ya da mail linkine giriyorsa açık var demektir.
Bir de bazı uygulamalar Host’u filtreliyor ama “X-Forwarded-Host” başlığını unutuyor. O yüzden Host çalışmazsa isteğe şunu eklemeyi dene.
X-Forwarded-Host: saldirgan.com
Çoğu zaman filtre Host’a bakıyor ama bu başlığa bakmıyor aynı açık orada olabiliyor.
Korunma tarafı ise sunucu mutlak adresini asla Host başlığından almasın. Sabit bir domain listesi tutsun ya da konfigürasyondan okusun. Kullanıcının gönderdiği başlığa güven olmaz.
Kaynaklar
https://portswigger.net/web-security/host-header
https://portswigger.net/web-security/host-header/exploiting/password-reset-poisoning