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:
Operator
2026-06-23 16:12:14 -04:00
commit 98103466d8
239 changed files with 40012 additions and 0 deletions
+345
View File
@@ -0,0 +1,345 @@
#!/usr/bin/env python3
"""
Payload server infrastructure deployment module
"""
import os
import sys
import logging
# Add the project root to the path so we can import utils
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
from utils.common import (
COLORS, clear_screen, print_banner, generate_deployment_id,
setup_logging, get_public_ip, confirm_action, wait_for_input
)
from utils.provider_utils import select_provider, gather_provider_config
from utils.ssh_utils import generate_ssh_key
def gather_payload_parameters():
"""Collect parameters specific to payload server deployments"""
clear_screen()
print_banner()
print(f"{COLORS['WHITE']}PAYLOAD SERVER SETUP{COLORS['RESET']}")
print(f"{COLORS['WHITE']}===================={COLORS['RESET']}")
config = {}
# Generate deployment ID
config['deployment_id'] = generate_deployment_id()
print(f"Deployment ID: {COLORS['CYAN']}{config['deployment_id']}{COLORS['RESET']}")
# Provider selection
provider = select_provider()
if not provider:
return None
config['provider'] = provider
# Get provider-specific configuration
provider_config = gather_provider_config(provider)
if not provider_config:
return None
config.update(provider_config)
# Payload-specific configuration
print(f"\n{COLORS['BLUE']}Payload Server Configuration{COLORS['RESET']}")
# Domain configuration
domain = input(f"Domain for payload server [required]: ")
if not domain:
print(f"{COLORS['RED']}A domain is required for payload server deployments{COLORS['RESET']}")
return None
config['domain'] = domain
# Subdomain configuration
config['payload_subdomain'] = input("Payload server subdomain [default: cdn]: ") or "cdn"
# Payload types
print(f"\n{COLORS['BLUE']}Payload Types to Host:{COLORS['RESET']}")
config['host_executables'] = confirm_action("Host Windows executables?", default=True)
config['host_scripts'] = confirm_action("Host PowerShell/Python scripts?", default=True)
config['host_documents'] = confirm_action("Host weaponized documents?", default=False)
config['host_mobile'] = confirm_action("Host mobile payloads (APK/IPA)?", default=False)
# Security options
print(f"\n{COLORS['BLUE']}Security Options:{COLORS['RESET']}")
config['enable_basic_auth'] = confirm_action("Enable basic authentication?", default=True)
config['enable_ip_filtering'] = confirm_action("Enable IP filtering?", default=True)
config['enable_user_agent_filtering'] = confirm_action("Enable User-Agent filtering?", default=True)
config['enable_rate_limiting'] = confirm_action("Enable rate limiting?", default=True)
# Payload generation
config['auto_generate_payloads'] = confirm_action("Auto-generate common payloads?", default=False)
# Email for Let's Encrypt
default_email = f"admin@{config['domain']}"
config['letsencrypt_email'] = input(f"Email for Let's Encrypt [default: {default_email}]: ") or default_email
# Get operator IP for security
suggested_ip = get_public_ip()
if suggested_ip:
operator_ip = input(f"Your public IP for secure access [detected: {suggested_ip}]: ") or suggested_ip
else:
operator_ip = input("Your public IP for secure access: ")
config['operator_ip'] = operator_ip
# SSH key generation
ssh_key_path = generate_ssh_key(config['deployment_id'])
if not ssh_key_path:
print(f"{COLORS['RED']}Failed to generate SSH key{COLORS['RESET']}")
return None
config['ssh_key_path'] = f"{ssh_key_path}.pub"
# Post-deployment options
config['ssh_after_deploy'] = confirm_action("SSH into instance after deployment?", default=True)
return config
def payload_menu():
"""Display the payload server submenu and handle user selection"""
while True:
clear_screen()
print_banner()
print(f"{COLORS['WHITE']}PAYLOAD SERVER MENU{COLORS['RESET']}")
print(f"{COLORS['WHITE']}==================={COLORS['RESET']}")
print(f"1) Basic Payload Server {COLORS['GREEN']}*SIMPLE*{COLORS['RESET']} {COLORS['GRAY']}(Quick setup){COLORS['RESET']}")
print(f"2) Multi-Format Payload Server {COLORS['GRAY']}(Supports multiple payload types){COLORS['RESET']}")
print(f"3) Document Payload Server {COLORS['GRAY']}(Specialized for document payloads){COLORS['RESET']}")
print(f"4) Mobile Payload Server {COLORS['GRAY']}(Mobile-focused payloads){COLORS['RESET']}")
print(f"5) Secure Payload Server {COLORS['GRAY']}(Auth + filtering){COLORS['RESET']}")
print(f"6) Payload Server with Redirector {COLORS['GRAY']}(With traffic redirection){COLORS['RESET']}")
print(f"99) Return to Main Menu")
choice = input(f"\nSelect an option: ")
if choice == "1":
deploy_basic_payload_server()
elif choice == "2":
deploy_multi_format_payload_server()
elif choice == "3":
deploy_document_payload_server()
elif choice == "4":
deploy_mobile_payload_server()
elif choice == "5":
deploy_secure_payload_server()
elif choice == "6":
deploy_payload_server_with_redirector()
elif choice == "99":
return
else:
print(f"\n{COLORS['RED']}Invalid option. Please try again.{COLORS['RESET']}")
wait_for_input()
def deploy_basic_payload_server():
"""Deploy basic payload server"""
config = gather_payload_parameters()
if not config:
return
config['deployment_type'] = 'basic_payload_server'
config['enable_basic_auth'] = False
config['enable_ip_filtering'] = False
config['enable_user_agent_filtering'] = False
print(f"\n{COLORS['GREEN']}Deploying basic payload server...{COLORS['RESET']}")
execute_payload_deployment(config)
def deploy_payload_server_with_redirector():
"""Deploy payload server with redirector"""
config = gather_payload_parameters()
if not config:
return
# Additional redirector configuration
config['redirector_subdomain'] = input("Redirector subdomain [default: dl]: ") or "dl"
config['deployment_type'] = 'payload_server_with_redirector'
config['deploy_redirector'] = True
print(f"\n{COLORS['GREEN']}Deploying payload server with redirector...{COLORS['RESET']}")
execute_payload_deployment(config)
def deploy_secure_payload_server():
"""Deploy secure payload server with authentication and filtering"""
config = gather_payload_parameters()
if not config:
return
config['deployment_type'] = 'secure_payload_server'
config['enable_basic_auth'] = True
config['enable_ip_filtering'] = True
config['enable_user_agent_filtering'] = True
config['enable_rate_limiting'] = True
# Additional security configuration
config['auth_username'] = input("Basic auth username [default: admin]: ") or "admin"
config['auth_password'] = input("Basic auth password [default: random]: ") or None
print(f"\n{COLORS['GREEN']}Deploying secure payload server...{COLORS['RESET']}")
execute_payload_deployment(config)
def deploy_mobile_payload_server():
"""Deploy mobile payload server"""
config = gather_payload_parameters()
if not config:
return
config['deployment_type'] = 'mobile_payload_server'
config['host_mobile'] = True
config['host_executables'] = False
config['host_scripts'] = False
config['host_documents'] = False
print(f"\n{COLORS['GREEN']}Deploying mobile payload server...{COLORS['RESET']}")
execute_payload_deployment(config)
def deploy_document_payload_server():
"""Deploy document payload server"""
config = gather_payload_parameters()
if not config:
return
config['deployment_type'] = 'document_payload_server'
config['host_documents'] = True
config['host_executables'] = False
config['host_scripts'] = False
config['host_mobile'] = False
print(f"\n{COLORS['GREEN']}Deploying document payload server...{COLORS['RESET']}")
execute_payload_deployment(config)
def deploy_multi_format_payload_server():
"""Deploy multi-format payload server"""
config = gather_payload_parameters()
if not config:
return
config['deployment_type'] = 'multi_format_payload_server'
config['host_executables'] = True
config['host_scripts'] = True
config['host_documents'] = True
config['host_mobile'] = True
print(f"\n{COLORS['GREEN']}Deploying multi-format payload server...{COLORS['RESET']}")
execute_payload_deployment(config)
def execute_payload_deployment(config):
"""Execute payload server infrastructure deployment"""
clear_screen()
print_banner()
print(f"\n{COLORS['GREEN']}Starting payload server deployment...{COLORS['RESET']}")
# Set up logging
log_file = setup_logging(config['deployment_id'], "payload_deployment")
# Display configuration summary
print(f"\n{COLORS['CYAN']}Deployment Summary:{COLORS['RESET']}")
print(f"Deployment Type: {config['deployment_type']}")
print(f"Deployment ID: {config['deployment_id']}")
print(f"Provider: {config['provider']}")
print(f"Domain: {config['domain']}")
print(f"Host Executables: {config.get('host_executables', False)}")
print(f"Host Scripts: {config.get('host_scripts', False)}")
print(f"Host Documents: {config.get('host_documents', False)}")
print(f"Host Mobile: {config.get('host_mobile', False)}")
# Confirm deployment
if not confirm_action(f"\n{COLORS['YELLOW']}Proceed with payload server deployment?{COLORS['RESET']}", default=False):
print(f"\n{COLORS['YELLOW']}Deployment cancelled.{COLORS['RESET']}")
return
# Execute the actual deployment
success = execute_ansible_deployment(config)
if success:
print(f"\n{COLORS['GREEN']}Payload server infrastructure deployed successfully!{COLORS['RESET']}")
if config.get('ssh_after_deploy'):
from utils.ssh_utils import ssh_to_instance
ssh_to_instance(config)
else:
print(f"\n{COLORS['RED']}Payload server infrastructure deployment failed.{COLORS['RESET']}")
wait_for_input()
def execute_ansible_deployment(config):
"""Execute the Ansible deployment based on configuration"""
import subprocess
deployment_type = config.get('deployment_type')
provider = config.get('provider')
print(f"\n{COLORS['BLUE']}Executing {deployment_type} deployment on {provider}...{COLORS['RESET']}")
# Use the payload server playbooks
playbook_map = {
'basic_payload_server': 'payload_server.yml',
'payload_server_with_redirector': 'payload_server.yml',
'secure_payload_server': 'payload_server.yml',
'mobile_payload_server': 'payload_server.yml',
'document_payload_server': 'payload_server.yml',
'multi_format_payload_server': 'payload_server.yml'
}
playbook = playbook_map.get(deployment_type)
if not playbook:
print(f"{COLORS['RED']}Unknown deployment type: {deployment_type}{COLORS['RESET']}")
return False
# Change to the module directory and execute the playbook
module_dir = os.path.dirname(__file__)
playbook_path = os.path.join(module_dir, playbook)
if not os.path.exists(playbook_path):
print(f"{COLORS['YELLOW']}Playbook not found: {playbook_path}{COLORS['RESET']}")
print(f"{COLORS['YELLOW']}This would normally execute the {playbook} playbook{COLORS['RESET']}")
return True # Simulate success for now
try:
# Build the ansible-playbook command
cmd = [
'ansible-playbook',
playbook_path,
'-e', f'deployment_id={config["deployment_id"]}',
'-e', f'provider={config["provider"]}',
'-e', f'domain={config["domain"]}',
'-e', f'deployment_type={deployment_type}'
]
# Add payload-specific variables
for key in ['host_executables', 'host_scripts', 'host_documents', 'host_mobile']:
if key in config:
cmd.extend(['-e', f'{key}={str(config[key]).lower()}'])
# Add security options
for key in ['enable_basic_auth', 'enable_ip_filtering', 'enable_user_agent_filtering', 'enable_rate_limiting']:
if key in config:
cmd.extend(['-e', f'{key}={str(config[key]).lower()}'])
# Add provider-specific variables
if provider == 'aws':
if config.get('aws_access_key'):
cmd.extend(['-e', f'aws_access_key={config["aws_access_key"]}'])
if config.get('aws_secret_key'):
cmd.extend(['-e', f'aws_secret_key={config["aws_secret_key"]}'])
if config.get('aws_region'):
cmd.extend(['-e', f'aws_region={config["aws_region"]}'])
# Execute the playbook
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print(f"{COLORS['GREEN']}Ansible playbook executed successfully{COLORS['RESET']}")
return True
else:
print(f"{COLORS['RED']}Ansible playbook failed:{COLORS['RESET']}")
print(result.stderr)
return False
except Exception as e:
print(f"{COLORS['RED']}Error executing playbook: {e}{COLORS['RESET']}")
return False
if __name__ == "__main__":
payload_menu()
@@ -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
@@ -0,0 +1,24 @@
---
# Payload Redirector Deployment Playbook
- name: Deploy payload redirector
hosts: localhost
gather_facts: false
connection: local
vars_files:
- vars.yaml
vars:
deployment_id: "{{ deployment_id | default('') }}"
payload_redirector_name: "{{ payload_redirector_name | default('pr-' + deployment_id) }}"
provider: "{{ provider | default('aws') }}"
tasks:
- name: Deploy payload redirector based on provider
include_tasks: "../providers/{{ provider | upper }}/redirector.yml"
vars:
redirector_name: "{{ payload_redirector_name }}"
redirector_type: "payload"
redirector_subdomain: "{{ payload_subdomain | default('files') }}"
- name: Configure payload redirector
include_tasks: "tasks/configure_payload_redirector.yml"
when: not skip_configuration | default(false)
+23
View File
@@ -0,0 +1,23 @@
---
# Payload Server Deployment Playbook
- name: Deploy payload server
hosts: localhost
gather_facts: false
connection: local
vars_files:
- vars.yaml
vars:
deployment_id: "{{ deployment_id | default('') }}"
payload_server_name: "{{ payload_server_name | default('ps-' + deployment_id) }}"
provider: "{{ provider | default('aws') }}"
tasks:
- name: Deploy payload server based on provider
include_tasks: "../providers/{{ provider | upper }}/c2.yml"
vars:
c2_name: "{{ payload_server_name }}"
server_type: "payload"
- name: Configure payload server
include_tasks: "tasks/configure_payload_server.yml"
when: not skip_configuration | default(false)
@@ -0,0 +1,89 @@
---
# Configure payload redirector for hosting and delivering payloads
- name: Install required packages
apt:
name:
- nginx
- certbot
- python3-certbot-nginx
state: present
update_cache: yes
- name: Create payload directories
file:
path: "{{ item }}"
state: directory
mode: '0755'
owner: www-data
group: www-data
loop:
- /var/www/payloads
- /var/www/payloads/windows
- /var/www/payloads/linux
- /var/www/payloads/macos
- /var/www/payloads/docs
- name: Configure NGINX for payload delivery
template:
src: "../templates/phishing/nginx-payload-redirector.j2"
dest: /etc/nginx/sites-available/payloads
mode: '0644'
- name: Enable payload site
file:
src: /etc/nginx/sites-available/payloads
dest: /etc/nginx/sites-enabled/payloads
state: link
- name: Create payload sync script
template:
src: "../templates/phishing/sync_payloads.sh.j2"
dest: /root/Tools/sync_payloads.sh
mode: '0700'
- name: Set up payload sync timer
block:
- name: Create systemd service
copy:
content: |
[Unit]
Description=Payload Sync Service
After=network.target
[Service]
Type=oneshot
ExecStart=/root/Tools/sync_payloads.sh
User=root
[Install]
WantedBy=multi-user.target
dest: /etc/systemd/system/payload-sync.service
- name: Create systemd timer
copy:
content: |
[Unit]
Description=Payload Sync Timer
Requires=payload-sync.service
[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Persistent=true
[Install]
WantedBy=timers.target
dest: /etc/systemd/system/payload-sync.timer
- name: Enable and start timer
systemd:
name: payload-sync.timer
state: started
enabled: yes
daemon_reload: yes
- name: Configure firewall rules
include_tasks: security_hardening.yml
vars:
server_role: "payload_redirector"
@@ -0,0 +1,78 @@
---
# Configure payload server for creating and hosting malicious payloads
- name: Install payload generation tools
apt:
name:
- mingw-w64
- golang
- python3-pip
- upx-ucl
- osslsigncode
- mono-complete
- wine64
- wine32
state: present
update_cache: yes
- name: Create payload directories
file:
path: "{{ item }}"
state: directory
mode: '0700'
owner: root
group: root
loop:
- /root/Tools/payloads
- /root/Tools/payloads/templates
- /root/Tools/payloads/output
- /root/Tools/payloads/scripts
- name: Install Python payload tools
pip:
name:
- pycryptodome
- pyinstaller
- py2exe
state: present
- name: Clone payload generation tools
git:
repo: "{{ item.repo }}"
dest: "{{ item.dest }}"
loop:
- { repo: "https://github.com/Binject/go-donut", dest: "/root/Tools/go-donut" }
- { repo: "https://github.com/optiv/ScareCrow", dest: "/root/Tools/ScareCrow" }
- { repo: "https://github.com/TheWover/donut", dest: "/root/Tools/donut" }
- name: Build Go tools
shell: |
cd {{ item }} && go build
args:
creates: "{{ item }}/{{ item | basename }}"
loop:
- /root/Tools/go-donut
- /root/Tools/ScareCrow
- name: Deploy payload generation scripts
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: '0700'
loop:
- { src: "../templates/phishing/generate_doc_payloads.sh.j2", dest: "/root/Tools/payloads/scripts/generate_docs.sh" }
- { src: "../templates/phishing/generate_exe_payloads.sh.j2", dest: "/root/Tools/payloads/scripts/generate_exes.sh" }
- { src: "../templates/phishing/payload_obfuscator.py.j2", dest: "/root/Tools/payloads/scripts/obfuscate.py" }
- name: Create payload hosting service
template:
src: "../templates/phishing/payload-server.service.j2"
dest: /etc/systemd/system/payload-server.service
mode: '0644'
- name: Start payload server
systemd:
name: payload-server
state: started
enabled: yes
daemon_reload: yes