
Escáner HTTP(S) asíncrono que busca cadenas o expresiones regulares en los cuerpos y cabeceras de las respuestas en hosts, puertos, rangos CIDR y vhosts con certificados TLS.
# Descripción
Una herramienta Python rápida y asíncrona que escanea servidores HTTP(S) y
busca cadenas o patrones regex en cuerpos y cabeceras de respuestas HTTP.
Acepta hosts individuales, URLs, rangos CIDR, rangos IP o archivos; escanea
múltiples puertos por objetivo (único, listas separadas por comas o rangos,
auto-detectando TLS o plano por puerto); puede extraer y escanear (v)hosts
basados en nombre directamente de los certificados TLS; transmite las
coincidencias en vivo al terminal; y puede escribir los resultados en archivos
de registro de texto, CSV o JSONL.
Está diseñado para escaneos grandes: un núcleo asíncrono impulsa miles de
conexiones concurrentes, un pre-vuelo TCP descarta puertos muertos de forma
económica, los tiempos de espera por host y globales evitan que se cuelgue en
objetivos lentos/muertos, y una ejecución interrumpida puede reanudarse.
# Requisitos
- Python 3.11+ en un sistema POSIX (Linux, \*BSD, macOS - usa `termios` y el
manejo de señales Unix de asyncio)
- [httpx](https://pypi.org/project/httpx/) - `pip install -r requirements.txt`
(o `pip install httpx`)
- opcionales, se usan automáticamente si están presentes: `uvloop` (bucle de
eventos más rápido), `aiodns` (dns no bloqueante para `-r`), `h2` (HTTP/2 para
`-2`), `httpx[socks]` / socksio (proxies SOCKS)
httpgrep es un único script autocontenido - simplemente ejecute `./httpgrep.py`.
# Uso
```
$ httpgrep -H
__ __ __
/ /_ / /_/ /_____ ____ _________ ____
/ __ \/ __/ __/ __ \/ __ `/ ___/ _ \/ __ \
/ / / / /_/ /_/ /_/ / /_/ / / / __/ /_/ /
/_/ /_/\__/\__/ .___/\__, /_/ \___/ .___/
/_/ /____/ /_/
--== [ by nullsecurity.net ] ==--
uso
httpgrep -h <arg> -s <arg> [opts] | <misc>
opciones de objetivo
-h <hosts|archivo> - host/url único o rango de hosts-/cidr o archivo que
contenga hosts o archivo que contenga URLs, ej.: foobar.net,
192.168.0.1-192.168.0.254, 192.168.0.0/24, /tmp/hosts.txt
también funciona una lista de hosts separada por comas, ej.:
1.2.3.4,foo.net,10.0.0.0/24
NOTA: los hosts también pueden contener ':<puertos>' en la
línea de comandos o en el archivo, donde <puertos> es un
único puerto, lista separada por comas o rango, ej.:
foo.net:8080, foo.net:80,443, 10.0.0.1:1-1024
-p <puertos|archivo> - puerto(s) a los que conectarse: un único puerto, lista
separada por comas, rango, o un archivo con una
especificación por línea, ej.: 80, 80,443,8080, 8000-8100,
/tmp/ports.txt
(por defecto: 80, o 443 cuando se da -t)
-t - forzar TLS/SSL en todos los puertos. por defecto el esquema
se auto-detecta por puerto (http plano, cambiando a TLS si
el puerto lo habla)
-u <URI|archivo> - URI o URIs separadas por comas o archivo con URIs (una por
línea) donde buscar las cadenas dadas, ej.: /foobar/,
/foo.html, /admin,/login, /tmp/paths.txt (por defecto: /)
-r - mostrar el nombre de reverse-dns (PTR) de los IPv4
escaneados como etiqueta; la ip sigue siendo el objetivo
del escaneo (sin desvío de alcance). no bloqueante con el
paquete aiodns
opciones http
-X <método> - método de petición HTTP a usar, cualquier mayúscula/
minúscula (por defecto: get). use '?' para listar los
métodos disponibles.
-a <user:pass> - credenciales de autenticación http (formato: 'user:pass')
-U <UA> - establecer User-Agent personalizado (por defecto: último
ms edge, windows)
-A - usar user-agent aleatorio por petición
-R <cabeceras> - establecer cabeceras personalizadas (formato:
'foo=bar;lol=lulz;...')
-C <cookies> - establecer cookies (formato: 'foo=bar;lol=lulz;...')
-F - no seguir redirecciones HTTP
-L <num> - máximo de redirecciones a seguir (por defecto: 10; se
ignora con -F)
-E - verificar certificados TLS/SSL (por defecto: sin
verificación)
-P <proxy> - usar proxy (formato: '[http|https|socks4|socks5]://host:port')
(socks necesita el paquete 'httpx[socks]' / socksio)
-f <códigos> - solo informar de respuestas con los códigos de estado HTTP
dados, ej.: '200', '200,301,302'
-e <códigos> - excluir respuestas con los códigos de estado HTTP dados,
ej.: '404', '403,404,500'
-2 - probar HTTP/2 (negociado por ALPN en TLS, retrocede a 1.1;
http plano permanece en 1.1). necesita el paquete 'h2'
opciones de búsqueda
-s <cadena|archivo> - una sola cadena/regex o múltiples cadenas/regex en un
archivo para encontrar en cuerpos y cabeceras de respuestas
HTTP (ver -w), ej.: 'tomcat 8', '/tmp/igot0daysforthese.txt'
-S <cadena|archivo> - invertir (grep -v): descartar TODAS las coincidencias de
una respuesta si esta cadena/regex (o archivo) aparece en
cualquier parte de su cuerpo o cabeceras, ej. para filtrar
páginas dinámicas de error / 404
-w <dónde> - dónde buscar: headers, body, o headers,body
(por defecto: headers,body)
-b <bytes> - número de bytes de contexto a mostrar desde una
coincidencia en el cuerpo (por defecto: 64)
-m <tamaño> - cuerpo máximo a leer + buscar; sufijo b/kb/mb, sin sufijo =
kb, ej.: 512, 1mb, 262144b (por defecto: 256kb)
-i - usar búsqueda sin distinción de mayúsculas/minúsculas
-I - usar inversión sin distinción de mayúsculas/minúsculas
(para -S)
opciones de escaneo
-x <num> - máximo de conexiones concurrentes (asíncrono; por defecto:
300). aumente ulimit -n en consecuencia para valores muy
altos
-c <segundos> - tiempo de espera de lectura por host en segundos, también
limita el tiempo de lectura del cuerpo. el pre-vuelo tcp
está limitado a 2s independientemente, así que los hosts
filtrados/muertos liberan su ranura rápido (por defecto: 3.0)
-G <segundos> - tiempo de espera global: detener todo el escaneo después de
N segundos (red de seguridad contra cualquier cuelgue; por
defecto: ninguno)
-y <num> - reintentar una sonda fallida hasta <num> veces (por defecto:
0). ayuda con hosts inestables a escala; manténgalo pequeño
-1 - una vez que un host tiene una coincidencia, saltar sus
sondas aún no iniciadas (mejor esfuerzo; las peticiones en
curso aún terminan, así que con -x alto aún puede ver unas
pocas coincidencias por host)
-z <tamaño> - escanear objetivos en orden aleatorio dentro de una ventana
con límite de memoria de <tamaño> de ram (sufijo b/kb/mb/gb),
ej.: -z 1gb. mantiene rangos/archivos enormes sin agotar la
memoria
-Z <num> - limitar la ventana de -z a <num> objetivos (por defecto
2000000, ~267mb a ~140 bytes cada uno). más = mezcla más
amplia en rangos enormes, a costa de ram y almacenamiento
en búfer al inicio
-W - guardar/reanudar: en ctrl+c escribir el progreso en
httpgrep.session; volver a ejecutar con -W para reanudar
desde él (si no, empezar de nuevo)
-T <0|1> - también sondear los (v)hosts del certificado (CN + SAN)
como peticiones extra además del escaneo directo. 0 = vía
cabecera Host en la misma ip (dentro del alcance); 1 =
TAMBIÉN por nombre dns/SNI (puede salir del alcance).
necesita TLS (url https, -t, o un puerto *443).
opciones de salida
-l <archivo> - registrar las coincidencias encontradas en <archivo>.<fmt>
según el formato -O elegido (ej.: -l out -O csv,jsonl =>
out.csv, out.jsonl)
-O <formatos> - formato(s) de archivo de registro, lista separada por
comas de: txt, csv, jsonl (por defecto: txt; use '?' para
listar). la salida en terminal siempre permanece legible
para humanos.
-v - verboso: imprimir cada url a medida que se escanea
-7 - escapar no-ASCII en la salida del terminal a \xNN, para que
un cuerpo de respuesta hostil no pueda corromper su terminal
(los registros permanecen crudos)
opciones misceláneas
-H - imprimir ayuda
-V - imprimir información de versión
ejemplos
# buscar 'apache' en cabeceras y cuerpo de un único host
$ httpgrep -h foobar.net -s apache
# escanear un rango CIDR en el puerto 8080, buscar 'tomcat' solo en el cuerpo
$ httpgrep -h 192.168.0.0/24 -p 8080 -s tomcat -w body
# escanear un host a través de múltiples puertos y un rango de puertos buscando 'jenkins'
$ httpgrep -h 192.168.0.10 -p 80,443,8080,8000-8100 -s jenkins -i
# escanear lista de hosts, archivo de cadenas de búsqueda, registrar coincidencias (-> /tmp/out.txt)
$ httpgrep -h /tmp/hosts.txt -s /tmp/strings.txt -x 200 -l /tmp/out
# buscar 'admin' sin distinción de mayúsculas/minúsculas a través de múltiples URIs vía TLS
$ httpgrep -h foobar.net -t -u /admin,/login,/dashboard -s admin -i
# escanear rango IP, reverse DNS, solo informar de respuestas 200
$ httpgrep -h 10.0.0.1-10.0.0.254 -s 'powered by' -r -f 200
# buscar solo en cabeceras, no seguir redirecciones, salida verbosa
$ httpgrep -h foobar.net -s 'X-Powered-By' -w headers -F -v
# buscar 'admin', pero descartar páginas dinámicas de error (inversión, sin distinción de mayúsculas/minúsculas)
$ httpgrep -h 192.168.0.0/24 -s admin -i -S 'error|not found' -I
# enrutar a través de proxy, UA personalizado, buscar cadenas de versión
$ httpgrep -h /tmp/hosts.txt -s 'nginx/1\.' -P http://127.0.0.1:8080 -U 'curl/8.0'
# escaneo grande reanudable: ctrl+c guarda el estado, vuelva a ejecutar con -W para continuar; también
# limite toda la ejecución a 1 hora como red de seguridad contra cuelgues
$ httpgrep -h 10.0.0.0/16 -p 80,443 -s admin -W -G 3600
```
# Salida
Las coincidencias se imprimen en vivo, una por línea:
```
[*] <url> | [vhost] | <estado> | <tipo> | <coincidencia>
```
- `<url>` - la URL escaneada (`scheme://host:port/uri`).
- `<vhost>` - presente con `-T` (el (v)host del certificado probado vía la
cabecera `Host`) o `-r` (el nombre PTR de la ip escaneada);
vacío para escaneos directos.
- `<estado>` - el código de estado de la respuesta HTTP (después de
redirecciones).
- `<tipo>` - `body` o `header`.
- `<coincidencia>` - acierto en el cuerpo: una ventana corta con repr desde la
coincidencia (`-b` bytes); acierto en la cabecera: `nombre: valor`.
El terminal siempre muestra esta forma legible. Con `-l <base>` las mismas
coincidencias se reflejan en `<base>.<fmt>` para cada formato `-O` - `txt`
(estas líneas), `csv` (filas `url,vhost,status,type,match` con una cabecera),
`jsonl` (un objeto JSON por coincidencia).
En un escaneo multi-objetivo se muestra una línea de estado en vivo (fijada al
fondo en una tty, líneas simples cuando se redirige):
```
[+] wait bitch, escaneando: <objetivos> | <escaneados>/<total> | <pct>% | <n> aciertos
```
`<total>` es el recuento de objetivos (cidrs/ rangos calculados, no ampliados);
`<n> aciertos` es el número acumulado de líneas de coincidencia emitidas hasta
ahora.
# Autor
noptrix
# Notas
- código rápido y sucio
- httpgrep ya está empaquetado y disponible para [BlackArch Linux](https://www.blackarch.org/)
- Mis ramas master siempre son estables; las ramas dev se crean para el trabajo actual.
- Todo mi material público que encuentres está oficialmente anunciado y publicado a través de [nullsecurity.net](https://www.nullsecurity.net).
# Licencia
Consulte docs/LICENSE.
# Aviso legal
Enfatizamos aquí que el material relacionado con hacking que se encuentra en
[nullsecurity.net](http://nullsecurity.net) es solo con fines educativos.
No somos responsables de ningún daño. Usted es responsable de sus propias
acciones.