
Marco de pruebas diferenciales para implementaciones HTTP
The HTTP Garden es una colección de servidores y proxies HTTP configurados para ser componibles, junto con scripts para interactuar con ellos de una manera que facilita mucho la búsqueda de vulnerabilidades. Para ver algunas demostraciones interesantes de las vulnerabilidades que puedes encontrar con HTTP Garden, consulta nuestra charla en ShmooCon 2024.
Queremos agradecer a nuestros amigos de Galois, Trail of Bits, Narf Industries y Dartmouth College por hacer posible este proyecto.
Este material se basa en un trabajo respaldado por la Agencia de Proyectos de Investigación Avanzada de Defensa (DARPA) bajo el número de contrato HR0011-19-C-0076.
pip) o desde el gestor de paquetes de tu sistema:docker
pyyaml
tqdm
Si instalas los paquetes de Python con el gestor de paquetes de tu sistema, ten en cuenta que los nombres de los paquetes pueden necesitar el prefijo py3-, python3- o python-, dependiendo del sistema.
./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 | ✓
Parece que todos coinciden. (Ten en cuenta que, aunque Nginx añadió las cabeceras content-length y content-type, el Garden es consciente de ello y no permite que esta discrepancia insignificante aparezca en la salida de grid).
Probemos un payload que utiliza un final de línea LF simple en un cuerpo de mensaje fragmentado (chunked). Esto está prohibido en la especificación.
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 | ✓
Bien, entonces Gunicorn respondió 400, Hyper no respondió y Nginx aceptó. Esto es una violación de la especificación por parte de los autores de Nginx que no les importa corregir.
También habrás notado que, aunque Gunicorn y Hyper no tuvieron exactamente la misma respuesta, aparecían como coincidentes en la salida de grid anteriormente.
Esto se debe a que sus respuestas son esencialmente equivalentes (un rechazo del mensaje), y el Garden tiene esto en cuenta.
imagesEl directorio images contiene un subdirectorio para cada servidor HTTP y transductor del Garden.
Cada objetivo tiene su propia imagen Docker.
Todos los programas se compilan desde el código fuente cuando es posible.
Para poder compilar fácilmente múltiples versiones de cada objetivo, todos los objetivos están parametrizados con una URL de repositorio (APP_REPO), nombre de rama (APP_BRANCH) y hash de commit (APP_VERSION).
toolsEl directorio tools contiene los scripts que se utilizan para interactuar con los servidores. Dentro de él encontrarás
probe_quirks.py: Un script para enumerar las peculiaridades benignas de análisis HTTP en los sistemas bajo prueba que deben ignorarse durante el fuzzing,repl.py: La interfaz de usuario principal de HTTP Garden,update.py: Un script para actualizar los hashes de commit en 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 |
Las siguientes son explicaciones de algunas omisiones notables del Garden:
| Nombre | Justificación |
|---|---|
| Cualquier cosa de Microsoft | MSRC nos dijo que "el contrabando HTTP no se considera una vulnerabilidad", y no siento ninguna necesidad particular de ayudar a Microsoft. |
| unicorn | Utiliza el mismo analizador HTTP que yahns. |
| SwiftNIO | Utiliza llhttp para el análisis HTTP, que ya está cubierto por node_stdlib. |
| Bun | Utiliza picohttpparser para el análisis HTTP, que ya está cubierto por h2o. |
| Deno | Utiliza hyper para el análisis HTTP, que ya está en el Garden. |
| Daphne | Utiliza twisted para el análisis HTTP, que ya está en el Garden. |
| pitchfork | Utiliza el mismo analizador que yahns. |
| nghttpx | Utiliza lhttp para el análisis HTTP, que ya está cubierto por node_stdlib. |
| Cheroot | Ignora nuestros informes. |
| CherryPy | Utiliza cheroot para el análisis HTTP. |
| libhttpserver | Utiliza libmicrohttpd para el análisis HTTP, que ya está en el Garden. |
| Werkzeug | Utiliza la stdlib de CPython para el análisis HTTP, que ya está en el Garden. |
Consulta TROPHIES.md para obtener una lista completa de los errores que el Garden ha encontrado.
| Utiliza la stdlib de Go para el análisis HTTP, que ya está en el Garden. |
| Tengine | Utiliza el analizador HTTP de Nginx. |
| OpenResty | Utiliza el analizador HTTP de Nginx. |
| Google Cloud Global External Application Load Balancer | Basado en Envoy. |
| Google Cloud Regional External Application Load Balancer | Basado en Envoy. |
| Phusion Passenger | Utiliza llhttpd para el análisis HTTP, que ya está cubierto por node_stdlib. |
| passim | Utiliza libsoup para el análisis HTTP, que ya está en el Garden. |
| boa | Sin mantenimiento. |
| Ulfius | Utiliza libmicrohttpd, que ya está en el Garden. |
| Vultr Load Balancer | Es simplemente HAProxy, que ya está en el Garden. |
| VMWare Avi Load Balancer | Es simplemente Nginx, que ya está en el Garden. |
| Sanic | Utiliza httptools, que ya está cubierto por Uvicorn. |
| CPython http.server | No está pensado para uso en producción. |
| openjdk_stdlib | No proporciona un canal coherente de divulgación de vulnerabilidades. |
| dart_stdlib | Ignoró informes anteriores. |
| eventlet | La biblioteca HTTP es solo un fork de la de la stdlib de CPython. |
| uwsgi | No soporta cuerpos de mensaje fragmentados (chunked). |