78 lines
2.7 KiB
Bash
78 lines
2.7 KiB
Bash
#!/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
|