#!/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
