The HTTP Garden 是一个可组合的 HTTP 服务器和代理的集合,附带用于与它们交互的脚本,让发现漏洞变得容易得多。想看看使用 HTTP Garden 可以发现哪些漏洞的酷炫演示,请查看我们的 ShmooCon 2024 演讲。
我们感谢 Galois、Trail of Bits、Narf Industries 和 Dartmouth College 的朋友们,让这个项目成为可能。
本材料基于国防高级研究计划局(DARPA)在合同号 HR0011-19-C-0076 下支持的工作。
pip)或系统包管理器获取:docker
pyyaml
tqdm
如果你使用系统包管理器安装 Python 包,请注意包名可能需要根据系统加上 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 头,Garden 也能感知这一点,并且不会让这个无关紧要的差异显示在 grid 输出中。)
让我们尝试一个在分块消息体中使用裸 LF 行结尾的 payload。这在规范中是不允许的。
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 输出中也显示为一致。
这是因为它们的响应本质上等价(都是拒绝该消息),而 Garden 会考虑到这一点。
imagesimages 目录为 Garden 中的每个 HTTP 服务器和转换器(transducer)包含一个子目录。
每个目标都有自己的 Docker 镜像。
所有程序在可能的情况下都会从源码构建。
为了便于构建每个目标的多个版本,所有目标都通过仓库 URL(APP_REPO)、分支名(APP_BRANCH)和提交哈希(APP_VERSION)进行参数化。
toolstools 目录包含用于与服务器交互的脚本。在其中,你会找到
probe_quirks.py:一个用于枚举被测系统中无害的 HTTP 解析怪癖的脚本,以便在模糊测试期间忽略它们,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 |
以下是对 Garden 中几个显著遗漏项的解释: