Seni Ben Unutmak İçin Sevmedim Cross Protocol Request Forgery (CPRF)

Kategori: Web Güvenliği - Güncellenme: 30 Nisan 2018 - Netsparker Security Team

Nisan ayında yayınlanan bir makale tarihin tozlu raflarında unutulmaya yüz tutmuş bir saldırı vektörünü bizlere yeniden hatırlattı. Fakat bu defa yeni bir ad ile: Cross Protocol Request Forgery

‘Aranızdan Biri Bana İhanet Edecek!’

Nereden çıktı CPRF?

Biraz daha geriye gidelim ve temel birkaç konsepte, CSRF ve SSRF 'e göz atalım…

CSRF (Cross-Site Request Forgery) yani siteler arası istek sahteciliği, kullanıcı browserından hedefe yönelen her isteğe Cookie ya da browserdaki credentialsların eklenmesinden hareketle, hedefteki bir durumun, tarayıcı tarafından gönderilen bu yetkiler ile değiştirilebilmesi zafiyetine verilen isimdir.

SSRF (Server-Side Request Forgery) ise sistemin kullanıcıdan ya da etkileşimde olduğu kaynaktan beklediği veri ile gerek sunucunun kendi iç ağındaki bir adrese yahut başka bir kaynağa istek yapılmasının sağlandığı bir zafiyet türüdür.

CPRF ise HTTP türünde olmayan bir servise istek yapılmasını sağlamak ve gerek isteğin kendisi ile state değişikliği yaparak, yahut dönen yanıtın tarayıcı da yanlış yorumlanmasını sağlayarak XSS vb. Zafiyetleri tetiklemek yoluyla istismar edilebilen bir zafiyettir.

İlk olarak 2001 yılında The HTML Form Protocol Attack adı ile Jochen Topf tarafından raporlanan zafiyet aşağıdaki şekilde gerçekleşmekte idi:

<form method="post" action="http://victim.example.com:25"> 
<textarea name="foo">
HELO example.com 
MAIL FROM:<somebody@example.com> 
RCPT TO:<recipient@example.org> 
DATA 
Subject: Hi there! 
From: somebody@example.com 
To: recipient@example.org

Hello world! 
. 
QUIT 
</textarea
 <input type="submit" value="Send it!">
</form>

Yukarıdaki isteğe cevaben, aşağıdaki gibi bir yanıt alabilecektiniz:

220 mail.example.org ESMTP Hi there!
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
500 Command unrecognized
250 mail.example.org Hello example.com [10.11.12.13]
250 <somebody@example.com> is syntactically correct
250 <recipient@example.org> is syntactically correct
354 Enter message, ending with "." on a line by itself
250 OK id=15IYAS-00073G-00
221 mail.example.org closing connection

500 Command unrecognized hatası HTTP Request'ine browser tarafından otomatik olarak eklenen istek headerlarından kaynaklanmaktadır. Yine bu yanıt headerlardan yoksun olduğu için tarayıcıda muhtemelen görüntülenmeyecektir. Görüntülensin ya da görüntülenmesin görünen o ki yukarıdaki istek ile saldırgan muradına ermiş, mail sunucusu üzerinden e-posta göndermeyi başarmıştır.

Benzer şekilde bu tarz yanıtlarda HTTP'nin güncel spesifikasyonlarına uygun bir yanıt başlığı yok, dolayısıyla browserlar tarafından görüntülenemeyecekler. Fakat tarayıcı HTTP 0.9 gibi başlık bilgilerinin henüz söz konusu olmadığı HTTP sürümünü destekliyor ise content sniffing ile hata mesajındaki script kodları da tarayıcı tarafından çalıştırılarak yukarıdaki istek XSS zafiyetine yol açabilir.

Yukarıda zikredilen atak vektörleri dolayısıyla bu tarz risklere yol açabilecek portlara erişim modern tarayıcılarda engellenmiş durumda.

Engelli olan bu protokollere istek yapabilmek mümkün mü? Evet, XHR ile!

XHR yani XMLHttpRequest nesnesi ile, banlanan bu portlar da dahil olmak üzere pek çok noktaya istek yapabilirsiniz. Elbette CORS ile düzenlenen şartlar ve Same Origin Policy'in yönettiği kurallar dahilinde.

Eğer gerçekleştirmek istediği saldırıda yanıtın okunmasının bir önemi yoksa, saldırgan XHR kullanarak ağdaki farklı protokoller kullanan diğer sistemlere de istek yapabilir. Örneğin bugün en çok konuşulan konulardan biri olan IoT cihazlarına.

Bu cihazlar genellikle iç bir ağda konumlanacağı ve dışarıdan gelen saldırılara kapalı olabileceği varsayımından hareketle muhtemel saldırı senaryoları hesap edilmeden ya da yeterince ehemmiyet verilmeden dizayn edilen ve iç ağda konumlandırılan sistemlerdir.

Oysa yukarıda saydığımız vektörler sayesinde bir tarayıcı yolu ile ya da sistemde bulunan bir girdi noktası vasıtasıyla iç ağdaki, firewall arkasındaki bir sisteme ulaşabilirsiniz

var x = new XMLHttpRequest();
x.open("POST","http://localhost:2000");
x.send("whoami > /tmp/test.txt\n");

Yukarıdaki istek gönderildiğinde, browser tarafından eklenen headerlar ile aşağıdaki şekle dönüşecek:

POST / HTTP/1.1
Host:localhost:2000
Connection: keep-alive
Content-Length:23
Origin:http://www.example.com
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Content-Type:text/plain;charset=UTF-8
Accept:*/*
Referer:http://www.example.com/
Accept-Encoding:gzip, deflate, br

whoami > /tmp/test.txt

İstek, listener tarafından yakalandığında aşağıdaki şekilde yorumlanacak:

$ POST / HTTP/1.1 
/bin/sh: 8: POST: not found 
$ Host: localhost:2001 
/bin/sh: 9: Host:: not found 
$ Content-Length:23 
/bin/sh: 11: Content-Length:: not found 
... 
$ whoami > /tmp/test.txt

HTTP istek headerı olarak eklenen POST, Host, Content-Length gibi değerlerin sistem tarafından yorumlanamadığını ama hata töleranslı bu sistemin isteğin body kısmında gönderilen komutu çalıştıracağı görülüyor.

CSPF ile iletişim kurabileceğiniz custom protokoller IoT cihazlarından, cep telefonlarına, database sistemlerinden, geliştirme araçları ve dahili web uygulamalarına kadar geniş bir yelpazede.

Makalede iç ağda konumlanan bu sistemlerin tespitine dair WebRTC gibi iç IP'leri leak eden yöntemlerin kullanılabileceği, erken sonlandırılan bağlantılara karşı XHR değil de çiçeği burnunda(!) fetch'in önerildiği çok değerli ipuçları mevcut.

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

Netsparker

Tam isabet, hızlı ve kolay kullanım

DEMO SÜRÜMÜNÜ İNDİR