
إطار عمل للاختبار التفاضلي لتنفيذات HTTP
تُعد HTTP Garden مجموعة من خوادم HTTP ووكلائها المصممة لتكون قابلة للتكوين، إلى جانب سكربتات للتفاعل معها بطريقة تجعل اكتشاف الثغرات أسهل بكثير. لعرض بعض العروض الممتعة للثغرات التي يمكنك اكتشافها باستخدام HTTP Garden، شاهد محادثتنا في ShmooCon 2024.
نود أن نشكر أصدقاءنا في Galois، وTrail of Bits، وNarf Industries، وDartmouth College لجعل هذا المشروع ممكنًا.
هذه المادة مبنية على عمل مدعوم من وكالة مشاريع الأبحاث الدفاعية المتقدمة (DARPA) بموجب رقم العقد HR0011-19-C-0076.
pip) أو من مدير الحزم لنظامك:docker
pyyaml
tqdm
إذا كنت تثبّت حزم بايثون عبر مدير الحزم لنظامك، فاعلم أن أسماء الحزم قد تحتاج إلى بادئة py3- أو python3- أو python-، حسب النظام.
./garden.sh start --build gunicorn hyper nginx haproxy
./garden.sh repl
garden> payload 'GET / HTTP/1.1\r\nHOST: a\r\n\r\n' | transduce haproxy | fanout | grid
'GET / HTTP/1.1\r\nHOST: a\r\n\r\n'
⬇️ haproxy
'GET / HTTP/1.1\r\nhost: a\r\n\r\n'
gunicorn: [
HTTPRequest(
method=b'GET', uri=b'/', version=b'1.1',
headers=[
(b'host', b'a'),
],
body=b'',
),
]
hyper: [
HTTPRequest(
method=b'GET', uri=b'/', version=b'1.1',
headers=[
(b'host', b'a'),
],
body=b'',
),
]
nginx: [
HTTPRequest(
method=b'GET', uri=b'/', version=b'1.1',
headers=[
(b'host', b'a'),
(b'content-length', b''),
(b'content-type', b''),
],
body=b'',
),
]
g
u
n
i h n
c y g
o p i
r e n
n r x
+-----
gunicorn|✓ ✓ ✓
hyper | ✓ ✓
nginx | ✓
يبدو أن جميعها متوافقة. (لاحظ أنه على الرغم من أن Nginx أضاف ترويسات content-length وcontent-type، فإن الحديقة تدرك ذلك ولا تسمح لهذا الاختلاف غير المهم بالظهور في مخرجات grid.)
لنجرّب حمولة تستخدم نهاية سطر بـ LF فقط في نص رسالة مقسّمة (chunked). هذا غير مسموح به في المواصفة.
garden> payload 'POST / HTTP/1.1\r\nHost: a\r\nTransfer-Encoding: chunked\r\n\r\n0\n\r\n' | fanout | grid
gunicorn: [
HTTPResponse(version=b'1.1', method=b'400', reason=b'Bad Request'),
]
hyper: [
]
nginx: [
HTTPRequest(
method=b'POST', uri=b'/', version=b'1.1',
headers=[
(b'transfer-encoding', b'chunked'),
(b'host', b'a'),
(b'content-length', b'0'),
(b'content-type', b''),
],
body=b'',
),
]
g
u
n
i h n
c y g
o p i
r e n
n r x
+-----
gunicorn|✓ ✓ X
hyper | ✓ X
nginx | ✓
حسنًا، استجاب Gunicorn بـ 400، ولم يستجب Hyper، بينما قبِل Nginx الرسالة. هذا مخالفة للمواصفة من مؤلفي Nginx وهم لا يهتمون بإصلاحها.
ربما لاحظت أيضًا أنه على الرغم من أن استجابتي Gunicorn وHyper لم تكونا متطابقتين تمامًا، فقد ظهرتا كمتوافقتين في مخرجات grid سابقًا.
ذلك لأن استجاباتهما مكافئة جوهريًا (رفض الرسالة)، وتأخذ الحديقة هذا في الاعتبار.
imagesيحتوي دليل images على دليل فرعي لكل خادم HTTP ومحوّل في الحديقة.
يحصل كل هدف على صورة Docker خاصة به.
تُبنى جميع البرامج من المصدر عند الإمكان.
ولتسهيل بناء إصدارات متعددة من كل هدف، تُحدَّد معاملات جميع الأهداف برابط المستودع (APP_REPO) واسم الفرع (APP_BRANCH) وقيمة الالتزام (APP_VERSION).
toolsيحتوي دليل tools على السكربتات المستخدمة للتفاعل مع الخوادم. ستجد بداخله:
probe_quirks.py: سكربت لتعداد الشذوذات غير المؤذية في تحليل HTTP في الأنظمة قيد الاختبار بحيث يتم تجاهلها أثناء التلغيم (fuzzing)،repl.py: واجهة المستخدم الأساسية لـ HTTP Garden،update.py: سكربت لتحديث قيم الالتزام في docker-compose.yml،|-| | aiohttp | | apache_httpd | | apache_tomcat | | appweb | | aws_c_http | | cpp_httplib | | eclipse_grizzly | | eclipse_jetty | | fasthttp | | go_stdlib | | gunicorn | | h2o | | haproxy_fcgi | | hyper | | hypercorn | | ktor | | libevent | | libmicrohttpd | | libsoup | | lighttpd | | mongoose | | netty | | nginx | | node_stdlib | | openbsd_httpd | | openlitespeed | | openwrt_uhttpd | | protocol_http1 | | puma | | tornado | | | | | | | | | | | | |
|-| | apache_httpd_proxy | | apache_traffic_server | | envoy | | go_stdlib_proxy | | h2o_proxy | | haproxy | | lighttpd_proxy | | nghttpx | | nginx_proxy | | openlitespeed_proxy | | pound | | squid | | varnish | | yahns_proxy |
فيما يلي شرح لبعض الاستثناءات البارزة من الحديقة:
انظر TROPHIES.md للحصول على قائمة كاملة بالثغرات التي عثرت عليها الحديقة.
| الاسم | السبب |
|---|
| أي شيء من Microsoft | أخبرتنا MSRC أن «HTTP smuggling لا يُعتبر ثغرة أمنية»، ولا أشعر بحاجة خاصة لمساعدة Microsoft. |
| unicorn | يستخدم محلّل HTTP نفسه المستخدم في yahns. |
| SwiftNIO | يستخدم llhttp لتحليل HTTP، وهو مغطى بالفعل بواسطة node_stdlib. |
| Bun | يستخدم picohttpparser لتحليل HTTP، وهو مغطى بالفعل بواسطة h2o. |
| Deno | يستخدم hyper لتحليل HTTP، وهو موجود بالفعل في الحديقة. |
| Daphne | يستخدم twisted لتحليل HTTP، وهو موجود بالفعل في الحديقة. |
| pitchfork | يستخدم المحلّل نفسه المستخدم في yahns. |
| nghttpx | يستخدم lhttp لتحليل HTTP، وهو مغطى بالفعل بواسطة node_stdlib. |
| Cheroot | يتجاهل تقاريرنا. |
| CherryPy | يستخدم cheroot لتحليل HTTP. |
| libhttpserver | يستخدم libmicrohttpd لتحليل HTTP، وهو موجود بالفعل في الحديقة. |
| Werkzeug | يستخدم المكتبة القياسية لـ CPython لتحليل HTTP، وهي موجودة بالفعل في الحديقة. |
| Caddy | يستخدم المكتبة القياسية لـ Go لتحليل HTTP، وهي موجودة بالفعل في الحديقة. |
| Tengine | يستخدم محلّل HTTP الخاص بـ Nginx. |
| OpenResty | يستخدم محلّل HTTP الخاص بـ Nginx. |
| Google Cloud Global External Application Load Balancer | مبني على Envoy. |
| Google Cloud Regional External Application Load Balancer | مبني على Envoy. |
| Phusion Passenger | يستخدم llhttpd لتحليل HTTP، وهو مغطى بالفعل بواسطة node_stdlib. |
| passim | يستخدم libsoup لتحليل HTTP، وهو موجود بالفعل في الحديقة. |
| boa | لم يعد يُصان. |
| Ulfius | يستخدم libmicrohttpd، وهو موجود بالفعل في الحديقة. |
| Vultr Load Balancer | إنه في الأساس HAProxy، وهو موجود بالفعل في الحديقة. |
| VMWare Avi Load Balancer | إنه في الأساس Nginx، وهو موجود بالفعل في الحديقة. |
| Sanic | يستخدم httptools، وهو مغطى بالفعل بواسطة Uvicorn. |
| CPython http.server | غير مخصص للاستخدام في الإنتاج. |
| openjdk_stdlib | لا يوفر قناة واضحة للإبلاغ عن الثغرات. |
| dart_stdlib | تجاهل التقارير السابقة. |
| eventlet | مكتبة HTTP الخاصة به هي مجرد نسخة مشتقة من تلك الموجودة في المكتبة القياسية لـ CPython. |
| uwsgi | لا يدعم أجسام الرسائل المقسّمة (chunked). |