
ماسح تكوين ثابت يكتشف تهيئات nginx المعرضة لخطأ التقاط-تجاوز المعقد ثنائي المسار (خريطة regex + التقاط regex → تجاوز سعة الكومة / تسرب معلومات).
ماسح ثابت للقراءة فقط يكتشف إعدادات nginx المعرّضة لخطأ فئة تصادم الالتقاط ثنائي المرور complex_value (استشارة F5/nginx SIRT، يوليو 2026). يقوم بتحليل إعداداتك ويبلّغ عن النمط المعرّض مع السبب والموقع. لا يستغل أي شيء ولا يمس الخادم قيد التشغيل.
ملف واحد، مكتبة قياسية فقط، Python 3.6+.
الشرح الكامل للثغرة: https://cyberstan.co.uk/nginx-rce/
يبني nginx العديد من قيم التوجيهات على مرحلتين. تقيس مرحلة LEN الطول وتخصص مخزنًا مؤقتًا، ثم تكتب مرحلة VALUE فيه. تُقرأ التقاطات التعبيرات النمطية ($1 إلى $9، أو المسمّاة (?P<name>...)) من حالة مشتركة لكل طلب. يشغّل map الذي يكون مفتاح مطابقته تعبيرًا نمطيًا مطابقة PCRE جديدة في اللحظة التي تُقيَّم فيها متغيّره، وتلك المطابقة تكتب فوق حالة الالتقاط المشتركة. إذا قِيس التقاط في مرحلة LEN ثم شُغّل map بتعبير نمطي قبل أن تعيد مرحلة VALUE كتابة ذلك الالتقاط، تختلف المرحلتان:
كلا الاتجاهين قابل للاستغلال عن بُعد عندما يكون مدخل map متأثرًا بالمهاجم ($request_body، $http_*، $arg_*، $uri، $ssl_preread_server_name، وما إلى ذلك).
يبلّغ الماسح عن موقع أو خادم عندما تلتقي كل هذه العناصر في مخزن مؤقت واحد ثنائي المرور، بالترتيب القابل للاستغلال:
location ~ بتعبير نمطي، أو server_name ~، أو rewrite، أو if (... ~ ...)، أو map بتعبير نمطي مع مجموعة التقاط.map (http أو stream) بمفتاح مطابقة تعبير نمطي ~ أو ~*، يُشار إليه بمتغيّر خرجه.return، set، add_header، proxy_method، proxy_pass، rewrite، index، وغيرها): كلا المرجعين في القيمة نفسها.proxy_set_header، proxy_set_body، fastcgi_param، scgi_param، uwsgi_param، grpc_set_header): تبني مخزنًا مؤقتًا واحدًا لكل طلب للعائلة بأكملها، لذا يمكن أن يكون المرجعان في توجيهات منفصلة في الموقع نفسه.# scan a single config (follows include directives by default)
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf
# scan a directory (uses nginx.conf if present, else all *.conf)
python3 nginx_capture_clobber_scan.py /etc/nginx/
# scan several roots
python3 nginx_capture_clobber_scan.py site-a.conf site-b.conf
# machine-readable output
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf --json
# do not expand include directives
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf --no-includes
| الخيار | التأثير |
|---|---|
--json | إخراج تقرير JSON بدلاً من النص. |
--no-includes | عدم اتباع توجيهات include. |
| الرمز | المعنى |
|---|---|
0 | لم يتم العثور على أي إعدادات قابلة للاستغلال. |
1 | تم العثور على إعداد واحد قابل للاستغلال على الأقل. |
2 | خطأ في الاستخدام (لم يتم إعطاء مسار، أو لم يتم العثور على أي مسار). |
قابل للاستخدام في CI، نظرًا لأن الإعداد القابل للاستغلال يُرجع رمز خروج غير صفري:
python3 nginx_capture_clobber_scan.py /etc/nginx/nginx.conf || echo "review needed"
يطبع وضع النص، لكل نتيجة: الملف والسطر، والنطاق المحيط، وتوجيه الـ sink،
ومتغيرات الالتقاط والـ map المعنية، والـ map المسبِّبة، وسببًا من سطر واحد. تسرد
قسمًا مُنقّحًا حالات التعايش بالترتيب الآمن. يُنتج --json:
{
"vulnerable": true,
"findings": [
{
"file": "/etc/nginx/conf.d/api.conf",
"line": 12,
"scope": "location ~ ^/api/(.+)$",
"directive": "proxy (family buffer)",
"captures": ["$1"],
"map_vars": ["$is_bot"],
"triggers": ["$is_bot <- regex-map on $http_user_agent [nginx.conf:30]"],
"reason": "..."
}
],
"cleared_safe_order": [],
"regex_maps": [],
"missing_includes": []
}
map بتعبير نمطي في نفس الموقع أو المخزن المؤقت مع
مرجع $1 إلى $9 أو مرجع التقاط مسمّى.(?P<name>...) عبر عدة خرائط regex.proxy_set_header أو
fastcgi_param.set الديناميكية.include غير القابلة للقراءة (على سبيل المثال المسارات المطلقة غير الموجودة
محليًا) تُبلَّغ ضمن missing_includes، ولا تُتخطّى بصمت. شغّله
على المضيف الذي يُحلّ فيه الإعداد للحصول على تغطية كاملة.تحليل الثغرة وسلسلة الاستغلال: https://cyberstan.co.uk/nginx-rce/