#!/usr/bin/env bash # falco_response.sh: Active response handler for QueComanTierra Falco rules # # Falco pipes JSON alerts here via program_output. # Per-rule actions: # Bash Native TCP Exfiltration → kill PID + ss --kill socket # Shell Spawning OpenSSL Bulk Enc. → kill PID (kills openssl + parent shell) # Mass Document Deletion by Shell → kill PID # Hidden Encrypted Archive in Tmp → kill PID + remove the .enc file # # IMPORTANT: runs as root (Falco requirement). Validate PIDs before killing. set -euo pipefail LOG="/var/log/falco-response.log" ALERT=$(cat) # full JSON from Falco log() { echo "$(date -u +%FT%TZ) [RESPONSE] $*" | tee -a "$LOG" >&2; } rule=$(echo "$ALERT" | jq -r '.rule') pid=$(echo "$ALERT" | jq -r '.output_fields["proc.pid"] // empty') dst_ip=$(echo "$ALERT" | jq -r '.output_fields["fd.rip"] // empty') dst_port=$(echo "$ALERT"| jq -r '.output_fields["fd.rport"]// empty') file=$(echo "$ALERT" | jq -r '.output_fields["fd.name"] // empty') user=$(echo "$ALERT" | jq -r '.output_fields["user.name"]// empty') log "RULE='$rule' PID='$pid' USER='$user'" kill_pid() { local p="$1" # Validate: PID must be numeric and process must still exist [[ "$p" =~ ^[0-9]+$ ]] || { log "PID inválido: $p"; return 1; } [[ -d "/proc/$p" ]] || { log "PID $p ya no existe"; return 0; } log "KILL -9 $p ($(cat /proc/$p/cmdline | tr '\0' ' '))" kill -9 "$p" && log "PID $p terminado" || log "No se pudo matar $p" } kill_socket() { local ip="$1" port="$2" [[ -n "$ip" && -n "$port" ]] || return 0 log "Cerrando socket TCP → $ip:$port" # ss --kill requiere iproute2 >= 5.3 ss --kill state established dst "${ip}:${port}" 2>>"$LOG" \ && log "Socket $ip:$port cerrado" \ || log "ss --kill falló (¿iproute2 < 5.3?)" } case "$rule" in "Bash Native TCP Exfiltration") log "ACCIÓN: matar proceso + cerrar socket" kill_pid "$pid" kill_socket "$dst_ip" "$dst_port" ;; "Shell Spawning OpenSSL Bulk Encryption") log "ACCIÓN: matar proceso openssl" kill_pid "$pid" ;; "Mass Document Deletion by Shell Process") log "ACCIÓN: matar proceso de borrado masivo" kill_pid "$pid" ;; "Hidden Encrypted Archive Staged in Tmp") log "ACCIÓN: matar proceso + eliminar vault" kill_pid "$pid" if [[ -n "$file" && "$file" == /tmp/*.enc && "$file" == /tmp/.* ]]; then log "Eliminando vault cifrado: $file" rm -f "$file" && log "Vault eliminado" || log "No se pudo eliminar $file" fi ;; *) log "Regla desconocida, sin acción automática: $rule" ;; esac