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,74 @@
|
||||
---
|
||||
name: launch_chromium_proxy
|
||||
kind: function
|
||||
lang: bash
|
||||
domain: browser
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "launch_chromium_proxy [--proxy URL] [--profile DIR] [--url URL] [--ca-cert PATH] [--extra \"ARGS\"]"
|
||||
description: "Lanza Chromium (o Chrome) apuntando a un proxy HTTP/HTTPS local con un perfil completamente aislado del perfil real del usuario. Pensado para capturar trafico con un proxy de interceptacion (mitmproxy, Burp Suite) sin contaminar la sesion normal de navegacion. Emite un JSON con el PID del proceso lanzado."
|
||||
tags: [chromium, chrome, proxy, mitmproxy, burp, browser, web-proxy, intercept, tls]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: []
|
||||
params:
|
||||
- name: "--proxy URL"
|
||||
desc: "URL del proxy HTTP/HTTPS local, ej. http://127.0.0.1:8080. Se pasa a Chromium como --proxy-server=URL. Default: http://127.0.0.1:8080."
|
||||
- name: "--profile DIR"
|
||||
desc: "Directorio de perfil aislado para Chromium (--user-data-dir). Se crea automaticamente si no existe. Default: /tmp/chromium-proxy. Usar un path distinto por sesion si se quiere aislamiento total entre corridas."
|
||||
- name: "--url URL"
|
||||
desc: "URL inicial a abrir al arrancar el navegador. Opcional. Si se omite, Chromium abre su pagina de nueva pestana."
|
||||
- name: "--ca-cert PATH"
|
||||
desc: "Ruta a un CA cert PEM del proxy (ej. ~/.mitmproxy/mitmproxy-ca-cert.pem). Si se pasa, la funcion NO agrega --ignore-certificate-errors y asume que el usuario ya importo el CA en el perfil o en el sistema. Si se omite, se agrega --ignore-certificate-errors automaticamente para que el proxy MITM no rompa HTTPS (menos seguro)."
|
||||
- name: "--extra \"ARGS\""
|
||||
desc: "Flags extra que se pasan directamente a chromium, ej. --extra \"--disable-gpu --window-size=1280,800\". El valor completo debe ir entre comillas."
|
||||
output: "JSON en stdout: {\"pid\": <pid>, \"browser\": \"<binario>\", \"proxy\": \"<url>\", \"profile\": \"<dir>\", \"log\": \"<ruta_log>\"}. Mensajes de estado e informacion de CA en stderr. El navegador corre en background desacoplado de la sesion. Exit codes: 0=lanzado correctamente, 1=binario no encontrado o argumento invalido o error al crear el directorio de perfil."
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "bash/functions/browser/launch_chromium_proxy.sh"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```bash
|
||||
source bash/functions/browser/launch_chromium_proxy.sh
|
||||
|
||||
# Caso mas comun: interceptar trafico con mitmproxy corriendo en 8080
|
||||
# (sin CA instalado: --ignore-certificate-errors se aplica automaticamente)
|
||||
result=$(launch_chromium_proxy --proxy http://127.0.0.1:8080 --url https://httpbin.org/get)
|
||||
echo "$result"
|
||||
# {"pid":12345,"browser":"chromium","proxy":"http://127.0.0.1:8080","profile":"/tmp/chromium-proxy","log":"/tmp/chromium-proxy-12345.log"}
|
||||
|
||||
# Con CA cert instalado (mitmproxy): sin --ignore-certificate-errors
|
||||
launch_chromium_proxy \
|
||||
--proxy http://127.0.0.1:8080 \
|
||||
--ca-cert ~/.mitmproxy/mitmproxy-ca-cert.pem \
|
||||
--profile /tmp/mitm-session \
|
||||
--url https://api.ejemplo.com/v1/test
|
||||
|
||||
# Con Burp Suite en puerto 8081, perfil aislado y ventana de tamano fijo
|
||||
launch_chromium_proxy \
|
||||
--proxy http://127.0.0.1:8081 \
|
||||
--profile /tmp/burp-session \
|
||||
--extra "--window-size=1440,900" \
|
||||
--url https://app.objetivo.com
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando necesitas capturar y analizar trafico HTTPS de un navegador con mitmproxy, Burp Suite u otro proxy de interceptacion, sin tocar el perfil real del usuario ni sus cookies/credenciales guardadas. Ideal antes de hacer analisis de trafico de una app web o API, o al reproducir un flujo autenticado desde una sesion limpia.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Deteccion de binario en orden**: la funcion prueba `chromium`, `chromium-browser`, `google-chrome-stable`, `google-chrome`. En sistemas donde solo existe `google-chrome`, ese sera el binario usado. Si ninguno esta en el PATH, retorna exit 1. Instalar con `sudo apt install chromium` o `chromium-browser`.
|
||||
- **`--ignore-certificate-errors` sin `--ca-cert`**: este flag desactiva toda la validacion TLS del navegador. Es conveniente para empezar rapido, pero reduce la seguridad de la sesion. Para produccion o analisis de seguridad serio, instalar el CA del proxy en el sistema (`sudo cp mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt && sudo update-ca-certificates`) o en el perfil de Chromium (chrome://settings/certificates), y pasar `--ca-cert` para que la funcion omita el flag inseguro.
|
||||
- **`--proxy-bypass-list="<-loopback>"`**: fuerza que el trafico loopback (127.0.0.1, localhost) TAMBIEN pase por el proxy. Sin esto, Chromium excluye loopback del proxy por defecto y no veras esas peticiones en mitmproxy. Si quieres el comportamiento estandar (excluir loopback), elimina este flag via `--extra`.
|
||||
- **Perfil persistente entre sesiones**: el perfil en `/tmp/chromium-proxy` (o el directorio que elijas) persiste entre ejecuciones. Si quieres una sesion 100% limpia cada vez, pasa `--profile /tmp/chromium-proxy-$$` (usa el PID del shell como sufijo) o borra el directorio antes de llamar a la funcion.
|
||||
- **`setsid` + `disown`**: el navegador se lanza desacoplado de la sesion del agente. Si la shell/sesion que llamo a la funcion termina, el proceso Chromium sigue vivo. Para matarlo, usar `kill <pid>` con el PID del JSON de salida.
|
||||
- **Log del navegador**: stdout y stderr de Chromium se redirigen a `/tmp/chromium-proxy-<pid>.log`. Si el navegador no arranca, revisar ese archivo para ver el error.
|
||||
- **Chrome STABLE 138+**: al igual que `chrome_load_extensions`, algunos flags de automatizacion estan bloqueados en Chrome STABLE. Para interceptacion de trafico `--proxy-server` y `--user-data-dir` siguen funcionando en todas las versiones. Esta funcion es compatible con Chrome/Chromium en cualquier canal.
|
||||
- **Multiples instancias**: si ya hay una instancia de Chromium corriendo con el mismo `--user-data-dir`, Chromium puede reusar esa instancia en lugar de abrir una nueva. Usar un directorio de perfil distinto por sesion concurrente.
|
||||
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
# launch_chromium_proxy — Lanza Chromium apuntando a un proxy HTTP/HTTPS local con perfil aislado.
|
||||
|
||||
launch_chromium_proxy() {
|
||||
local proxy_url="http://127.0.0.1:8080"
|
||||
local profile_dir="/tmp/chromium-proxy"
|
||||
local start_url=""
|
||||
local ca_cert=""
|
||||
local extra_args=""
|
||||
|
||||
# Parsear argumentos
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--proxy)
|
||||
proxy_url="$2"; shift 2 ;;
|
||||
--profile)
|
||||
profile_dir="$2"; shift 2 ;;
|
||||
--url)
|
||||
start_url="$2"; shift 2 ;;
|
||||
--ca-cert)
|
||||
ca_cert="$2"; shift 2 ;;
|
||||
--extra)
|
||||
extra_args="$2"; shift 2 ;;
|
||||
*)
|
||||
echo "ERROR: argumento desconocido: $1" >&2
|
||||
return 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Detectar binario del navegador
|
||||
local browser_bin=""
|
||||
for candidate in chromium chromium-browser google-chrome-stable google-chrome; do
|
||||
if command -v "$candidate" &>/dev/null; then
|
||||
browser_bin="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -z "$browser_bin" ]]; then
|
||||
echo "ERROR: no se encontro ningun binario Chromium/Chrome en el PATH." >&2
|
||||
echo " Probados: chromium, chromium-browser, google-chrome-stable, google-chrome." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Crear directorio de perfil si no existe
|
||||
if [[ ! -d "$profile_dir" ]]; then
|
||||
mkdir -p "$profile_dir" || {
|
||||
echo "ERROR: no se pudo crear el directorio de perfil: $profile_dir" >&2
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
# Construir argumentos del navegador
|
||||
local args=(
|
||||
"--proxy-server=${proxy_url}"
|
||||
"--user-data-dir=${profile_dir}"
|
||||
"--proxy-bypass-list=<-loopback>"
|
||||
"--no-first-run"
|
||||
"--no-default-browser-check"
|
||||
)
|
||||
|
||||
# Manejo de certificados TLS
|
||||
if [[ -n "$ca_cert" ]]; then
|
||||
# El usuario instalo el CA en el perfil; no ignorar errores de certificado.
|
||||
# (El CA se instala en el sistema o en el perfil antes de lanzar.)
|
||||
echo "INFO: CA cert declarado: $ca_cert" >&2
|
||||
echo "INFO: Asegurate de haber importado el CA en el perfil o en el sistema antes de navegar HTTPS." >&2
|
||||
else
|
||||
# Sin CA cert: ignorar errores de certificado para que mitmproxy/Burp funcionen sin configuracion extra.
|
||||
# ADVERTENCIA: esto desactiva la validacion TLS completa del navegador.
|
||||
args+=("--ignore-certificate-errors")
|
||||
echo "WARN: --ignore-certificate-errors activo. Usa --ca-cert si instalaste el CA del proxy." >&2
|
||||
fi
|
||||
|
||||
# URL inicial opcional
|
||||
if [[ -n "$start_url" ]]; then
|
||||
args+=("$start_url")
|
||||
fi
|
||||
|
||||
# Argumentos extra pasados por el usuario
|
||||
# shellcheck disable=SC2206
|
||||
local extra_arr=()
|
||||
if [[ -n "$extra_args" ]]; then
|
||||
read -r -a extra_arr <<< "$extra_args"
|
||||
args+=("${extra_arr[@]}")
|
||||
fi
|
||||
|
||||
# Log temporal para stderr/stdout del navegador
|
||||
local log_file="/tmp/chromium-proxy-$$.log"
|
||||
|
||||
# Lanzar en background desacoplado de la sesion del agente
|
||||
setsid "$browser_bin" "${args[@]}" </dev/null >"$log_file" 2>&1 &
|
||||
local browser_pid=$!
|
||||
disown "$browser_pid"
|
||||
|
||||
# Emitir JSON con informacion del proceso lanzado
|
||||
printf '{"pid":%d,"browser":"%s","proxy":"%s","profile":"%s","log":"%s"}\n' \
|
||||
"$browser_pid" "$browser_bin" "$proxy_url" "$profile_dir" "$log_file"
|
||||
}
|
||||
|
||||
# Ejecutar si se llama directamente (fn run / bash <file>)
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
launch_chromium_proxy "$@"
|
||||
fi
|
||||
@@ -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