
HTTP 구현체를 위한 차등 테스트 프레임워크
HTTP Garden은 구성 가능하도록 설계된 HTTP 서버와 프록시 모음으로, 취약점을 훨씬 쉽게 찾을 수 있는 방식으로 이들과 상호작용하는 스크립트를 함께 제공합니다. HTTP Garden으로 찾을 수 있는 취약점에 대한 멋진 데모를 보려면 ShmooCon 2024 발표를 확인하세요.
이 프로젝트를 가능하게 해 주신 Galois, Trail of Bits, Narf Industries, Dartmouth College의 친구들에게 감사드립니다.
이 자료는 계약 번호 HR0011-19-C-0076에 따라 국방고등연구계획국(DARPA)의 지원을 받은 작업을 기반으로 합니다.
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 줄바꿈을 사용하는 페이로드를 시도해 보겠습니다. 이는 사양에서 허용되지 않습니다.
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 서버와 트랜스듀서별 하위 디렉터리가 포함되어 있습니다.
각 대상은 자체 Docker 이미지를 갖습니다.
가능한 경우 모든 프로그램은 소스에서 빌드됩니다.
각 대상의 여러 버전을 쉽게 빌드할 수 있도록 모든 대상은 저장소 URL(APP_REPO), 브랜치 이름(APP_BRANCH), 커밋 해시(APP_VERSION)로 파라미터화되어 있습니다.
toolstools 디렉터리에는 서버와 상호작용하는 데 사용되는 스크립트가 포함되어 있습니다. 그 안에는 다음이 있습니다:
probe_quirks.py: 퍼징 중 무시할 테스트 대상 시스템의 무해한 HTTP 파싱 특성(quirks)을 열거하는 스크립트,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에서 눈에 띄게 제외된 몇 가지 항목에 대한 설명입니다: