feat(cybersecurity): auto-commit con 10 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
---
|
||||
name: query_mitm_flows
|
||||
kind: function
|
||||
lang: bash
|
||||
domain: cybersecurity
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "query_mitm_flows(file_or_glob: string, filter?: string, har?: string, mitmdump?: string) -> void"
|
||||
description: "Consulta capturas .mitm guardadas con mitmproxy: vuelca los flujos que coinciden con un filtro de mitmproxy a stdout, o exporta la captura a HAR. Acepta uno o varios archivos .mitm (incluyendo globs expandidos por el shell). Autodetecta mitmdump en PATH y $HOME/.local/bin."
|
||||
tags: [bash, cybersecurity, mitmproxy, web-proxy, query, har, capture, traffic, proxy, network]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: []
|
||||
params:
|
||||
- name: file_or_glob
|
||||
desc: "Ruta a un archivo .mitm o glob expandido por el shell (ej. ~/captures/traffic-*.mitm). Acepta múltiples archivos como argumentos posicionales."
|
||||
- name: filter
|
||||
desc: "Expresión de filtro mitmproxy (ej. '~m POST & ~u /api', '~c 500', '~d example.com'). Si se omite, vuelca todos los flujos."
|
||||
- name: har
|
||||
desc: "Ruta de salida para exportar en formato HAR (--set hardump=OUT). Si se omite, el volcado va a stdout."
|
||||
- name: mitmdump
|
||||
desc: "Ruta al binario mitmdump. Si se omite, autodetecta en PATH y luego en $HOME/.local/bin/mitmdump."
|
||||
output: "Vuelca los flujos capturados a stdout (modo default) o exporta a un archivo HAR (con --har); informa la ruta de exportación en stderr al terminar. Exit code de mitmdump propagado."
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "bash/functions/cybersecurity/query_mitm_flows.sh"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```bash
|
||||
source bash/functions/cybersecurity/query_mitm_flows.sh
|
||||
|
||||
# Volcar todos los flujos de una captura
|
||||
query_mitm_flows ~/captures/traffic-20260602.mitm
|
||||
|
||||
# Filtrar solo peticiones POST a /api (glob expandido por el shell)
|
||||
query_mitm_flows ~/captures/traffic-20260602-*.mitm --filter "~m POST & ~u /api"
|
||||
|
||||
# Ver solo respuestas con código 500
|
||||
query_mitm_flows session.mitm --filter "~c 500"
|
||||
|
||||
# Exportar a HAR para abrir en el Network tab del browser DevTools
|
||||
query_mitm_flows ~/captures/traffic-20260602.mitm --har salida.har
|
||||
|
||||
# Exportar a HAR con filtro aplicado
|
||||
query_mitm_flows session.mitm --filter "~d example.com" --har example_flows.har
|
||||
|
||||
# Especificar mitmdump manualmente (ej. en un venv de Python)
|
||||
query_mitm_flows session.mitm --mitmdump ~/.venv/bin/mitmdump --filter "~m POST"
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando hayas capturado tráfico HTTP/HTTPS con mitmproxy y necesites consultarlo después sin abrir una interfaz interactiva: filtrar flujos específicos por método, dominio, URL o código de respuesta, o exportar la captura a HAR para análisis posterior en herramientas externas (browser DevTools, Insomnia, Postman). Úsala desde scripts de análisis automatizados o pipelines de revisión de seguridad.
|
||||
|
||||
## Gotchas
|
||||
|
||||
**Sintaxis de filtros mitmproxy** — los filtros se pasan como expresión entre comillas:
|
||||
|
||||
| Operador | Significado | Ejemplo |
|
||||
|---|---|---|
|
||||
| `~u <regex>` | URL (path + query) | `~u /api/login` |
|
||||
| `~d <regex>` | Dominio del host | `~d example.com` |
|
||||
| `~m <método>` | Método HTTP | `~m POST` |
|
||||
| `~c <código>` | Código de respuesta | `~c 500` |
|
||||
| `~bq <regex>` | Body del request | `~bq password` |
|
||||
| `~bs <regex>` | Body del response | `~bs token` |
|
||||
| `~t <regex>` | Content-Type | `~t application/json` |
|
||||
| `~s` | Solo respuestas | `~s` |
|
||||
| `~q` | Solo requests | `~q` |
|
||||
|
||||
Combinar con `&` (AND), `|` (OR), `!` (NOT). Ejemplos:
|
||||
- `"~m POST & ~u /api"` — POST a rutas /api
|
||||
- `"~c 500 | ~c 503"` — errores de servidor
|
||||
- `"~d example.com & !~u /static"` — todo de example.com excepto estáticos
|
||||
|
||||
**Globs:** el shell expande el glob *antes* de pasar los argumentos a la función. Pasar `~/captures/traffic-*.mitm` sin comillas para que el shell expanda; con comillas el glob llega literalmente y fallará si el archivo no existe.
|
||||
|
||||
**Inspección interactiva:** para navegar los flujos con UI, usar `mitmweb -r <file>` (web) o `mitmproxy -r <file>` (TUI), no esta función. Esta función es para consulta programática y scripting.
|
||||
|
||||
**Múltiples archivos con `-r`:** mitmdump acepta varios flags `-r` y concatena los flujos en orden. El filtro se aplica sobre el conjunto completo.
|
||||
|
||||
**HAR y filtros juntos:** al usar `--har` con `--filter`, solo los flujos que pasen el filtro se exportan al HAR.
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env bash
|
||||
# query_mitm_flows — Consulta capturas .mitm con mitmdump: vuelca flujos a stdout
|
||||
# o exporta a HAR. Acepta uno o varios archivos (también globs expandidos por el shell).
|
||||
|
||||
query_mitm_flows() {
|
||||
local -a files=()
|
||||
local filter=""
|
||||
local har_out=""
|
||||
local mitmdump_bin=""
|
||||
|
||||
# ── Parseo de argumentos ────────────────────────────────────────────────────
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--filter)
|
||||
[[ -z "${2:-}" ]] && { echo "ERROR: --filter requiere un valor" >&2; return 1; }
|
||||
filter="$2"; shift 2 ;;
|
||||
--har)
|
||||
[[ -z "${2:-}" ]] && { echo "ERROR: --har requiere una ruta de salida" >&2; return 1; }
|
||||
har_out="$2"; shift 2 ;;
|
||||
--mitmdump)
|
||||
[[ -z "${2:-}" ]] && { echo "ERROR: --mitmdump requiere la ruta al binario" >&2; return 1; }
|
||||
mitmdump_bin="$2"; shift 2 ;;
|
||||
--*)
|
||||
echo "ERROR: opcion desconocida: $1" >&2; return 1 ;;
|
||||
*)
|
||||
files+=("$1"); shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ── Validar que se paso al menos un archivo ─────────────────────────────────
|
||||
if [[ ${#files[@]} -eq 0 ]]; then
|
||||
echo "ERROR: se requiere al menos un archivo .mitm como argumento" >&2
|
||||
echo "Uso: query_mitm_flows <file_or_glob> [--filter EXPR] [--har OUT] [--mitmdump BIN]" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ── Verificar que cada archivo existe ──────────────────────────────────────
|
||||
local -a valid_files=()
|
||||
for f in "${files[@]}"; do
|
||||
if [[ -f "$f" ]]; then
|
||||
valid_files+=("$f")
|
||||
else
|
||||
echo "ERROR: archivo no encontrado: $f" >&2
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#valid_files[@]} -eq 0 ]]; then
|
||||
echo "ERROR: ningun archivo valido encontrado (el patron no matcheo nada)" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ── Autodetectar mitmdump ───────────────────────────────────────────────────
|
||||
if [[ -z "$mitmdump_bin" ]]; then
|
||||
if command -v mitmdump &>/dev/null; then
|
||||
mitmdump_bin="mitmdump"
|
||||
elif [[ -x "$HOME/.local/bin/mitmdump" ]]; then
|
||||
mitmdump_bin="$HOME/.local/bin/mitmdump"
|
||||
else
|
||||
echo "ERROR: mitmdump no encontrado. Instala mitmproxy:" >&2
|
||||
echo " pip install mitmproxy o pip install --user mitmproxy" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -x "$(command -v "$mitmdump_bin" 2>/dev/null || echo "$mitmdump_bin")" ]]; then
|
||||
echo "ERROR: binario mitmdump no ejecutable: $mitmdump_bin" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# ── Construir y ejecutar el comando ────────────────────────────────────────
|
||||
local -a cmd=("$mitmdump_bin" -n)
|
||||
|
||||
# Añadir todos los archivos de entrada con -r
|
||||
for f in "${valid_files[@]}"; do
|
||||
cmd+=(-r "$f")
|
||||
done
|
||||
|
||||
# Modo HAR
|
||||
if [[ -n "$har_out" ]]; then
|
||||
cmd+=(--set "hardump=${har_out}")
|
||||
fi
|
||||
|
||||
# Filtro de flujos (argumento posicional al final)
|
||||
if [[ -n "$filter" ]]; then
|
||||
cmd+=("$filter")
|
||||
fi
|
||||
|
||||
"${cmd[@]}"
|
||||
local exit_code=$?
|
||||
|
||||
if [[ -n "$har_out" && $exit_code -eq 0 ]]; then
|
||||
echo "HAR exportado a ${har_out}" >&2
|
||||
fi
|
||||
|
||||
return $exit_code
|
||||
}
|
||||
|
||||
# Ejecutar si se llama directamente
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
query_mitm_flows "$@"
|
||||
fi
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
name: start_mitm_capture
|
||||
kind: function
|
||||
lang: bash
|
||||
domain: cybersecurity
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "start_mitm_capture([--port N] [--out DIR] [--rotate-min N] [--addon PATH] [--mitmdump BIN] [--log PATH]) -> string"
|
||||
description: "Arranca mitmdump en modo headless en segundo plano como proxy de interceptación liviano, con rotación de capturas cada N minutos vía el addon rotate_capture_flows.py del registry. El proceso sobrevive al cierre de la shell (setsid). Emite JSON con PID, puerto, directorio de salida y ruta del log."
|
||||
tags: [bash, cybersecurity, mitmproxy, proxy, capture, web-proxy, network, interception, mitmdump]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: []
|
||||
params:
|
||||
- name: "--port N"
|
||||
desc: "Puerto TCP donde mitmdump escucha conexiones del cliente proxy. Default: 8080."
|
||||
- name: "--out DIR"
|
||||
desc: "Directorio donde se guardan los archivos .mitm rotados. Se crea automáticamente si no existe. Default: $HOME/captures."
|
||||
- name: "--rotate-min N"
|
||||
desc: "Minutos de duración de cada archivo de captura antes de rotar. Default: 20."
|
||||
- name: "--addon PATH"
|
||||
desc: "Ruta al addon Python de rotación (rotate_capture_flows.py). Default: derivado desde FN_REGISTRY_ROOT o desde la ubicación del propio script (3 niveles arriba)."
|
||||
- name: "--mitmdump BIN"
|
||||
desc: "Ruta al binario mitmdump. Default: autodetectado con command -v mitmdump, luego $HOME/.local/bin/mitmdump. Si no se encuentra, falla con instrucción de instalación."
|
||||
- name: "--log PATH"
|
||||
desc: "Archivo de log del proceso mitmdump. Default: <out>/mitmdump.log."
|
||||
output: "JSON en stdout: {\"pid\": <pid>, \"port\": <port>, \"out_dir\": \"<dir>\", \"rotate_min\": <n>, \"log\": \"<log>\"}. Exit 1 en error (binario no encontrado, addon ausente, proceso muerto al arrancar)."
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "bash/functions/cybersecurity/start_mitm_capture.sh"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```bash
|
||||
source bash/functions/cybersecurity/start_mitm_capture.sh
|
||||
|
||||
# Arranque con defaults (puerto 8080, capturas en ~/captures, rotación cada 20 min)
|
||||
start_mitm_capture --port 8080 --out /home/enmanuel/captures --rotate-min 20
|
||||
|
||||
# Salida esperada:
|
||||
# {"pid": 123456, "port": 8080, "out_dir": "/home/enmanuel/captures", "rotate_min": 20, "log": "/home/enmanuel/captures/mitmdump.log"}
|
||||
|
||||
# Puerto alternativo y rotación más frecuente
|
||||
start_mitm_capture --port 9090 --out /tmp/mitm_session --rotate-min 5
|
||||
|
||||
# Pasando addon y binario explícitos
|
||||
start_mitm_capture \
|
||||
--port 8080 \
|
||||
--out /home/enmanuel/captures \
|
||||
--addon /home/enmanuel/fn_registry/python/functions/cybersecurity/rotate_capture_flows.py \
|
||||
--mitmdump /home/enmanuel/.local/bin/mitmdump
|
||||
|
||||
# Leer el PID para poder parar el proceso más adelante
|
||||
info=$(start_mitm_capture --port 8080 --out /home/enmanuel/captures)
|
||||
pid=$(echo "$info" | python3 -c "import sys,json; print(json.load(sys.stdin)['pid'])")
|
||||
echo "Proxy corriendo con PID $pid"
|
||||
# Para parar: kill "$pid"
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando necesites un proxy de interceptación pasivo siempre activo en segundo plano que capture y rote el tráfico HTTP/HTTPS de forma continua sin supervisión manual. Úsala antes de lanzar pruebas de integración, sesiones de auditoría web o scraping supervisado donde quieras replay o análisis posterior de las capturas `.mitm`.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **HTTPS requiere instalar el CA de mitmproxy en el cliente.** El certificado raíz está en `~/.mitmproxy/mitmproxy-ca-cert.pem` tras el primer arranque. En navegadores: importar como CA de confianza. En curl/httpx: `--cacert ~/.mitmproxy/mitmproxy-ca-cert.pem`. En Chrome/Chromium headless: `--ignore-certificate-errors` (solo para pruebas).
|
||||
- **El proceso queda en background.** Para pararlo: `kill <pid>` (el PID se devuelve en el JSON) o `port_kill 8080` si tienes la función del registry disponible.
|
||||
- **El addon rotate_capture_flows.py debe existir.** La función lo busca en la raíz del registry derivada automáticamente; si el registry está en una ubicación no estándar, pasa `--addon` explícitamente o setea `FN_REGISTRY_ROOT`.
|
||||
- **setsid desacopla el proceso de la shell.** Si cierras la terminal, mitmdump sigue corriendo. Necesitas matar el PID manualmente o via systemd/supervisor si quieres ciclo de vida gestionado.
|
||||
- **El log crece sin límite.** El log de mitmdump no rota; solo rotan los archivos `.mitm` de capturas. Monitoriza el tamaño de `<out>/mitmdump.log` en sesiones largas.
|
||||
- **Solo funciona con mitmdump >= 9.x** (API de addons `--set` con parámetros por nombre). Versiones anteriores usan sintaxis distinta.
|
||||
|
||||
## Notas
|
||||
|
||||
La derivación de la raíz del registry cuando `FN_REGISTRY_ROOT` no está seteado asciende 3 niveles desde `bash/functions/cybersecurity/` hasta la raíz usando `dirname "${BASH_SOURCE[0]}"`. Esto funciona siempre que el script se sourcee desde su ubicación original en el registry.
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bash
|
||||
# start_mitm_capture — Arranca mitmdump en segundo plano como proxy de interceptación
|
||||
# con rotación de capturas cada N minutos vía addon Python del registry.
|
||||
|
||||
start_mitm_capture() {
|
||||
local port=8080
|
||||
local out_dir="$HOME/captures"
|
||||
local rotate_min=20
|
||||
local addon_path=""
|
||||
local mitmdump_bin=""
|
||||
local log_path=""
|
||||
|
||||
# Parseo de argumentos
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--port) port="$2"; shift 2 ;;
|
||||
--out) out_dir="$2"; shift 2 ;;
|
||||
--rotate-min) rotate_min="$2"; shift 2 ;;
|
||||
--addon) addon_path="$2"; shift 2 ;;
|
||||
--mitmdump) mitmdump_bin="$2"; shift 2 ;;
|
||||
--log) log_path="$2"; shift 2 ;;
|
||||
*)
|
||||
echo "ERROR: argumento desconocido: $1" >&2
|
||||
echo "Uso: start_mitm_capture [--port N] [--out DIR] [--rotate-min N] [--addon PATH] [--mitmdump BIN] [--log PATH]" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Derivar raíz del registry cuando FN_REGISTRY_ROOT no está seteado
|
||||
local registry_root
|
||||
if [[ -n "${FN_REGISTRY_ROOT:-}" ]]; then
|
||||
registry_root="$FN_REGISTRY_ROOT"
|
||||
else
|
||||
# bash/functions/cybersecurity/ -> 3 niveles arriba = raíz del registry
|
||||
registry_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
fi
|
||||
|
||||
# Default addon usando la raíz derivada
|
||||
if [[ -z "$addon_path" ]]; then
|
||||
addon_path="${registry_root}/python/functions/cybersecurity/rotate_capture_flows.py"
|
||||
fi
|
||||
|
||||
# Default log path (depende de out_dir, se resuelve después de crear el dir)
|
||||
# Se asigna más abajo si sigue vacío
|
||||
|
||||
# Crear directorio de capturas si no existe
|
||||
if [[ ! -d "$out_dir" ]]; then
|
||||
mkdir -p "$out_dir" || {
|
||||
echo "ERROR: no se pudo crear el directorio de capturas: $out_dir" >&2
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
# Asignar log por defecto ahora que out_dir existe
|
||||
if [[ -z "$log_path" ]]; then
|
||||
log_path="${out_dir}/mitmdump.log"
|
||||
fi
|
||||
|
||||
# Resolver binario mitmdump
|
||||
if [[ -z "$mitmdump_bin" ]]; then
|
||||
if command -v mitmdump &>/dev/null; then
|
||||
mitmdump_bin="$(command -v mitmdump)"
|
||||
elif [[ -x "$HOME/.local/bin/mitmdump" ]]; then
|
||||
mitmdump_bin="$HOME/.local/bin/mitmdump"
|
||||
else
|
||||
echo "ERROR: mitmdump no encontrado; instala con: uv tool install mitmproxy" >&2
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
if [[ ! -x "$mitmdump_bin" ]]; then
|
||||
echo "ERROR: el binario indicado no existe o no es ejecutable: $mitmdump_bin" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verificar que el addon existe
|
||||
if [[ ! -f "$addon_path" ]]; then
|
||||
echo "ERROR: addon no encontrado: $addon_path" >&2
|
||||
echo " Asegúrate de que FN_REGISTRY_ROOT apunta a la raíz del registry" >&2
|
||||
echo " o pasa --addon con la ruta correcta a rotate_capture_flows.py" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Arrancar mitmdump en background con setsid (sobrevive al cierre de la shell).
|
||||
# El redirect </dev/null desacopla stdin: sin él, el proceso retiene el pipe
|
||||
# heredado y la shell sale con exit 144 (SIGTERM) al cerrarse. disown lo saca
|
||||
# de la tabla de jobs para que la shell no le envíe señales al terminar.
|
||||
setsid "$mitmdump_bin" \
|
||||
-s "$addon_path" \
|
||||
--set "rotate_min=${rotate_min}" \
|
||||
--set "capture_dir=${out_dir}" \
|
||||
--listen-port "$port" \
|
||||
</dev/null >> "$log_path" 2>&1 &
|
||||
local pid=$!
|
||||
disown "$pid" 2>/dev/null || true
|
||||
|
||||
# Esperar ~1s y verificar que el proceso sigue vivo
|
||||
sleep 1
|
||||
if ! kill -0 "$pid" 2>/dev/null; then
|
||||
echo "ERROR: mitmdump murió al arrancar. Últimas líneas del log:" >&2
|
||||
tail -20 "$log_path" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Emitir JSON con información del proceso arrancado
|
||||
printf '{"pid": %d, "port": %d, "out_dir": "%s", "rotate_min": %d, "log": "%s"}\n' \
|
||||
"$pid" "$port" "$out_dir" "$rotate_min" "$log_path"
|
||||
}
|
||||
|
||||
# Ejecutar si se llama directamente (fn run / bash <file>)
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
start_mitm_capture "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user