
إطار عمل للاختبار التفاضلي لتنفيذات 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 | | twisted | | undertow | | uvicorn | | waitress | | webrick | | yahns |
|-| | 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 |
فيما يلي شرح لبعض الاستثناءات البارزة من الحديقة: