
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 |