restructuring for easier navigation and modularity
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
# tasks/cleanup_confirmation.yml - Common task file for cleanup confirmation
|
||||
- name: Show cleanup information
|
||||
debug:
|
||||
msg: |
|
||||
************************************************
|
||||
* CLEANUP OPERATION *
|
||||
************************************************
|
||||
The following resources will be DELETED PERMANENTLY:
|
||||
{% if cleanup_redirector and redirector_name is defined %}
|
||||
- Redirector: {{ redirector_name }} ({{ redirector_ip | default('IP unknown') }})
|
||||
{% endif %}
|
||||
{% if cleanup_c2 and c2_name is defined %}
|
||||
- C2 Server: {{ c2_name }} ({{ c2_ip | default('IP unknown') }})
|
||||
{% endif %}
|
||||
when: confirm_cleanup | bool
|
||||
|
||||
- name: Confirm cleanup operation
|
||||
pause:
|
||||
prompt: "\n>>> Type 'yes' to confirm deletion or press Ctrl+C to abort <<<"
|
||||
register: confirmation
|
||||
when: confirm_cleanup | bool
|
||||
|
||||
- name: Skip cleanup if not confirmed
|
||||
meta: end_play
|
||||
when: confirm_cleanup | bool and confirmation.user_input != 'yes'
|
||||
@@ -1,137 +0,0 @@
|
||||
---
|
||||
# Advanced evasion techniques for red team phishing
|
||||
|
||||
- name: Install advanced evasion tools
|
||||
apt:
|
||||
name:
|
||||
- python3-dnspython
|
||||
- python3-requests
|
||||
- python3-selenium
|
||||
- chromium-browser
|
||||
- chromium-chromedriver
|
||||
- tor
|
||||
- proxychains4
|
||||
state: present
|
||||
|
||||
- name: Create SMTP smuggling configuration
|
||||
template:
|
||||
src: "../templates/smtp-smuggling.py.j2"
|
||||
dest: "/root/Tools/phishing/smtp-smuggling.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: enable_smtp_smuggling | default(false) | bool
|
||||
|
||||
- name: Configure SPF bypass techniques
|
||||
template:
|
||||
src: "../templates/spf-bypass.sh.j2"
|
||||
dest: "/root/Tools/phishing/spf-bypass.sh"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: enable_spf_bypass | default(false) | bool
|
||||
|
||||
- name: Create domain aging simulation
|
||||
template:
|
||||
src: "../templates/domain-aging.py.j2"
|
||||
dest: "/root/Tools/phishing/domain-aging.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: aged_domain_mode | default(false) | bool
|
||||
|
||||
- name: Set up MTA fronting configuration
|
||||
template:
|
||||
src: "../templates/mta-fronting.conf.j2"
|
||||
dest: "/etc/postfix/mta_fronting.cf"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
when: enable_mta_fronting | default(false) | bool
|
||||
notify: restart postfix
|
||||
|
||||
- name: Create file format manipulation tools
|
||||
copy:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- { src: "../files/pdf-weaponizer.py", dest: "/root/Tools/phishing/pdf-weaponizer.py" }
|
||||
- { src: "../files/office-macro-generator.py", dest: "/root/Tools/phishing/office-macro-generator.py" }
|
||||
- { src: "../files/lnk-generator.py", dest: "/root/Tools/phishing/lnk-generator.py" }
|
||||
|
||||
- name: Create Living off the Land (LOtL) payload templates
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- { src: "../templates/lotl-powershell.ps1.j2", dest: "/root/Tools/phishing/templates/lotl-powershell.ps1" }
|
||||
- { src: "../templates/lotl-wmic.cmd.j2", dest: "/root/Tools/phishing/templates/lotl-wmic.cmd" }
|
||||
- { src: "../templates/lotl-bitsadmin.cmd.j2", dest: "/root/Tools/phishing/templates/lotl-bitsadmin.cmd" }
|
||||
|
||||
- name: Set up CDN abuse configuration
|
||||
template:
|
||||
src: "../templates/cdn-abuse.py.j2"
|
||||
dest: "/root/Tools/phishing/cdn-abuse.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: enable_cdn_abuse | default(false) | bool
|
||||
|
||||
- name: Create domain reputation monitoring
|
||||
template:
|
||||
src: "../templates/reputation-monitor.py.j2"
|
||||
dest: "/root/Tools/phishing/reputation-monitor.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Set up cron job for reputation monitoring
|
||||
cron:
|
||||
name: "Domain reputation monitoring"
|
||||
minute: "0"
|
||||
hour: "*/4"
|
||||
job: "/root/Tools/phishing/reputation-monitor.py >> /root/Tools/phishing/logs/reputation.log 2>&1"
|
||||
|
||||
- name: Create email header spoofing tools
|
||||
template:
|
||||
src: "../templates/header-spoofing.py.j2"
|
||||
dest: "/root/Tools/phishing/header-spoofing.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Configure Tor for anonymization
|
||||
template:
|
||||
src: "../templates/torrc-phishing.j2"
|
||||
dest: "/etc/tor/torrc"
|
||||
backup: yes
|
||||
notify: restart tor
|
||||
when: enable_tor_routing | default(false) | bool
|
||||
|
||||
- name: Create user-agent rotation script
|
||||
template:
|
||||
src: "../templates/user-agent-rotation.py.j2"
|
||||
dest: "/root/Tools/phishing/user-agent-rotation.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Set up automated evasion techniques
|
||||
template:
|
||||
src: "../templates/automated-evasion.py.j2"
|
||||
dest: "/root/Tools/phishing/automated-evasion.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
handlers:
|
||||
- name: restart tor
|
||||
systemd:
|
||||
name: tor
|
||||
state: restarted
|
||||
@@ -1,344 +0,0 @@
|
||||
---
|
||||
# Common tasks for configuring C2 server with Havoc C2 and EDR evasion
|
||||
# Shared across all providers
|
||||
|
||||
- name: Update apt cache
|
||||
apt:
|
||||
update_cache: yes
|
||||
|
||||
- name: Disable default Kali MOTD
|
||||
file:
|
||||
path: "{{ ansible_env.HOME }}/.hushlogin"
|
||||
state: touch
|
||||
mode: '0644'
|
||||
when: ansible_distribution == "Kali GNU/Linux"
|
||||
|
||||
- name: Set a custom MOTD
|
||||
template:
|
||||
src: "../templates/motd.j2"
|
||||
dest: /etc/motd
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
- name: Install base utilities and tools via apt
|
||||
apt:
|
||||
name:
|
||||
- git
|
||||
- wget
|
||||
- curl
|
||||
- unzip
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- tmux
|
||||
- pipx
|
||||
- nmap
|
||||
- tcpdump
|
||||
- hydra
|
||||
- john
|
||||
- hashcat
|
||||
- sqlmap
|
||||
- gobuster
|
||||
- dirb
|
||||
- enum4linux
|
||||
- dnsenum
|
||||
- seclists
|
||||
- responder
|
||||
- golang
|
||||
- proxychains
|
||||
- tor
|
||||
- crackmapexec
|
||||
- jq
|
||||
- build-essential
|
||||
- zip
|
||||
- unzip
|
||||
- postfix
|
||||
- net-tools
|
||||
- certbot
|
||||
- opendkim
|
||||
- opendkim-tools
|
||||
- dovecot-core
|
||||
- dovecot-imapd
|
||||
- dovecot-pop3d
|
||||
- dovecot-sieve
|
||||
- dovecot-managesieved
|
||||
- yq
|
||||
- build-essential
|
||||
# Additional Havoc C2 dependencies
|
||||
- mingw-w64
|
||||
- nasm
|
||||
- cmake
|
||||
- ninja-build
|
||||
- libfontconfig1
|
||||
- libglu1-mesa-dev
|
||||
- libgtest-dev
|
||||
- libspdlog-dev
|
||||
- libboost-all-dev
|
||||
- libncurses5-dev
|
||||
- libgdbm-dev
|
||||
- libssl-dev
|
||||
- libreadline-dev
|
||||
- libffi-dev
|
||||
- libsqlite3-dev
|
||||
- libbz2-dev
|
||||
- mesa-common-dev
|
||||
- qtbase5-dev
|
||||
- qtchooser
|
||||
- qt5-qmake
|
||||
- qtbase5-dev-tools
|
||||
- libqt5websockets5
|
||||
- libqt5websockets5-dev
|
||||
state: present
|
||||
|
||||
- name: Create directories for operational scripts
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- /root/Tools
|
||||
- /root/Tools/beacons
|
||||
- /root/Tools/payloads
|
||||
|
||||
- name: Copy operational scripts
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "/root/Tools/{{ item | basename }}"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- "../files/clean-logs.sh"
|
||||
- "../files/secure-exit.sh"
|
||||
- "../files/havoc_installer.sh"
|
||||
- "../files/havoc_shell_handler.sh"
|
||||
- "../files/secure_payload_sync.sh"
|
||||
|
||||
- name: Copy post-install script
|
||||
copy:
|
||||
src: "../files/post_install_c2.sh"
|
||||
dest: "/root/Tools/post_install_c2.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Copy port randomization script
|
||||
copy:
|
||||
src: "../files/randomize_ports.sh"
|
||||
dest: "/root/Tools/randomize_ports.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create post-install instructions
|
||||
template:
|
||||
src: "../templates/POST_INSTALL_INSTRUCTIONS.txt.j2"
|
||||
dest: "/root/POST_INSTALL_INSTRUCTIONS.txt"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Set up systemd timer for payload sync
|
||||
shell: |
|
||||
cat > /etc/systemd/system/payload-sync.service << 'EOF'
|
||||
[Unit]
|
||||
Description=Secure Payload Sync Service
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/root/Tools/secure_payload_sync.sh
|
||||
User=root
|
||||
Group=root
|
||||
PrivateTmp=true
|
||||
StandardOutput=null
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat > /etc/systemd/system/payload-sync.timer << 'EOF'
|
||||
[Unit]
|
||||
Description=Secure Payload Sync Timer
|
||||
Requires=payload-sync.service
|
||||
|
||||
[Timer]
|
||||
OnBootSec=5min
|
||||
OnUnitActiveSec=30m
|
||||
RandomizedDelaySec=30m
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable payload-sync.timer
|
||||
systemctl start payload-sync.timer
|
||||
|
||||
- name: Install Havoc C2 Framework
|
||||
shell: "/root/Tools/havoc_installer.sh"
|
||||
args:
|
||||
creates: "/root/Tools/Havoc"
|
||||
async: 1800 # Allow 30 minutes for completion
|
||||
poll: 0 # Don't wait for completion
|
||||
register: havoc_installation_job
|
||||
|
||||
- name: Wait for Havoc installation to complete
|
||||
async_status:
|
||||
jid: "{{ havoc_installation_job.ansible_job_id }}"
|
||||
register: job_result
|
||||
until: job_result.finished
|
||||
retries: 60 # Check every 30 seconds for up to 30 minutes
|
||||
delay: 30
|
||||
when: havoc_installation_job is defined
|
||||
|
||||
- name: Display Havoc installation output
|
||||
debug:
|
||||
var: havoc_installation_result.stdout_lines
|
||||
when: havoc_installation_result.stdout_lines is defined
|
||||
|
||||
- name: Create Havoc payload generation script
|
||||
template:
|
||||
src: "../templates/generate_havoc_payloads.sh.j2"
|
||||
dest: "/root/Tools/generate_havoc_payloads.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create Havoc C2 configuration from template
|
||||
template:
|
||||
src: "../templates/havoc-config.yaotl.j2"
|
||||
dest: "/root/Tools/Havoc/data/havoc.yaotl"
|
||||
mode: '0600'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create Linux loader script template
|
||||
template:
|
||||
src: "../templates/linux_loader.sh.j2"
|
||||
dest: "/root/Tools/linux_loader.template"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create Windows PowerShell loader template
|
||||
template:
|
||||
src: "../templates/windows_loader.ps1.j2"
|
||||
dest: "/root/Tools/windows_loader.template"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create beacon server script from template
|
||||
template:
|
||||
src: "../templates/serve-havoc-payloads.sh.j2"
|
||||
dest: "/root/Tools/serve-havoc-payloads.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
vars:
|
||||
redirector_subdomain: "{{ redirector_subdomain | default('cdn') }}"
|
||||
domain: "{{ domain }}"
|
||||
redirector_port: "{{ redirector_port | default('443') }}"
|
||||
|
||||
- name: Run port randomization if enabled
|
||||
include_tasks: port_randomization.yml
|
||||
when: randomize_ports | default(false) | bool
|
||||
|
||||
- name: Generate Havoc payloads
|
||||
shell: "/root/Tools/generate_havoc_payloads.sh"
|
||||
args:
|
||||
creates: "/root/Tools/Havoc/payloads/manifest.json"
|
||||
register: payload_generation_result
|
||||
environment:
|
||||
PATH: "{{ ansible_env.PATH }}:/usr/local/bin"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Display payload generation output
|
||||
debug:
|
||||
var: payload_generation_result.stdout_lines
|
||||
when: payload_generation_result.stdout_lines is defined
|
||||
|
||||
- name: Start payload server
|
||||
shell: |
|
||||
nohup /root/Tools/serve-havoc-payloads.sh > /dev/null 2>&1 &
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: beacon_server_result
|
||||
|
||||
- name: Create NGINX configuration fragment for redirector
|
||||
template:
|
||||
src: "../templates/redirector-havoc-fragment.j2"
|
||||
dest: "/root/Tools/redirector-config.conf"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
vars:
|
||||
c2_ip: "{{ ansible_host }}"
|
||||
redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"
|
||||
|
||||
- name: Create Havoc usage guide
|
||||
template:
|
||||
src: "../templates/havoc-guide.j2"
|
||||
dest: "/root/havoc-guide.txt"
|
||||
mode: '0600'
|
||||
owner: root
|
||||
group: root
|
||||
vars:
|
||||
c2_ip: "{{ ansible_host }}"
|
||||
redirector_domain: "{{ redirector_subdomain }}.{{ domain }}"
|
||||
|
||||
- name: Include traffic flow configuration
|
||||
include_tasks: "../tasks/traffic_flow_config.yml"
|
||||
|
||||
- name: Set up cron job for log cleaning if zero-logs enabled
|
||||
cron:
|
||||
name: "Clean logs"
|
||||
minute: "0"
|
||||
hour: "*/6"
|
||||
job: "/root/Tools/clean-logs.sh > /dev/null 2>&1"
|
||||
when: zero_logs | bool
|
||||
|
||||
- name: Ensure SSH key for redirector access is available
|
||||
block:
|
||||
- name: Copy deployment SSH key to C2 for redirector access (AWS)
|
||||
copy:
|
||||
src: "~/.ssh/c2deploy_{{ deployment_id }}.pem"
|
||||
dest: "/root/.ssh/redirector_key"
|
||||
mode: '0600'
|
||||
owner: root
|
||||
group: root
|
||||
when: provider == "aws"
|
||||
|
||||
- name: Copy deployment SSH key to C2 for redirector access (non-AWS)
|
||||
copy:
|
||||
src: "{{ ssh_key_path | replace('.pub', '') }}"
|
||||
dest: "/root/.ssh/redirector_key"
|
||||
mode: '0600'
|
||||
owner: root
|
||||
group: root
|
||||
when: provider != "aws"
|
||||
|
||||
- name: Create SSH config for redirector access
|
||||
blockinfile:
|
||||
path: /root/.ssh/config
|
||||
create: yes
|
||||
mode: '0600'
|
||||
owner: root
|
||||
group: root
|
||||
marker: "# {mark} ANSIBLE MANAGED REDIRECTOR CONFIG"
|
||||
block: |
|
||||
Host redirector
|
||||
HostName {{ redirector_ip }}
|
||||
User {{ ssh_user | default('root') }}
|
||||
IdentityFile /root/.ssh/redirector_key
|
||||
StrictHostKeyChecking no
|
||||
when: not redirector_only | bool and redirector_ip is defined
|
||||
|
||||
# Include integrated tracker tasks if requested
|
||||
- name: Include integrated tracker setup
|
||||
include_tasks: "configure_integrated_tracker.yml"
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
@@ -1,111 +0,0 @@
|
||||
---
|
||||
# FedRAMP compliance configuration for user awareness testing
|
||||
|
||||
- name: Create FedRAMP compliant landing pages
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
with_items:
|
||||
- { src: "../templates/fedramp-success-page.html.j2", dest: "/var/www/phishing/fedramp-success.html" }
|
||||
- { src: "../templates/fedramp-education-page.html.j2", dest: "/var/www/phishing/fedramp-education.html" }
|
||||
- { src: "../templates/fedramp-training-materials.html.j2", dest: "/var/www/phishing/training.html" }
|
||||
|
||||
- name: Create FedRAMP compliant email templates
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- { src: "../templates/fedramp-email-template.html.j2", dest: "/root/Tools/phishing/templates/fedramp-email.html" }
|
||||
- { src: "../templates/fedramp-notification-email.html.j2", dest: "/root/Tools/phishing/templates/fedramp-notification.html" }
|
||||
|
||||
- name: Configure anonymized reporting
|
||||
template:
|
||||
src: "../templates/fedramp-reporting.py.j2"
|
||||
dest: "/root/Tools/phishing/fedramp-reporting.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create role-based tracking system
|
||||
template:
|
||||
src: "../templates/role-tracking.py.j2"
|
||||
dest: "/root/Tools/phishing/role-tracking.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Set up immediate phish identification
|
||||
template:
|
||||
src: "../templates/immediate-identification.js.j2"
|
||||
dest: "/var/www/phishing/assets/immediate-identification.js"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Create educational content delivery system
|
||||
template:
|
||||
src: "../templates/education-delivery.php.j2"
|
||||
dest: "/var/www/phishing/api/education.php"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Configure compliance database schema
|
||||
shell: |
|
||||
sqlite3 /root/Tools/phishing/compliance.db << EOF
|
||||
CREATE TABLE IF NOT EXISTS fedramp_campaigns (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
csp_organization TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
status TEXT DEFAULT 'active'
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS role_interactions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
campaign_id TEXT NOT NULL,
|
||||
user_role TEXT NOT NULL,
|
||||
interaction_type TEXT NOT NULL,
|
||||
interaction_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
education_completed BOOLEAN DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS compliance_metrics (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
campaign_id TEXT NOT NULL,
|
||||
metric_type TEXT NOT NULL,
|
||||
metric_value INTEGER NOT NULL,
|
||||
recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
EOF
|
||||
args:
|
||||
creates: /root/Tools/phishing/compliance.db
|
||||
|
||||
- name: Set database permissions for compliance
|
||||
file:
|
||||
path: /root/Tools/phishing/compliance.db
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: '0644'
|
||||
|
||||
- name: Create compliance report generator
|
||||
template:
|
||||
src: "../templates/compliance-report-generator.py.j2"
|
||||
dest: "/root/Tools/phishing/generate-compliance-report.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Configure email allowlisting instructions
|
||||
template:
|
||||
src: "../templates/allowlist-instructions.md.j2"
|
||||
dest: "/root/Tools/phishing/ALLOWLIST_INSTRUCTIONS.md"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
@@ -1,198 +0,0 @@
|
||||
---
|
||||
# Advanced Gophish configuration with enhanced evasion and features
|
||||
|
||||
- name: Create Gophish user
|
||||
user:
|
||||
name: gophish
|
||||
system: yes
|
||||
shell: /bin/bash
|
||||
home: /opt/gophish
|
||||
create_home: yes
|
||||
|
||||
- name: Download latest Gophish release
|
||||
get_url:
|
||||
url: "https://github.com/gophish/gophish/releases/download/v0.12.1/gophish-v0.12.1-linux-64bit.zip"
|
||||
dest: /tmp/gophish.zip
|
||||
mode: '0644'
|
||||
|
||||
- name: Extract Gophish
|
||||
unarchive:
|
||||
src: /tmp/gophish.zip
|
||||
dest: /opt/gophish
|
||||
owner: gophish
|
||||
group: gophish
|
||||
remote_src: yes
|
||||
|
||||
- name: Install additional packages for advanced features
|
||||
apt:
|
||||
name:
|
||||
- nginx
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
- sqlite3
|
||||
- jq
|
||||
- curl
|
||||
- wget
|
||||
- php-fpm
|
||||
- php-sqlite3
|
||||
- nodejs
|
||||
- npm
|
||||
state: present
|
||||
|
||||
- name: Configure advanced Gophish settings
|
||||
template:
|
||||
src: "../templates/phishing/gophish-advanced-config.j2"
|
||||
dest: /opt/gophish/config.json
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0600'
|
||||
|
||||
- name: Create enhanced email templates directory
|
||||
file:
|
||||
path: /opt/gophish/templates/{{ item }}
|
||||
state: directory
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0755'
|
||||
loop:
|
||||
- email
|
||||
- landing
|
||||
- static
|
||||
|
||||
- name: Deploy email templates
|
||||
template:
|
||||
src: "../templates/phishing/email-templates/{{ item }}.j2"
|
||||
dest: "/opt/gophish/templates/email/{{ item }}.html"
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0644'
|
||||
loop:
|
||||
- office365_login
|
||||
- password_expiry
|
||||
- security_alert
|
||||
- file_share
|
||||
when: not fedramp_mode | default(false) | bool
|
||||
|
||||
- name: Deploy FedRAMP compliant templates
|
||||
template:
|
||||
src: "../templates/phishing/fedramp-compliance.j2"
|
||||
dest: "/opt/gophish/templates/email/fedramp_template.html"
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0644'
|
||||
when: fedramp_mode | default(false) | bool
|
||||
|
||||
- name: Create advanced landing pages
|
||||
template:
|
||||
src: "../templates/phishing/phishing-landing-page.j2"
|
||||
dest: "/opt/gophish/templates/landing/{{ item }}_landing.html"
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0644'
|
||||
loop:
|
||||
- office365
|
||||
- generic
|
||||
- fedramp
|
||||
vars:
|
||||
template_type: "{{ item }}"
|
||||
|
||||
- name: Install enhanced tracking pixel
|
||||
copy:
|
||||
src: "../files/simple_email_tracker.py"
|
||||
dest: /opt/gophish/tracker.py
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0755'
|
||||
|
||||
- name: Create Gophish database backup script
|
||||
template:
|
||||
src: "../templates/phishing/gophish-backup.sh.j2"
|
||||
dest: /opt/gophish/backup.sh
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0755'
|
||||
|
||||
- name: Set up database backup cron
|
||||
cron:
|
||||
name: "Backup Gophish database"
|
||||
minute: "0"
|
||||
hour: "*/6"
|
||||
job: "/opt/gophish/backup.sh"
|
||||
user: gophish
|
||||
|
||||
- name: Create Gophish systemd service
|
||||
template:
|
||||
src: "../templates/phishing/gophish.service.j2"
|
||||
dest: /etc/systemd/system/gophish.service
|
||||
mode: '0644'
|
||||
|
||||
- name: Enable and start Gophish service
|
||||
systemd:
|
||||
name: gophish
|
||||
state: started
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
|
||||
- name: Create campaign automation script
|
||||
template:
|
||||
src: "../templates/phishing/campaign-automation.py.j2"
|
||||
dest: /opt/gophish/campaign-automation.py
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0755'
|
||||
|
||||
- name: Install Python dependencies for automation
|
||||
pip:
|
||||
name:
|
||||
- requests
|
||||
- python-dateutil
|
||||
- jinja2
|
||||
state: present
|
||||
|
||||
- name: Configure SMTP relay to MTA front
|
||||
blockinfile:
|
||||
path: /opt/gophish/config.json
|
||||
marker: "// {mark} ANSIBLE MANAGED SMTP CONFIG"
|
||||
block: |
|
||||
"smtp": {
|
||||
"host": "{{ mta_front_ip }}:587",
|
||||
"username": "{{ smtp_relay_user }}",
|
||||
"password": "{{ smtp_relay_pass }}",
|
||||
"from": "{{ sender_email }}",
|
||||
"ignore_cert_errors": true
|
||||
}
|
||||
|
||||
- name: Create phishing metrics dashboard
|
||||
template:
|
||||
src: "../templates/phishing/metrics-dashboard.html.j2"
|
||||
dest: /opt/gophish/static/metrics.html
|
||||
owner: gophish
|
||||
group: gophish
|
||||
mode: '0644'
|
||||
|
||||
- name: Set up log aggregation
|
||||
lineinfile:
|
||||
path: /etc/rsyslog.conf
|
||||
line: "local0.* /var/log/gophish.log"
|
||||
state: present
|
||||
notify: restart rsyslog
|
||||
|
||||
- name: Configure log rotation for Gophish
|
||||
copy:
|
||||
dest: /etc/logrotate.d/gophish
|
||||
content: |
|
||||
/var/log/gophish.log {
|
||||
daily
|
||||
missingok
|
||||
rotate 30
|
||||
compress
|
||||
delaycompress
|
||||
notifempty
|
||||
create 0644 gophish gophish
|
||||
}
|
||||
|
||||
handlers:
|
||||
- name: restart rsyslog
|
||||
service:
|
||||
name: rsyslog
|
||||
state: restarted
|
||||
@@ -1,150 +0,0 @@
|
||||
---
|
||||
# Common task for configuring integrated email tracker on C2 server
|
||||
|
||||
- name: Check if integrated tracker setup is requested
|
||||
debug:
|
||||
msg: "Setting up integrated email tracker on C2 server"
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Install required packages for tracker
|
||||
apt:
|
||||
name:
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- python3-pillow
|
||||
- nginx
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
- jq
|
||||
state: present
|
||||
update_cache: yes
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Create tracker directory
|
||||
file:
|
||||
path: /root/Tools/tracker
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Create tracker data directory
|
||||
file:
|
||||
path: /root/Tools/tracker/data
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Create tracker system user
|
||||
user:
|
||||
name: tracker
|
||||
system: yes
|
||||
shell: /usr/sbin/nologin
|
||||
home: /root/Tools/tracker
|
||||
create_home: no
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Create Python virtual environment for tracker
|
||||
pip:
|
||||
virtualenv: /root/Tools/tracker/venv
|
||||
name:
|
||||
- flask
|
||||
- pillow
|
||||
- gunicorn
|
||||
virtualenv_command: /usr/bin/python3 -m venv
|
||||
environment:
|
||||
PATH: "/usr/local/bin:/usr/bin:/bin"
|
||||
vars:
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Copy tracker application code
|
||||
copy:
|
||||
src: "../files/simple_email_tracker.py"
|
||||
dest: /root/Tools/tracker/simple_email_tracker.py
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Copy tracker statistics CLI tool
|
||||
copy:
|
||||
src: "../files/tracker-stats.sh"
|
||||
dest: /root/Tools/tracker/tracker-stats.sh
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Copy systemd service file for tracker
|
||||
copy:
|
||||
src: "../files/tracker.service"
|
||||
dest: /etc/systemd/system/tracker.service
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Set correct permissions for tracker directories
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: tracker
|
||||
group: tracker
|
||||
recurse: yes
|
||||
loop:
|
||||
- /root/Tools/tracker
|
||||
- /root/Tools/tracker/data
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Create NGINX site config for tracker
|
||||
template:
|
||||
src: "../files/tracker-nginx.conf"
|
||||
dest: /etc/nginx/sites-available/tracker
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
vars:
|
||||
tracker_domain: "{{ tracker_domain | default('track.' + domain) }}"
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Enable tracker NGINX site
|
||||
file:
|
||||
src: /etc/nginx/sites-available/tracker
|
||||
dest: /etc/nginx/sites-enabled/tracker
|
||||
state: link
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Configure redirector to proxy tracking requests
|
||||
lineinfile:
|
||||
path: /etc/nginx/sites-available/default
|
||||
insertafter: "^\\s*location / {"
|
||||
line: " # Email tracker proxy path\n location /px/(.*)\\.png$ {\n proxy_pass http://{{ c2_ip }}:443/pixel/$1.png;\n proxy_set_header Host {{ tracker_domain }};\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-Proto https;\n }"
|
||||
delegate_to: "{{ groups['redirectors'][0] }}"
|
||||
when: setup_integrated_tracker | default(false) | bool and groups['redirectors'] is defined
|
||||
|
||||
- name: Set up SSL if requested
|
||||
shell: |
|
||||
certbot --nginx -d {{ tracker_domain }} --non-interactive --agree-tos -m {{ tracker_email }}
|
||||
args:
|
||||
creates: /etc/letsencrypt/live/{{ tracker_domain }}/fullchain.pem
|
||||
when: setup_integrated_tracker | default(false) | bool and tracker_setup_ssl | default(true) | bool
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Start and enable tracker service
|
||||
systemd:
|
||||
name: tracker
|
||||
state: started
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
|
||||
- name: Add tracker alias to bashrc for easy access
|
||||
lineinfile:
|
||||
path: /root/.bashrc
|
||||
line: 'alias tracker="/root/Tools/tracker/tracker-stats.sh"'
|
||||
state: present
|
||||
when: setup_integrated_tracker | default(false) | bool
|
||||
@@ -1,170 +0,0 @@
|
||||
---
|
||||
# Common task for configuring mail server
|
||||
# Shared across all providers
|
||||
|
||||
- name: Configure Postfix main.cf
|
||||
lineinfile:
|
||||
path: /etc/postfix/main.cf
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
with_items:
|
||||
- { regexp: '^myhostname', line: "myhostname = mail.{{ domain }}" }
|
||||
- { regexp: '^mydomain', line: "mydomain = {{ domain }}" }
|
||||
- { regexp: '^myorigin', line: "myorigin = $mydomain" }
|
||||
- { regexp: '^inet_interfaces', line: "inet_interfaces = all" }
|
||||
- { regexp: '^inet_protocols', line: "inet_protocols = ipv4" }
|
||||
- { regexp: '^smtpd_banner', line: "smtpd_banner = $myhostname ESMTP $mail_name" }
|
||||
- { regexp: '^mynetworks', line: "mynetworks = 127.0.0.0/8 [::1]/128" }
|
||||
- { regexp: '^relay_domains', line: "relay_domains = $mydestination" }
|
||||
- { regexp: '^smtpd_tls_cert_file', line: "smtpd_tls_cert_file = /etc/letsencrypt/live/{{ domain }}/fullchain.pem" }
|
||||
- { regexp: '^smtpd_tls_key_file', line: "smtpd_tls_key_file = /etc/letsencrypt/live/{{ domain }}/privkey.pem" }
|
||||
- { regexp: '^smtpd_tls_security_level', line: "smtpd_tls_security_level = encrypt" }
|
||||
- { regexp: '^smtpd_tls_session_cache_database', line: "smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache" }
|
||||
- { regexp: '^smtp_tls_session_cache_database', line: "smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache" }
|
||||
- { regexp: '^smtpd_use_tls', line: "smtpd_use_tls = yes" }
|
||||
- { regexp: '^smtpd_tls_auth_only', line: "smtpd_tls_auth_only = yes" }
|
||||
- { regexp: '^milter_default_action', line: "milter_default_action = accept" }
|
||||
- { regexp: '^milter_protocol', line: "milter_protocol = 6" }
|
||||
- { regexp: '^smtpd_milters', line: "smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock" }
|
||||
- { regexp: '^non_smtpd_milters', line: "non_smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock" }
|
||||
|
||||
- name: Configure OpenDKIM
|
||||
lineinfile:
|
||||
path: /etc/opendkim.conf
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
with_items:
|
||||
- { regexp: '^Domain', line: "Domain {{ domain }}" }
|
||||
- { regexp: '^KeyFile', line: "KeyFile /etc/opendkim/keys/{{ domain }}/mail.private" }
|
||||
- { regexp: '^Selector', line: "Selector mail" }
|
||||
- { regexp: '^Socket', line: "Socket local:/var/spool/postfix/opendkim/opendkim.sock" }
|
||||
- { regexp: '^Syslog', line: "Syslog yes" }
|
||||
- { regexp: '^UMask', line: "UMask 002" }
|
||||
- { regexp: '^Mode', line: "Mode sv" }
|
||||
|
||||
- name: Create DKIM directory
|
||||
file:
|
||||
path: /etc/opendkim/keys/{{ domain }}
|
||||
state: directory
|
||||
owner: opendkim
|
||||
group: opendkim
|
||||
mode: 0700
|
||||
|
||||
- name: Generate DKIM keys
|
||||
command: >
|
||||
opendkim-genkey -D /etc/opendkim/keys/{{ domain }} -d {{ domain }} -s mail
|
||||
args:
|
||||
creates: /etc/opendkim/keys/{{ domain }}/mail.private
|
||||
|
||||
- name: Set permissions for DKIM keys
|
||||
file:
|
||||
path: /etc/opendkim/keys/{{ domain }}/mail.private
|
||||
owner: opendkim
|
||||
group: opendkim
|
||||
mode: 0600
|
||||
|
||||
- name: Configure OpenDKIM TrustedHosts
|
||||
copy:
|
||||
content: |
|
||||
127.0.0.1
|
||||
::1
|
||||
localhost
|
||||
{{ domain }}
|
||||
dest: /etc/opendkim/TrustedHosts
|
||||
owner: opendkim
|
||||
group: opendkim
|
||||
mode: 0644
|
||||
|
||||
- name: Enable submission port (587) in master.cf
|
||||
blockinfile:
|
||||
path: /etc/postfix/master.cf
|
||||
insertafter: '^#submission'
|
||||
block: |
|
||||
submission inet n - y - - smtpd
|
||||
-o syslog_name=postfix/submission
|
||||
-o smtpd_tls_security_level=encrypt
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
|
||||
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
|
||||
- name: Configure Dovecot for Postfix SASL
|
||||
blockinfile:
|
||||
path: /etc/dovecot/conf.d/10-master.conf
|
||||
insertafter: '^service auth {'
|
||||
block: |
|
||||
# Postfix smtp-auth
|
||||
unix_listener /var/spool/postfix/private/auth {
|
||||
mode = 0660
|
||||
user = postfix
|
||||
group = postfix
|
||||
}
|
||||
|
||||
- name: Set Dovecot auth_mechanisms
|
||||
lineinfile:
|
||||
path: /etc/dovecot/conf.d/10-auth.conf
|
||||
regexp: '^auth_mechanisms'
|
||||
line: 'auth_mechanisms = plain login'
|
||||
|
||||
- name: Create Dovecot password file for SASL authentication
|
||||
file:
|
||||
path: /etc/dovecot/passwd
|
||||
state: touch
|
||||
mode: '0600'
|
||||
owner: dovecot
|
||||
group: dovecot
|
||||
|
||||
- name: Add SMTP auth user to Dovecot
|
||||
lineinfile:
|
||||
path: /etc/dovecot/passwd
|
||||
line: "{{ smtp_auth_user }}:{{ smtp_auth_pass | password_hash('sha512_crypt') }}"
|
||||
|
||||
- name: Disable system auth and use passwd-file
|
||||
lineinfile:
|
||||
path: /etc/dovecot/conf.d/10-auth.conf
|
||||
regexp: '^!include auth-system.conf.ext'
|
||||
line: '#!include auth-system.conf.ext'
|
||||
|
||||
- name: Add auth-passwdfile configuration
|
||||
blockinfile:
|
||||
path: /etc/dovecot/conf.d/10-auth.conf
|
||||
insertafter: '^auth_mechanisms ='
|
||||
block: |
|
||||
passdb {
|
||||
driver = passwd-file
|
||||
args = scheme=sha512_crypt /etc/dovecot/passwd
|
||||
}
|
||||
userdb {
|
||||
driver = static
|
||||
args = uid=vmail gid=vmail home=/var/vmail/%u
|
||||
}
|
||||
|
||||
- name: Create vmail group
|
||||
group:
|
||||
name: vmail
|
||||
gid: 5000
|
||||
state: present
|
||||
|
||||
- name: Create vmail user
|
||||
user:
|
||||
name: vmail
|
||||
uid: 5000
|
||||
group: vmail
|
||||
create_home: no
|
||||
|
||||
- name: Create vmail directory structure
|
||||
file:
|
||||
path: /var/vmail
|
||||
state: directory
|
||||
owner: vmail
|
||||
group: vmail
|
||||
mode: 0700
|
||||
|
||||
- name: Restart Postfix
|
||||
service:
|
||||
name: postfix
|
||||
state: restarted
|
||||
|
||||
- name: Restart Dovecot
|
||||
service:
|
||||
name: dovecot
|
||||
state: restarted
|
||||
@@ -1,151 +0,0 @@
|
||||
---
|
||||
# Configure MTA Front server for email relay and SMTP smuggling
|
||||
|
||||
- name: Update system packages
|
||||
apt:
|
||||
update_cache: yes
|
||||
upgrade: dist
|
||||
|
||||
- name: Install MTA packages
|
||||
apt:
|
||||
name:
|
||||
- postfix
|
||||
- postfix-pcre
|
||||
- dovecot-core
|
||||
- dovecot-imapd
|
||||
- opendkim
|
||||
- opendkim-tools
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- nginx
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
- dnsutils
|
||||
- swaks
|
||||
- telnet
|
||||
state: present
|
||||
|
||||
- name: Configure Postfix for MTA fronting
|
||||
template:
|
||||
src: "../templates/phishing/postfix-mta-front.j2"
|
||||
dest: /etc/postfix/main.cf
|
||||
backup: yes
|
||||
notify: restart postfix
|
||||
|
||||
- name: Configure Postfix master.cf for advanced relaying
|
||||
blockinfile:
|
||||
path: /etc/postfix/master.cf
|
||||
block: |
|
||||
# SMTP smuggling and advanced relay configurations
|
||||
587 inet n - y - - smtpd
|
||||
-o syslog_name=postfix/submission
|
||||
-o smtpd_tls_security_level=encrypt
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
-o smtpd_tls_wrappermode=no
|
||||
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
|
||||
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
|
||||
-o milter_macro_daemon_name=ORIGINATING
|
||||
|
||||
# SMTP smuggling support
|
||||
cleanup unix n - y - 0 cleanup
|
||||
-o header_checks=pcre:/etc/postfix/header_checks
|
||||
-o nested_header_checks=pcre:/etc/postfix/nested_header_checks
|
||||
|
||||
- name: Create SMTP smuggling header checks
|
||||
copy:
|
||||
dest: /etc/postfix/header_checks
|
||||
content: |
|
||||
# SMTP smuggling techniques
|
||||
/^Content-Transfer-Encoding:\s*7bit/i REPLACE Content-Transfer-Encoding: 8bit
|
||||
/^Content-Type:\s*text\/plain/i REPLACE Content-Type: text/html
|
||||
mode: '0644'
|
||||
notify:
|
||||
- reload postfix
|
||||
- postmap header_checks
|
||||
|
||||
- name: Create nested header checks for advanced smuggling
|
||||
copy:
|
||||
dest: /etc/postfix/nested_header_checks
|
||||
content: |
|
||||
# Advanced SMTP smuggling patterns
|
||||
/^\s*<script/i IGNORE
|
||||
/^\s*<iframe/i IGNORE
|
||||
mode: '0644'
|
||||
notify:
|
||||
- reload postfix
|
||||
- postmap nested_header_checks
|
||||
|
||||
- name: Configure DKIM for domain reputation
|
||||
include_tasks: ../tasks/configure_mail.yml
|
||||
|
||||
- name: Create relay authentication
|
||||
copy:
|
||||
dest: /etc/postfix/sasl_passwd
|
||||
content: |
|
||||
{{ phishing_domain }} {{ smtp_relay_user }}:{{ smtp_relay_pass }}
|
||||
mode: '0600'
|
||||
owner: root
|
||||
group: root
|
||||
notify:
|
||||
- postmap sasl_passwd
|
||||
- restart postfix
|
||||
|
||||
- name: Configure transport maps for backend routing
|
||||
copy:
|
||||
dest: /etc/postfix/transport
|
||||
content: |
|
||||
{{ phishing_domain }} smtp:[{{ gophish_ip }}]:25
|
||||
.{{ phishing_domain }} smtp:[{{ gophish_ip }}]:25
|
||||
mode: '0644'
|
||||
notify:
|
||||
- postmap transport
|
||||
- restart postfix
|
||||
|
||||
- name: Install Python SMTP testing tools
|
||||
pip:
|
||||
name:
|
||||
- smtplib-extended
|
||||
- email-validator
|
||||
- faker
|
||||
state: present
|
||||
|
||||
- name: Create SMTP smuggling test script
|
||||
template:
|
||||
src: "../templates/phishing/smtp-smuggling-test.py.j2"
|
||||
dest: /root/Tools/smtp-smuggling-test.py
|
||||
mode: '0755'
|
||||
|
||||
- name: Create email reputation monitoring script
|
||||
template:
|
||||
src: "../templates/phishing/reputation-monitor.sh.j2"
|
||||
dest: /root/Tools/reputation-monitor.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Set up log monitoring for deliverability
|
||||
cron:
|
||||
name: "Monitor email deliverability"
|
||||
minute: "*/15"
|
||||
job: "/root/Tools/reputation-monitor.sh >> /var/log/reputation.log 2>&1"
|
||||
|
||||
handlers:
|
||||
- name: restart postfix
|
||||
service:
|
||||
name: postfix
|
||||
state: restarted
|
||||
|
||||
- name: reload postfix
|
||||
service:
|
||||
name: postfix
|
||||
state: reloaded
|
||||
|
||||
- name: postmap header_checks
|
||||
command: postmap /etc/postfix/header_checks
|
||||
|
||||
- name: postmap nested_header_checks
|
||||
command: postmap /etc/postfix/nested_header_checks
|
||||
|
||||
- name: postmap sasl_passwd
|
||||
command: postmap /etc/postfix/sasl_passwd
|
||||
|
||||
- name: postmap transport
|
||||
command: postmap /etc/postfix/transport
|
||||
@@ -1,157 +0,0 @@
|
||||
---
|
||||
# Configure phishing redirector with advanced evasion techniques
|
||||
|
||||
- name: Install packages for phishing redirector
|
||||
apt:
|
||||
name:
|
||||
- nginx
|
||||
- nginx-extras
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
- socat
|
||||
- netcat-openbsd
|
||||
- jq
|
||||
- curl
|
||||
- geoip-database
|
||||
- libgeoip1
|
||||
- php-fpm
|
||||
- php-geoip
|
||||
state: present
|
||||
|
||||
- name: Configure advanced nginx for phishing redirector
|
||||
template:
|
||||
src: "../templates/phishing/nginx-phishing-redirector.j2"
|
||||
dest: /etc/nginx/sites-available/phishing-redirector
|
||||
mode: '0644'
|
||||
notify: restart nginx
|
||||
|
||||
- name: Enable phishing redirector site
|
||||
file:
|
||||
src: /etc/nginx/sites-available/phishing-redirector
|
||||
dest: /etc/nginx/sites-enabled/phishing-redirector
|
||||
state: link
|
||||
notify: restart nginx
|
||||
|
||||
- name: Remove default nginx site
|
||||
file:
|
||||
path: /etc/nginx/sites-enabled/default
|
||||
state: absent
|
||||
notify: restart nginx
|
||||
|
||||
- name: Create legitimate website content
|
||||
template:
|
||||
src: "../templates/phishing/legitimate-website.html.j2"
|
||||
dest: /var/www/html/index.html
|
||||
mode: '0644'
|
||||
|
||||
- name: Create robots.txt for SEO legitimacy
|
||||
copy:
|
||||
dest: /var/www/html/robots.txt
|
||||
content: |
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Sitemap: https://{{ phishing_subdomain }}.{{ phishing_domain }}/sitemap.xml
|
||||
|
||||
- name: Create sitemap for legitimacy
|
||||
template:
|
||||
src: "../templates/phishing/sitemap.xml.j2"
|
||||
dest: /var/www/html/sitemap.xml
|
||||
mode: '0644'
|
||||
|
||||
- name: Install MaxMind GeoIP for location-based filtering
|
||||
get_url:
|
||||
url: "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&license_key={{ maxmind_license_key | default('') }}&suffix=tar.gz"
|
||||
dest: /tmp/geoip.tar.gz
|
||||
when: maxmind_license_key is defined
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Create security research filtering script
|
||||
template:
|
||||
src: "../templates/phishing/security-filter.lua.j2"
|
||||
dest: /etc/nginx/security-filter.lua
|
||||
mode: '0644'
|
||||
|
||||
- name: Configure nginx stream module for advanced traffic analysis
|
||||
template:
|
||||
src: "../templates/phishing/stream-analysis.conf.j2"
|
||||
dest: /etc/nginx/modules-enabled/stream-analysis.conf
|
||||
mode: '0644'
|
||||
|
||||
- name: Create phishing campaign analytics
|
||||
template:
|
||||
src: "../templates/phishing/analytics.js.j2"
|
||||
dest: /var/www/html/analytics.js
|
||||
mode: '0644'
|
||||
|
||||
- name: Set up legitimate SSL certificate
|
||||
shell: |
|
||||
certbot --nginx -d {{ phishing_subdomain }}.{{ phishing_domain }} \
|
||||
--non-interactive --agree-tos -m {{ letsencrypt_email }}
|
||||
args:
|
||||
creates: /etc/letsencrypt/live/{{ phishing_subdomain }}.{{ phishing_domain }}/fullchain.pem
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Create fail2ban configuration for suspicious activity
|
||||
copy:
|
||||
dest: /etc/fail2ban/jail.d/phishing-protection.conf
|
||||
content: |
|
||||
[phishing-scanner-protection]
|
||||
enabled = true
|
||||
port = 80,443
|
||||
filter = phishing-scanner
|
||||
logpath = /var/log/nginx/access.log
|
||||
maxretry = 3
|
||||
bantime = 3600
|
||||
findtime = 300
|
||||
|
||||
- name: Create fail2ban filter for security tools
|
||||
copy:
|
||||
dest: /etc/fail2ban/filter.d/phishing-scanner.conf
|
||||
content: |
|
||||
[Definition]
|
||||
failregex = ^<HOST>.*"(GET|POST).*(nmap|nikto|sqlmap|burp|w3af|nessus|openvas).*"
|
||||
^<HOST>.*".*User-Agent.*(scanner|bot|crawl|security|test).*"
|
||||
^<HOST>.*"(GET|POST).*\.(php|asp|jsp)\?.*"
|
||||
ignoreregex =
|
||||
|
||||
- name: Start and enable fail2ban
|
||||
systemd:
|
||||
name: fail2ban
|
||||
state: started
|
||||
enabled: yes
|
||||
|
||||
- name: Create traffic monitoring script
|
||||
template:
|
||||
src: "../templates/phishing/traffic-monitor.sh.j2"
|
||||
dest: /root/Tools/traffic-monitor.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Set up traffic monitoring cron
|
||||
cron:
|
||||
name: "Monitor phishing traffic"
|
||||
minute: "*/5"
|
||||
job: "/root/Tools/traffic-monitor.sh >> /var/log/phishing-traffic.log 2>&1"
|
||||
|
||||
- name: Configure rate limiting for suspicious patterns
|
||||
blockinfile:
|
||||
path: /etc/nginx/nginx.conf
|
||||
insertbefore: "http {"
|
||||
block: |
|
||||
# Rate limiting zones
|
||||
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
|
||||
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
|
||||
|
||||
# GeoIP configuration
|
||||
geoip_country /usr/share/GeoIP/GeoIP.dat;
|
||||
map $geoip_country_code $allowed_country {
|
||||
default 1;
|
||||
CN 0;
|
||||
RU 0;
|
||||
KP 0;
|
||||
}
|
||||
|
||||
handlers:
|
||||
- name: restart nginx
|
||||
service:
|
||||
name: nginx
|
||||
state: restarted
|
||||
@@ -1,296 +0,0 @@
|
||||
---
|
||||
# Common tasks for configuring advanced phishing server
|
||||
# Supports both red team and FedRAMP compliance modes
|
||||
|
||||
- name: Update system packages
|
||||
apt:
|
||||
update_cache: yes
|
||||
upgrade: dist
|
||||
|
||||
- name: Install base packages for phishing server
|
||||
apt:
|
||||
name:
|
||||
- nginx
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
- postfix
|
||||
- dovecot-core
|
||||
- dovecot-imapd
|
||||
- opendkim
|
||||
- opendkim-tools
|
||||
- sqlite3
|
||||
- git
|
||||
- curl
|
||||
- wget
|
||||
- jq
|
||||
- unzip
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- nodejs
|
||||
- npm
|
||||
- php-fpm
|
||||
- php-sqlite3
|
||||
- php-curl
|
||||
- php-json
|
||||
- swaks
|
||||
- dnsutils
|
||||
- net-tools
|
||||
- fail2ban
|
||||
state: present
|
||||
|
||||
- name: Create phishing tools directory
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- /root/Tools/phishing
|
||||
- /root/Tools/phishing/templates
|
||||
- /root/Tools/phishing/campaigns
|
||||
- /root/Tools/phishing/logs
|
||||
- /var/www/phishing
|
||||
- /var/www/phishing/assets
|
||||
- /var/www/phishing/api
|
||||
|
||||
- name: Set up GoPhish directory
|
||||
file:
|
||||
path: /root/Tools/gophish
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Download latest GoPhish release
|
||||
shell: |
|
||||
LATEST_URL=$(curl -s https://api.github.com/repos/gophish/gophish/releases/latest | jq -r '.assets[] | select(.browser_download_url | contains("linux-64bit.zip")) | .browser_download_url')
|
||||
curl -L "$LATEST_URL" -o /tmp/gophish.zip
|
||||
unzip /tmp/gophish.zip -d /root/Tools/gophish
|
||||
chmod +x /root/Tools/gophish/gophish
|
||||
rm -f /tmp/gophish.zip
|
||||
args:
|
||||
creates: /root/Tools/gophish/gophish
|
||||
|
||||
- name: Create advanced GoPhish configuration
|
||||
template:
|
||||
src: "../templates/advanced-gophish-config.j2"
|
||||
dest: "/root/Tools/gophish/config.json"
|
||||
mode: '0600'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create GoPhish systemd service
|
||||
template:
|
||||
src: "../templates/gophish.service.j2"
|
||||
dest: "/etc/systemd/system/gophish.service"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Configure Postfix for outbound email
|
||||
template:
|
||||
src: "../templates/postfix-phishing.conf.j2"
|
||||
dest: "/etc/postfix/main.cf"
|
||||
backup: yes
|
||||
notify: restart postfix
|
||||
|
||||
- name: Configure OpenDKIM for email authentication
|
||||
template:
|
||||
src: "../templates/opendkim-phishing.conf.j2"
|
||||
dest: "/etc/opendkim.conf"
|
||||
backup: yes
|
||||
notify: restart opendkim
|
||||
|
||||
- name: Create DKIM keys directory
|
||||
file:
|
||||
path: "/etc/opendkim/keys/{{ phishing_domain }}"
|
||||
state: directory
|
||||
owner: opendkim
|
||||
group: opendkim
|
||||
mode: '0700'
|
||||
|
||||
- name: Generate DKIM keys
|
||||
command: >
|
||||
opendkim-genkey -D /etc/opendkim/keys/{{ phishing_domain }}
|
||||
-d {{ phishing_domain }} -s phishing
|
||||
args:
|
||||
creates: "/etc/opendkim/keys/{{ phishing_domain }}/phishing.private"
|
||||
|
||||
- name: Set DKIM key permissions
|
||||
file:
|
||||
path: "/etc/opendkim/keys/{{ phishing_domain }}/phishing.private"
|
||||
owner: opendkim
|
||||
group: opendkim
|
||||
mode: '0600'
|
||||
|
||||
- name: Create phishing landing page templates
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
with_items:
|
||||
- { src: "../templates/phishing-landing-office365.html.j2", dest: "/var/www/phishing/office365.html" }
|
||||
- { src: "../templates/phishing-landing-gmail.html.j2", dest: "/var/www/phishing/gmail.html" }
|
||||
- { src: "../templates/phishing-landing-aws.html.j2", dest: "/var/www/phishing/aws.html" }
|
||||
- { src: "../templates/phishing-landing-generic.html.j2", dest: "/var/www/phishing/generic.html" }
|
||||
|
||||
- name: Create credential capture API
|
||||
template:
|
||||
src: "../templates/credential-capture-api.php.j2"
|
||||
dest: "/var/www/phishing/api/capture.php"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Create tracking pixel endpoint
|
||||
template:
|
||||
src: "../templates/tracking-pixel.php.j2"
|
||||
dest: "/var/www/phishing/track.php"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Configure Nginx for phishing sites
|
||||
template:
|
||||
src: "../templates/nginx-phishing.conf.j2"
|
||||
dest: "/etc/nginx/sites-available/phishing"
|
||||
mode: '0644'
|
||||
notify: reload nginx
|
||||
|
||||
- name: Enable phishing site
|
||||
file:
|
||||
src: /etc/nginx/sites-available/phishing
|
||||
dest: /etc/nginx/sites-enabled/phishing
|
||||
state: link
|
||||
notify: reload nginx
|
||||
|
||||
- name: Create phishing campaign management scripts
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- { src: "../templates/campaign-launcher.sh.j2", dest: "/root/Tools/phishing/launch-campaign.sh" }
|
||||
- { src: "../templates/stats-collector.sh.j2", dest: "/root/Tools/phishing/collect-stats.sh" }
|
||||
- { src: "../templates/email-validator.py.j2", dest: "/root/Tools/phishing/validate-emails.py" }
|
||||
|
||||
- name: Create database for tracking
|
||||
shell: |
|
||||
sqlite3 /root/Tools/phishing/tracking.db << EOF
|
||||
CREATE TABLE IF NOT EXISTS email_opens (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
campaign_id TEXT NOT NULL,
|
||||
recipient_email TEXT NOT NULL,
|
||||
ip_address TEXT,
|
||||
user_agent TEXT,
|
||||
opened_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
location TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS link_clicks (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
campaign_id TEXT NOT NULL,
|
||||
recipient_email TEXT NOT NULL,
|
||||
link_url TEXT NOT NULL,
|
||||
ip_address TEXT,
|
||||
user_agent TEXT,
|
||||
clicked_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
location TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS credential_submissions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
campaign_id TEXT NOT NULL,
|
||||
recipient_email TEXT,
|
||||
username TEXT,
|
||||
password_hash TEXT,
|
||||
ip_address TEXT,
|
||||
user_agent TEXT,
|
||||
submitted_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
location TEXT,
|
||||
additional_data TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS campaigns (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
template TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
status TEXT DEFAULT 'active',
|
||||
target_count INTEGER DEFAULT 0,
|
||||
opened_count INTEGER DEFAULT 0,
|
||||
clicked_count INTEGER DEFAULT 0,
|
||||
submitted_count INTEGER DEFAULT 0
|
||||
);
|
||||
EOF
|
||||
args:
|
||||
creates: /root/Tools/phishing/tracking.db
|
||||
|
||||
- name: Set database permissions
|
||||
file:
|
||||
path: /root/Tools/phishing/tracking.db
|
||||
owner: www-data
|
||||
group: www-data
|
||||
mode: '0644'
|
||||
|
||||
- name: Install Python dependencies for advanced features
|
||||
pip:
|
||||
name:
|
||||
- requests
|
||||
- beautifulsoup4
|
||||
- lxml
|
||||
- flask
|
||||
- flask-cors
|
||||
- dnspython
|
||||
- python-whois
|
||||
- selenium
|
||||
- fake-useragent
|
||||
state: present
|
||||
|
||||
- name: Create SSL certificate setup script
|
||||
template:
|
||||
src: "../templates/setup-phishing-ssl.sh.j2"
|
||||
dest: "/root/Tools/phishing/setup-ssl.sh"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create domain reputation checker
|
||||
template:
|
||||
src: "../templates/domain-reputation.py.j2"
|
||||
dest: "/root/Tools/phishing/check-reputation.py"
|
||||
mode: '0755'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Start and enable services
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
state: started
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
with_items:
|
||||
- postfix
|
||||
- opendkim
|
||||
- nginx
|
||||
- php7.4-fpm
|
||||
- gophish
|
||||
|
||||
handlers:
|
||||
- name: restart postfix
|
||||
systemd:
|
||||
name: postfix
|
||||
state: restarted
|
||||
|
||||
- name: restart opendkim
|
||||
systemd:
|
||||
name: opendkim
|
||||
state: restarted
|
||||
|
||||
- name: reload nginx
|
||||
systemd:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
@@ -1,457 +0,0 @@
|
||||
---
|
||||
# Common task for configuring redirector with full encryption
|
||||
# Shared across all providers
|
||||
|
||||
- name: Set a custom MOTD
|
||||
template:
|
||||
src: "../templates/motd-redirector.j2"
|
||||
dest: /etc/motd
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
|
||||
- name: Update package cache with retries
|
||||
apt:
|
||||
update_cache: yes
|
||||
cache_valid_time: 0
|
||||
register: cache_update
|
||||
until: cache_update is success
|
||||
retries: 5
|
||||
delay: 10
|
||||
ignore_errors: no
|
||||
|
||||
- name: Install core packages first (high priority)
|
||||
apt:
|
||||
name:
|
||||
- nginx
|
||||
- nginx-extras
|
||||
- socat
|
||||
- jq
|
||||
- secure-delete
|
||||
state: present
|
||||
update_cache: no
|
||||
register: core_packages
|
||||
until: core_packages is success
|
||||
retries: 3
|
||||
delay: 5
|
||||
|
||||
- name: Install network utilities with fallbacks
|
||||
block:
|
||||
- name: Try to install net-tools
|
||||
apt:
|
||||
name: net-tools
|
||||
state: present
|
||||
update_cache: no
|
||||
register: net_tools_install
|
||||
|
||||
rescue:
|
||||
- name: Install alternative network utilities
|
||||
apt:
|
||||
name:
|
||||
- iproute2
|
||||
- iputils-ping
|
||||
- netcat-openbsd
|
||||
state: present
|
||||
update_cache: no
|
||||
register: alt_network_tools
|
||||
|
||||
- name: Create net-tools compatibility aliases
|
||||
copy:
|
||||
dest: /usr/local/bin/netstat
|
||||
content: |
|
||||
#!/bin/bash
|
||||
# Compatibility wrapper for netstat using ss
|
||||
ss "$@"
|
||||
mode: '0755'
|
||||
when: alt_network_tools is success
|
||||
|
||||
- name: Install PHP-FPM with version handling
|
||||
block:
|
||||
- name: Install PHP-FPM (latest available)
|
||||
apt:
|
||||
name: php-fpm
|
||||
state: present
|
||||
update_cache: no
|
||||
register: php_install
|
||||
|
||||
rescue:
|
||||
- name: Install specific PHP version as fallback
|
||||
apt:
|
||||
name:
|
||||
- php7.4-fpm
|
||||
- php7.4-cli
|
||||
state: present
|
||||
update_cache: no
|
||||
register: php_fallback
|
||||
|
||||
- name: Install certbot with dependency handling
|
||||
block:
|
||||
- name: Install certbot and nginx plugin
|
||||
apt:
|
||||
name:
|
||||
- certbot
|
||||
- python3-certbot-nginx
|
||||
state: present
|
||||
update_cache: no
|
||||
register: certbot_install
|
||||
|
||||
rescue:
|
||||
- name: Install certbot without problematic dependencies
|
||||
shell: |
|
||||
apt-get install -y --no-install-recommends certbot
|
||||
apt-get install -y --fix-broken || true
|
||||
register: certbot_manual
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Install certbot via snap as ultimate fallback
|
||||
block:
|
||||
- name: Install snap if not present
|
||||
apt:
|
||||
name: snapd
|
||||
state: present
|
||||
|
||||
- name: Install certbot via snap
|
||||
snap:
|
||||
name: certbot
|
||||
classic: yes
|
||||
|
||||
- name: Create certbot symlink
|
||||
file:
|
||||
src: /snap/bin/certbot
|
||||
dest: /usr/bin/certbot
|
||||
state: link
|
||||
when: certbot_manual is failed
|
||||
|
||||
- name: Handle problematic Python dependencies
|
||||
block:
|
||||
- name: Try installing Python dependencies normally
|
||||
apt:
|
||||
name:
|
||||
- python3-requests-toolbelt
|
||||
- python3-zope.hookable
|
||||
state: present
|
||||
update_cache: no
|
||||
register: python_deps
|
||||
|
||||
rescue:
|
||||
- name: Install Python dependencies via pip as fallback
|
||||
pip:
|
||||
name:
|
||||
- requests-toolbelt
|
||||
- zope.hookable
|
||||
state: present
|
||||
register: pip_install
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Download and install packages manually if repositories are down
|
||||
shell: |
|
||||
cd /tmp
|
||||
# Try alternative repositories
|
||||
wget -q http://archive.ubuntu.com/ubuntu/pool/universe/p/python-requests-toolbelt/python3-requests-toolbelt_0.8.0-1.1_all.deb || \
|
||||
wget -q http://launchpad.net/ubuntu/+archive/primary/+files/python3-requests-toolbelt_0.8.0-1.1_all.deb || true
|
||||
|
||||
if [ -f python3-requests-toolbelt_*.deb ]; then
|
||||
dpkg -i python3-requests-toolbelt_*.deb || apt-get install -f -y
|
||||
fi
|
||||
when: pip_install is failed
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Verify critical packages are installed
|
||||
command: "{{ item.cmd }}"
|
||||
register: package_verify
|
||||
failed_when: package_verify.rc != 0
|
||||
loop:
|
||||
- { cmd: "nginx -v", name: "nginx" }
|
||||
- { cmd: "socat -V", name: "socat" }
|
||||
- { cmd: "jq --version", name: "jq" }
|
||||
- { cmd: "which certbot", name: "certbot" }
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Create package installation report
|
||||
debug:
|
||||
msg: |
|
||||
C2ingRed Package Installation Status:
|
||||
===================================
|
||||
Core Packages: {{ 'SUCCESS' if core_packages is success else 'FAILED' }}
|
||||
Network Tools: {{ 'SUCCESS' if net_tools_install is success else 'FALLBACK USED' }}
|
||||
PHP-FPM: {{ 'SUCCESS' if php_install is success else 'FALLBACK USED' if php_fallback is success else 'FAILED' }}
|
||||
Certbot: {{ 'SUCCESS' if certbot_install is success else 'FALLBACK USED' }}
|
||||
Python Deps: {{ 'SUCCESS' if python_deps is success else 'FALLBACK ATTEMPTED' }}
|
||||
|
||||
Critical Services Verified:
|
||||
{% for item in package_verify.results %}
|
||||
- {{ item.item.name }}: {{ 'OK' if item.rc == 0 else 'MISSING' }}
|
||||
{% endfor %}
|
||||
|
||||
- name: Force fix broken packages if any installation failed
|
||||
shell: |
|
||||
apt-get update --fix-missing
|
||||
apt-get install -f -y
|
||||
dpkg --configure -a
|
||||
when: core_packages is failed or certbot_install is failed
|
||||
register: fix_broken
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Final package status check and remediation
|
||||
block:
|
||||
- name: Check for any remaining broken packages
|
||||
shell: apt-get check
|
||||
register: apt_check
|
||||
failed_when: false
|
||||
|
||||
- name: List installed packages for verification
|
||||
shell: |
|
||||
echo "=== INSTALLED PACKAGES ==="
|
||||
dpkg -l | grep -E "(nginx|certbot|socat|jq|php)" || echo "Some packages missing"
|
||||
echo "=== BROKEN PACKAGES ==="
|
||||
apt-get check 2>&1 | grep -i "broken\|error" || echo "No broken packages detected"
|
||||
register: final_status
|
||||
|
||||
- name: Display final installation status
|
||||
debug:
|
||||
var: final_status.stdout_lines
|
||||
|
||||
- name: Ensure critical services are enabled
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
enabled: yes
|
||||
state: started
|
||||
loop:
|
||||
- nginx
|
||||
- php7.4-fpm
|
||||
ignore_errors: yes
|
||||
register: service_start
|
||||
|
||||
- name: Create operational readiness marker
|
||||
copy:
|
||||
dest: /tmp/c2ingred_packages_ready
|
||||
content: |
|
||||
C2ingRed Package Installation Complete
|
||||
Timestamp: {{ ansible_date_time.iso8601 }}
|
||||
Status: {{ 'READY' if core_packages is success else 'PARTIAL' }}
|
||||
mode: '0644'
|
||||
|
||||
- name: Create directories for operational scripts
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- /root/Tools
|
||||
- /root/Tools/shell-handler
|
||||
|
||||
- name: Copy clean-logs.sh script
|
||||
copy:
|
||||
src: "../files/clean-logs.sh"
|
||||
dest: /root/Tools/clean-logs.sh
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Copy redirector post-install script
|
||||
copy:
|
||||
src: "../files/post_install_redirector.sh"
|
||||
dest: "/root/Tools/post_install_redirector.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Copy port randomization script
|
||||
copy:
|
||||
src: "../files/randomize_ports.sh"
|
||||
dest: "/root/Tools/randomize_ports.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create redirector post-install instructions
|
||||
copy:
|
||||
content: |
|
||||
================================================================
|
||||
C2ingRed Redirector Post-Installation Instructions
|
||||
================================================================
|
||||
|
||||
To complete your setup with SSL certificates, run:
|
||||
/root/Tools/post_install_redirector.sh
|
||||
|
||||
This script will guide you through:
|
||||
- Setting up Let's Encrypt certificates
|
||||
- Starting required services
|
||||
- Updating NGINX configuration
|
||||
|
||||
For enhanced OPSEC, you can also randomize ports:
|
||||
/root/Tools/randomize_ports.sh
|
||||
|
||||
Run these after you've configured your DNS records to point to this server.
|
||||
dest: "/root/POST_INSTALL_INSTRUCTIONS.txt"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Copy shell handler script
|
||||
copy:
|
||||
src: "../files/havoc_shell_handler.sh"
|
||||
dest: /root/Tools/shell-handler/persistent-listener.sh
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Configure shell handler script with C2 IP
|
||||
replace:
|
||||
path: /root/Tools/shell-handler/persistent-listener.sh
|
||||
regexp: 'C2_HOST="127.0.0.1"'
|
||||
replace: 'C2_HOST="{{ c2_ip }}"'
|
||||
|
||||
- name: Configure shell handler script with listening port
|
||||
template:
|
||||
src: "../files/havoc_shell_handler.sh"
|
||||
dest: "/root/Tools/shell_handler.sh"
|
||||
mode: 0755
|
||||
vars:
|
||||
listen_port: "{{ shell_handler_port | default(8083) }}"
|
||||
|
||||
- name: Create shell handler service
|
||||
template:
|
||||
src: "../templates/shell-handler.service.j2"
|
||||
dest: /etc/systemd/system/shell-handler.service
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Configure NGINX for zero-logging if enabled
|
||||
template:
|
||||
src: "../templates/nginx.conf.j2"
|
||||
dest: /etc/nginx/nginx.conf
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
when: zero_logs | bool
|
||||
|
||||
- name: Create payload directory
|
||||
file:
|
||||
path: /var/www/resources
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Include traffic flow configuration
|
||||
include_tasks: "../tasks/traffic_flow_config.yml"
|
||||
|
||||
# Run port randomization if enabled
|
||||
- name: Run port randomization if enabled
|
||||
include_tasks: port_randomization.yml
|
||||
when: randomize_ports | default(true) | bool
|
||||
|
||||
# Add just before configuring NGINX
|
||||
- name: Check if snakeoil certificates exist
|
||||
stat:
|
||||
path: /etc/ssl/certs/ssl-cert-snakeoil.pem
|
||||
register: snakeoil_cert
|
||||
|
||||
- name: Generate self-signed certificates if snakeoil not available
|
||||
block:
|
||||
- name: Create directory for self-signed certificates
|
||||
file:
|
||||
path: /etc/nginx/conf.d
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Generate self-signed certificate
|
||||
shell: |
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout /etc/nginx/conf.d/selfsigned.key \
|
||||
-out /etc/nginx/conf.d/selfsigned.crt \
|
||||
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
|
||||
args:
|
||||
creates: /etc/nginx/conf.d/selfsigned.crt
|
||||
when: not snakeoil_cert.stat.exists
|
||||
|
||||
# Configure nginx for dual HTTP/HTTPS with complete encryption
|
||||
- name: Configure NGINX for secure C2 redirection
|
||||
template:
|
||||
src: "../templates/redirector-site.conf.j2"
|
||||
dest: /etc/nginx/sites-available/default
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create legitimate-looking index.html
|
||||
template:
|
||||
src: "../templates/redirector-index.html.j2"
|
||||
dest: /var/www/html/index.html
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Create SSL certificate setup instructions
|
||||
template:
|
||||
src: "../templates/setup-cert.sh.j2"
|
||||
dest: /root/Tools/setup-cert.sh
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Configure NGINX stream module for TCP traffic
|
||||
template:
|
||||
src: "../templates/stream.conf.j2"
|
||||
dest: /etc/nginx/modules-enabled/stream.conf
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Create credential harvesting directory
|
||||
file:
|
||||
path: /var/www/login
|
||||
state: directory
|
||||
mode: '0755'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
# Create secure storage outside web root
|
||||
- name: Create secure credential storage
|
||||
file:
|
||||
path: /var/private/creds
|
||||
state: directory
|
||||
mode: '0700' # Only owner access
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Deploy credential harvesting page
|
||||
template:
|
||||
src: "../templates/fake-login.html.j2"
|
||||
dest: "/var/www/login/auth.html"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Deploy credential capture script
|
||||
template:
|
||||
src: "../templates/capture.php.j2"
|
||||
dest: "/var/www/login/process.php"
|
||||
mode: '0644'
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: Install PHP for credential processing
|
||||
apt:
|
||||
name: php-fpm
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: Start and enable shell handler service
|
||||
systemd:
|
||||
name: shell-handler
|
||||
state: started
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
|
||||
- name: Set up cron job for log cleaning if zero-logs enabled
|
||||
cron:
|
||||
name: "Clean logs"
|
||||
minute: "0"
|
||||
hour: "*/6"
|
||||
job: "/root/Tools/clean-logs.sh > /dev/null 2>&1"
|
||||
when: zero_logs | bool
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
# Linode/initial-infrastructure.yml
|
||||
# This playbook only creates the Linode instances without trying to configure them
|
||||
# This separation makes the deployment more reliable
|
||||
|
||||
- name: Create Linode infrastructure
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
connection: local
|
||||
vars_files:
|
||||
- vars.yaml
|
||||
vars:
|
||||
# Default values if not provided
|
||||
ssh_user: "{{ ssh_user | default('root') }}"
|
||||
linode_region: "{{ linode_region | default(region_choices | random) }}"
|
||||
plan: "{{ plan | default('g6-standard-2') }}"
|
||||
image: "{{ image | default('linode/kali') }}"
|
||||
|
||||
# Determine what to deploy based on configuration
|
||||
deploy_redirector: "{{ not (c2_only | default(false)) }}"
|
||||
deploy_c2: "{{ not (redirector_only | default(false)) }}"
|
||||
|
||||
# Generate random names if not provided
|
||||
redirector_name: "{{ redirector_name | default('srv-' + 100000000 | random | to_uuid | hash('md5') | truncate(8, True, '')) }}"
|
||||
c2_name: "{{ c2_name | default('node-' + 100000000 | random | to_uuid | hash('md5') | truncate(8, True, '')) }}"
|
||||
|
||||
tasks:
|
||||
- name: Validate required Linode token
|
||||
assert:
|
||||
that:
|
||||
- linode_token is defined and linode_token != ""
|
||||
fail_msg: "Linode API token is required. Set linode_token in vars.yaml or via --linode-token."
|
||||
|
||||
- name: Create redirector Linode instance
|
||||
community.general.linode_v4:
|
||||
access_token: "{{ linode_token }}"
|
||||
label: "{{ redirector_name }}"
|
||||
type: "{{ plan }}"
|
||||
region: "{{ linode_region }}"
|
||||
image: "{{ image }}"
|
||||
root_pass: "{{ lookup('password', '/dev/null length=24 chars=ascii_letters,digits') }}"
|
||||
authorized_keys:
|
||||
- "{{ lookup('file', ssh_key_path) }}"
|
||||
state: present
|
||||
register: redirector_instance
|
||||
when: deploy_redirector
|
||||
|
||||
- name: Set redirector_ip for later use
|
||||
set_fact:
|
||||
redirector_instance_id: "{{ redirector_instance.instance.id }}"
|
||||
redirector_ip: "{{ redirector_instance.instance.ipv4[0] }}"
|
||||
when: deploy_redirector and redirector_instance is defined
|
||||
|
||||
- name: Create C2 Linode instance
|
||||
community.general.linode_v4:
|
||||
access_token: "{{ linode_token }}"
|
||||
label: "{{ c2_name }}"
|
||||
type: "{{ plan }}"
|
||||
region: "{{ linode_region }}"
|
||||
image: "{{ image }}"
|
||||
root_pass: "{{ lookup('password', '/dev/null length=24 chars=ascii_letters,digits') }}"
|
||||
authorized_keys:
|
||||
- "{{ lookup('file', ssh_key_path) }}"
|
||||
state: present
|
||||
register: c2_instance
|
||||
when: deploy_c2
|
||||
|
||||
- name: Set c2_ip for later use
|
||||
set_fact:
|
||||
c2_instance_id: "{{ c2_instance.instance.id }}"
|
||||
c2_ip: "{{ c2_instance.instance.ipv4[0] }}"
|
||||
when: deploy_c2 and c2_instance is defined
|
||||
|
||||
- name: Display instance information
|
||||
debug:
|
||||
msg:
|
||||
- "Linode instances created successfully!"
|
||||
- "Waiting for instances to initialize..."
|
||||
- "{{ 'Redirector IP: ' + redirector_ip if redirector_ip is defined else 'No redirector deployed' }}"
|
||||
- "{{ 'C2 Server IP: ' + c2_ip if c2_ip is defined else 'No C2 server deployed' }}"
|
||||
|
||||
- name: Wait for instances to initialize (30 seconds)
|
||||
pause:
|
||||
seconds: 30
|
||||
when: (deploy_redirector and redirector_instance is defined) or (deploy_c2 and c2_instance is defined)
|
||||
@@ -1,179 +0,0 @@
|
||||
---
|
||||
# Common task for installing offensive security tools
|
||||
# Shared across all providers
|
||||
|
||||
- name: Force tools directory to root regardless of user
|
||||
set_fact:
|
||||
home_dir: "/root"
|
||||
tools_dir: "/root/Tools"
|
||||
when: provider == "aws"
|
||||
|
||||
- name: Determine home directory path
|
||||
set_fact:
|
||||
home_dir: "{{ (ansible_user == 'root') | ternary('/root', '/home/' + ansible_user) }}"
|
||||
tools_dir: "{{ (ansible_user == 'root') | ternary('/root/Tools', '/home/' + ansible_user + '/Tools') }}"
|
||||
|
||||
- name: Create Tools directory
|
||||
file:
|
||||
path: "{{ tools_dir }}"
|
||||
state: directory
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ ansible_user }}"
|
||||
mode: '0755'
|
||||
|
||||
- name: Install base dependencies
|
||||
apt:
|
||||
name:
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- pipx
|
||||
- curl
|
||||
- wget
|
||||
- git
|
||||
- jq
|
||||
- unzip
|
||||
- tmux
|
||||
state: present
|
||||
update_cache: yes
|
||||
|
||||
- name: Check if pipx is installed
|
||||
command: which pipx
|
||||
register: pipx_check
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: Configure pipx path
|
||||
shell: |
|
||||
export PATH="$PATH:{{ home_dir }}/.local/bin"
|
||||
pipx ensurepath
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: pipx_path_result
|
||||
until: pipx_path_result is success
|
||||
retries: 3
|
||||
delay: 5
|
||||
when: pipx_check.rc == 0
|
||||
|
||||
- name: Set PATH for subsequent operations
|
||||
set_fact:
|
||||
custom_path: "{{ home_dir }}/.local/bin:{{ ansible_env.PATH }}"
|
||||
|
||||
- name: Install tools via pipx
|
||||
shell: |
|
||||
export PATH="{{ custom_path }}"
|
||||
pipx install git+https://github.com/Pennyw0rth/NetExec
|
||||
pipx install git+https://github.com/blacklanternsecurity/TREVORspray
|
||||
pipx install impacket
|
||||
environment:
|
||||
PATH: "{{ custom_path }}"
|
||||
register: pipx_install_result
|
||||
until: pipx_install_result is success
|
||||
retries: 3
|
||||
delay: 5
|
||||
|
||||
- name: Install offensive security tools
|
||||
apt:
|
||||
name:
|
||||
- nmap
|
||||
- tcpdump
|
||||
- hydra
|
||||
- john
|
||||
- hashcat
|
||||
- sqlmap
|
||||
- gobuster
|
||||
- dirb
|
||||
- enum4linux
|
||||
- dnsenum
|
||||
- seclists
|
||||
- responder
|
||||
- golang
|
||||
- proxychains
|
||||
- tor
|
||||
- crackmapexec
|
||||
state: present
|
||||
|
||||
- name: Download Kerbrute
|
||||
shell: |
|
||||
mkdir -p {{ tools_dir }}/Kerbrute
|
||||
wget https://github.com/ropnop/kerbrute/releases/latest/download/kerbrute_linux_amd64 -O {{ tools_dir }}/Kerbrute/kerbrute
|
||||
chmod +x {{ tools_dir }}/Kerbrute/kerbrute
|
||||
args:
|
||||
executable: /bin/bash
|
||||
creates: "{{ tools_dir }}/Kerbrute/kerbrute"
|
||||
|
||||
- name: Clone SharpCollection nightly builds
|
||||
git:
|
||||
repo: https://github.com/Flangvik/SharpCollection.git
|
||||
dest: "{{ tools_dir }}/SharpCollection"
|
||||
version: master
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clone PEASS-ng
|
||||
git:
|
||||
repo: https://github.com/carlospolop/PEASS-ng.git
|
||||
dest: "{{ tools_dir }}/PEASS-ng"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clone MailSniper
|
||||
git:
|
||||
repo: https://github.com/dafthack/MailSniper.git
|
||||
dest: "{{ tools_dir }}/MailSniper"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clone Inveigh
|
||||
git:
|
||||
repo: https://github.com/Kevin-Robertson/Inveigh.git
|
||||
dest: "{{ tools_dir }}/Inveigh"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Install Metasploit Framework (Nightly Build)
|
||||
shell: |
|
||||
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > /tmp/msfinstall
|
||||
chmod 755 /tmp/msfinstall
|
||||
/tmp/msfinstall
|
||||
rm -f /tmp/msfinstall
|
||||
args:
|
||||
executable: /bin/bash
|
||||
creates: /usr/bin/msfconsole
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Ensure GoPhish directory exists
|
||||
file:
|
||||
path: "{{ tools_dir }}/gophish"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Grab GoPhish latest release
|
||||
shell: |
|
||||
curl -s https://api.github.com/repos/gophish/gophish/releases/latest | jq -r '.assets[] | select(.browser_download_url | contains("linux-64bit.zip")) | .browser_download_url'
|
||||
register: gophish_url
|
||||
failed_when: gophish_url.stdout == ""
|
||||
changed_when: false
|
||||
|
||||
- name: Download and install GoPhish
|
||||
shell: |
|
||||
curl -L "{{ gophish_url.stdout }}" -o {{ tools_dir }}/gophish.zip
|
||||
unzip {{ tools_dir }}/gophish.zip -d {{ tools_dir }}/gophish
|
||||
rm -f {{ tools_dir }}/gophish.zip
|
||||
chmod +x {{ tools_dir }}/gophish/gophish
|
||||
args:
|
||||
creates: "{{ tools_dir }}/gophish/gophish"
|
||||
|
||||
- name: Deploy Gophish config.json with custom admin port
|
||||
template:
|
||||
src: "../templates/gophish-config.j2"
|
||||
dest: "{{ tools_dir }}/gophish/config.json"
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ ansible_user }}"
|
||||
mode: '0644'
|
||||
vars:
|
||||
gophish_admin_port: "8090"
|
||||
domain: "{{ domain }}"
|
||||
|
||||
- name: Set proper ownership for Tools directory
|
||||
file:
|
||||
path: "{{ tools_dir }}"
|
||||
owner: "{{ ansible_user }}"
|
||||
group: "{{ ansible_user }}"
|
||||
recurse: true
|
||||
mode: '0755'
|
||||
@@ -1,92 +0,0 @@
|
||||
---
|
||||
# tasks/port_randomization.yml
|
||||
# Task file to randomize ports for C2 infrastructure with improved host-based service management
|
||||
|
||||
- name: Create port randomization script
|
||||
copy:
|
||||
src: "../files/randomize_ports.sh"
|
||||
dest: "/root/Tools/randomize_ports.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Execute port randomization script
|
||||
shell: |
|
||||
cd /root/Tools && ./randomize_ports.sh
|
||||
register: randomize_result
|
||||
when: randomize_ports | default(true) | bool
|
||||
|
||||
- name: Display port randomization results
|
||||
debug:
|
||||
msg: "{{ randomize_result.stdout_lines }}"
|
||||
when: randomize_ports | default(true) | bool
|
||||
|
||||
- name: Store randomized ports in variables
|
||||
shell: |
|
||||
PORT_CONFIG="/root/Tools/port_config.json"
|
||||
if [ -f "$PORT_CONFIG" ]; then
|
||||
cat "$PORT_CONFIG"
|
||||
else
|
||||
echo '{"error": "Port configuration not found"}'
|
||||
fi
|
||||
register: port_config_result
|
||||
when: randomize_ports | default(true) | bool
|
||||
|
||||
- name: Set port fact variables
|
||||
set_fact:
|
||||
randomized_http_port: "{{ (port_config_result.stdout | from_json).http_c2_port | default(8888) }}"
|
||||
randomized_https_port: "{{ (port_config_result.stdout | from_json).https_c2_port | default(443) }}"
|
||||
randomized_mtls_port: "{{ (port_config_result.stdout | from_json).mtls_c2_port | default(31337) }}"
|
||||
randomized_shell_handler_port: "{{ (port_config_result.stdout | from_json).shell_handler_port | default(shell_handler_port) }}"
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0
|
||||
|
||||
- name: Update shell handler configuration with randomized port
|
||||
replace:
|
||||
path: "/root/Tools/shell-handler/persistent-listener.sh"
|
||||
regexp: "LISTEN_PORT=.*"
|
||||
replace: "LISTEN_PORT={{ randomized_shell_handler_port | default(shell_handler_port) }}"
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0
|
||||
|
||||
- name: Update shell handler service with randomized port
|
||||
lineinfile:
|
||||
path: "/etc/systemd/system/shell-handler.service"
|
||||
regexp: 'Environment="LISTEN_PORT='
|
||||
line: 'Environment="LISTEN_PORT={{ randomized_shell_handler_port | default(shell_handler_port) }}"'
|
||||
insertafter: '^\\[Service\\]'
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0
|
||||
|
||||
# Improved service management - checks for service existence before restarting
|
||||
- name: Determine services to restart based on host type
|
||||
set_fact:
|
||||
services_to_restart: []
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0
|
||||
|
||||
- name: Check if Havoc service exists
|
||||
stat:
|
||||
path: "/etc/systemd/system/havoc.service"
|
||||
register: havoc_service_stat
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0
|
||||
|
||||
- name: Add Havoc to services list if it exists
|
||||
set_fact:
|
||||
services_to_restart: "{{ services_to_restart + ['havoc'] }}"
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0 and havoc_service_stat.stat.exists | default(false)
|
||||
|
||||
- name: Check if shell-handler service exists
|
||||
stat:
|
||||
path: "/etc/systemd/system/shell-handler.service"
|
||||
register: shell_handler_service_stat
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0
|
||||
|
||||
- name: Add shell-handler to services list if it exists
|
||||
set_fact:
|
||||
services_to_restart: "{{ services_to_restart + ['shell-handler'] }}"
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0 and shell_handler_service_stat.stat.exists | default(false)
|
||||
|
||||
- name: Reload and restart services
|
||||
systemd:
|
||||
daemon_reload: yes
|
||||
name: "{{ item }}"
|
||||
state: restarted
|
||||
with_items: "{{ services_to_restart }}"
|
||||
when: randomize_ports | default(true) | bool and port_config_result.rc == 0 and services_to_restart | length > 0
|
||||
@@ -1,402 +0,0 @@
|
||||
---
|
||||
# Security hardening tasks for C2 server - Fixed AWS collection issues
|
||||
|
||||
- name: Check if system is updated
|
||||
apt:
|
||||
update_cache: yes
|
||||
register: apt_update_result
|
||||
until: apt_update_result is success
|
||||
retries: 5
|
||||
delay: 5
|
||||
|
||||
- name: Install security packages (non-UFW)
|
||||
apt:
|
||||
name:
|
||||
- fail2ban
|
||||
- unattended-upgrades
|
||||
- debsums
|
||||
- aide
|
||||
- rkhunter
|
||||
- logrotate
|
||||
state: present
|
||||
register: package_install
|
||||
until: package_install is success
|
||||
retries: 3
|
||||
delay: 5
|
||||
|
||||
# Provider and role detection - DRY principle
|
||||
- name: Determine deployment configuration
|
||||
set_fact:
|
||||
is_aws_provider: "{{ provider | default('unknown') == 'aws' }}"
|
||||
is_c2_server: "{{ 'c2servers' in group_names }}"
|
||||
is_redirector: "{{ 'redirectors' in group_names }}"
|
||||
|
||||
# UFW Configuration Block - Non-AWS only
|
||||
- name: UFW detection and installation block
|
||||
block:
|
||||
- name: Check if UFW is installed
|
||||
command: which ufw
|
||||
register: ufw_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
|
||||
- name: Install UFW if not present (non-AWS)
|
||||
apt:
|
||||
name: ufw
|
||||
state: present
|
||||
update_cache: yes
|
||||
register: ufw_install
|
||||
until: ufw_install is success
|
||||
retries: 3
|
||||
delay: 5
|
||||
when: ufw_check.rc != 0
|
||||
when: not is_aws_provider
|
||||
|
||||
- name: Configure UFW for non-AWS deployments
|
||||
block:
|
||||
- name: Configure UFW default policies
|
||||
community.general.ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
direction: incoming
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Configure UFW for C2 server
|
||||
block:
|
||||
- name: Reset UFW to default deny
|
||||
community.general.ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
direction: incoming
|
||||
|
||||
- name: Allow SSH only from operator IP
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "22"
|
||||
src: "{{ operator_ip }}"
|
||||
proto: tcp
|
||||
|
||||
- name: Allow Havoc Teamserver only from operator IP
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "{{ havoc_teamserver_port | default('40056') }}"
|
||||
src: "{{ operator_ip }}"
|
||||
proto: tcp
|
||||
|
||||
- name: Allow traffic only from redirector
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "{{ item }}"
|
||||
src: "{{ redirector_ip }}"
|
||||
proto: tcp
|
||||
loop:
|
||||
- "80"
|
||||
- "443"
|
||||
- "{{ havoc_http_port | default('8080') }}"
|
||||
- "{{ havoc_https_port | default('9443') }}"
|
||||
- "{{ havoc_payload_port | default('8443') }}"
|
||||
- "{{ gophish_admin_port }}"
|
||||
- "{{ gophish_phish_port | default('8081') }}"
|
||||
- "{{ tracker_port | default('5000') }}"
|
||||
when: is_c2_server
|
||||
|
||||
- name: Configure UFW for redirector
|
||||
block:
|
||||
- name: Reset UFW to default deny
|
||||
community.general.ufw:
|
||||
state: enabled
|
||||
policy: deny
|
||||
direction: incoming
|
||||
|
||||
- name: Allow SSH only from operator IP
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "22"
|
||||
src: "{{ operator_ip }}"
|
||||
proto: tcp
|
||||
|
||||
- name: Allow public services from anywhere
|
||||
community.general.ufw:
|
||||
rule: allow
|
||||
port: "{{ item }}"
|
||||
proto: tcp
|
||||
loop:
|
||||
- "80"
|
||||
- "443"
|
||||
- "{{ shell_handler_port | default('4488') }}"
|
||||
when: is_redirector
|
||||
when: not is_aws_provider and (ufw_check.rc == 0 or ufw_install is success)
|
||||
|
||||
# Iptables fallback configuration - Non-AWS only
|
||||
- name: Configure basic iptables rules if UFW unavailable
|
||||
block:
|
||||
- name: Set up basic iptables rules for C2 server
|
||||
shell: |
|
||||
iptables -F
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
# Allow established connections
|
||||
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
# Allow loopback
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
# Allow SSH from operator
|
||||
iptables -A INPUT -p tcp --dport 22 -s {{ operator_ip }} -j ACCEPT
|
||||
# Allow Havoc teamserver from operator
|
||||
iptables -A INPUT -p tcp --dport {{ havoc_teamserver_port | default(40056) }} -s {{ operator_ip }} -j ACCEPT
|
||||
# Allow traffic from redirector
|
||||
iptables -A INPUT -p tcp --dport 80 -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 443 -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ havoc_http_port | default(8080) }} -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ havoc_https_port | default(9443) }} -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ havoc_payload_port | default(8443) }} -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ gophish_admin_port }} -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ gophish_phish_port | default(8081) }} -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ tracker_port | default(5000) }} -s {{ redirector_ip }} -j ACCEPT
|
||||
when: is_c2_server
|
||||
|
||||
- name: Set up basic iptables rules for redirector
|
||||
shell: |
|
||||
iptables -F
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
# Allow established connections
|
||||
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
# Allow loopback
|
||||
iptables -A INPUT -i lo -j ACCEPT
|
||||
# Allow SSH from operator
|
||||
iptables -A INPUT -p tcp --dport 22 -s {{ operator_ip }} -j ACCEPT
|
||||
# Allow public services
|
||||
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ shell_handler_port | default(4488) }} -j ACCEPT
|
||||
when: is_redirector
|
||||
|
||||
- name: Save iptables rules
|
||||
shell: |
|
||||
iptables-save > /etc/iptables/rules.v4
|
||||
ignore_errors: yes
|
||||
when: not is_aws_provider and (ufw_check.rc != 0 and (ufw_install is undefined or ufw_install is failed))
|
||||
|
||||
# SSH Hardening - Universal application
|
||||
- name: Harden SSH configuration
|
||||
lineinfile:
|
||||
path: /etc/ssh/sshd_config
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
state: present
|
||||
backup: yes
|
||||
loop:
|
||||
- { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
|
||||
- { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
|
||||
- { regexp: '^#?X11Forwarding', line: 'X11Forwarding no' }
|
||||
- { regexp: '^#?MaxAuthTries', line: 'MaxAuthTries 3' }
|
||||
- { regexp: '^#?AllowTcpForwarding', line: 'AllowTcpForwarding yes' }
|
||||
- { regexp: '^#?ClientAliveInterval', line: 'ClientAliveInterval 300' }
|
||||
- { regexp: '^#?ClientAliveCountMax', line: 'ClientAliveCountMax 2' }
|
||||
- { regexp: '^#?Protocol', line: 'Protocol 2' }
|
||||
- { regexp: '^#?MaxStartups', line: 'MaxStartups 10:30:100' }
|
||||
- { regexp: '^#?LoginGraceTime', line: 'LoginGraceTime 60' }
|
||||
register: ssh_config_updated
|
||||
|
||||
# System resource limits configuration
|
||||
- name: Configure system resource limits
|
||||
community.general.pam_limits:
|
||||
domain: "*"
|
||||
limit_type: "{{ item.limit_type }}"
|
||||
limit_item: "{{ item.limit_item }}"
|
||||
value: "{{ item.value }}"
|
||||
loop:
|
||||
- { limit_type: soft, limit_item: nofile, value: 65535 }
|
||||
- { limit_type: hard, limit_item: nofile, value: 65535 }
|
||||
- { limit_type: soft, limit_item: nproc, value: 4096 }
|
||||
- { limit_type: hard, limit_item: nproc, value: 4096 }
|
||||
|
||||
# Fail2ban configuration - Universal
|
||||
- name: Set up fail2ban SSH jail
|
||||
copy:
|
||||
dest: /etc/fail2ban/jail.d/sshd.conf
|
||||
content: |
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
filter = sshd
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 5
|
||||
bantime = 3600
|
||||
findtime = 600
|
||||
|
||||
[sshd-ddos]
|
||||
enabled = true
|
||||
port = ssh
|
||||
filter = sshd-ddos
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 2
|
||||
bantime = 7200
|
||||
mode: '0644'
|
||||
register: fail2ban_config_updated
|
||||
|
||||
# Automatic security updates
|
||||
- name: Enable automatic security updates
|
||||
copy:
|
||||
dest: /etc/apt/apt.conf.d/20auto-upgrades
|
||||
content: |
|
||||
APT::Periodic::Update-Package-Lists "1";
|
||||
APT::Periodic::Unattended-Upgrade "1";
|
||||
APT::Periodic::AutocleanInterval "7";
|
||||
APT::Periodic::Download-Upgradeable-Packages "1";
|
||||
mode: '0644'
|
||||
|
||||
# Log cleaning functionality
|
||||
- name: Create Tools directory if it doesn't exist
|
||||
file:
|
||||
path: /root/Tools
|
||||
state: directory
|
||||
mode: '0700'
|
||||
when: zero_logs | default(false) | bool
|
||||
|
||||
- name: Create log cleaning script if zero-logs is enabled
|
||||
copy:
|
||||
dest: /root/Tools/clean-logs.sh
|
||||
content: |
|
||||
#!/bin/bash
|
||||
# C2ingRed Log cleaning script for operational security
|
||||
echo "Starting log cleaning at $(date)" >> /tmp/clean-logs.log
|
||||
|
||||
# Clear authentication logs
|
||||
echo "" > /var/log/auth.log
|
||||
echo "" > /var/log/auth.log.1
|
||||
|
||||
# Clear system logs
|
||||
echo "" > /var/log/syslog
|
||||
echo "" > /var/log/syslog.1
|
||||
|
||||
# Clear kernel logs
|
||||
echo "" > /var/log/kern.log
|
||||
echo "" > /var/log/kern.log.1
|
||||
|
||||
# Clear application specific logs
|
||||
find /var/log -type f -name "*.log" -exec truncate -s 0 {} \;
|
||||
find /var/log -type f -name "*.log.*" -exec truncate -s 0 {} \;
|
||||
|
||||
# Clear journal logs
|
||||
journalctl --vacuum-time=1s 2>/dev/null || true
|
||||
|
||||
# Clear bash history for all users
|
||||
for user_home in /home/*; do
|
||||
if [ -d "$user_home" ]; then
|
||||
echo "" > "$user_home/.bash_history" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
|
||||
# Clear root bash history
|
||||
echo "" > /root/.bash_history 2>/dev/null || true
|
||||
history -c 2>/dev/null || true
|
||||
|
||||
# Clear tmp files
|
||||
find /tmp -type f -mtime +1 -delete 2>/dev/null || true
|
||||
|
||||
echo "Log cleaning completed at $(date)" >> /tmp/clean-logs.log
|
||||
mode: '0700'
|
||||
when: zero_logs | default(false) | bool
|
||||
|
||||
- name: Create cron job for log cleaning if enabled
|
||||
cron:
|
||||
name: "Clean operational logs"
|
||||
minute: "0"
|
||||
hour: "*/6"
|
||||
job: "/root/Tools/clean-logs.sh"
|
||||
user: root
|
||||
when: zero_logs | default(false) | bool
|
||||
|
||||
# Service restart handlers
|
||||
- name: Restart SSH service if configuration changed
|
||||
service:
|
||||
name: ssh
|
||||
state: restarted
|
||||
when: ssh_config_updated.changed
|
||||
|
||||
- name: Check if fail2ban service exists
|
||||
stat:
|
||||
path: "/etc/init.d/fail2ban"
|
||||
register: fail2ban_service_stat
|
||||
|
||||
- name: Restart fail2ban service if installed and configuration changed
|
||||
service:
|
||||
name: fail2ban
|
||||
state: restarted
|
||||
enabled: yes
|
||||
when: fail2ban_service_stat.stat.exists and fail2ban_config_updated.changed
|
||||
|
||||
# AWS-specific security updates - NO MODULES REQUIRED
|
||||
- name: Check if we're running on AWS provider
|
||||
set_fact:
|
||||
is_aws_provider: "{{ hostvars['localhost']['provider'] | default('') == 'aws' }}"
|
||||
|
||||
- name: AWS-specific security updates
|
||||
block:
|
||||
- name: Get redirector security group information
|
||||
block:
|
||||
- name: Check if infrastructure state file exists
|
||||
stat:
|
||||
path: "{{ playbook_dir }}/infrastructure_state_{{ hostvars['localhost']['deployment_id'] }}.json"
|
||||
register: redirector_state_file
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Load redirector state if available
|
||||
include_vars:
|
||||
file: "{{ playbook_dir }}/infrastructure_state_{{ hostvars['localhost']['deployment_id'] }}.json"
|
||||
name: redirector_state
|
||||
when: redirector_state_file.stat.exists
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Update redirector security group via raw AWS CLI
|
||||
delegate_to: localhost
|
||||
shell: |
|
||||
export AWS_ACCESS_KEY_ID="{{ hostvars['localhost']['aws_access_key'] }}"
|
||||
export AWS_SECRET_ACCESS_KEY="{{ hostvars['localhost']['aws_secret_key'] }}"
|
||||
export AWS_DEFAULT_REGION="{{ redirector_state.region | default(aws_region) }}"
|
||||
|
||||
# Install AWS CLI if not present
|
||||
if ! command -v aws &> /dev/null; then
|
||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
|
||||
unzip -q awscliv2.zip
|
||||
sudo ./aws/install --update
|
||||
rm -rf aws awscliv2.zip
|
||||
fi
|
||||
|
||||
# Add security group rule (ignore if exists)
|
||||
aws ec2 authorize-security-group-ingress \
|
||||
--group-id {{ redirector_state.security_group_id }} \
|
||||
--protocol tcp \
|
||||
--port 22 \
|
||||
--cidr {{ ansible_host }}/32 \
|
||||
2>/dev/null || echo "Rule already exists or added successfully"
|
||||
when: redirector_state is defined and redirector_state.security_group_id is defined
|
||||
register: sg_update_result
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Display security group update result
|
||||
debug:
|
||||
msg: |
|
||||
AWS Security Group Update: {{ 'SUCCESS' if sg_update_result.rc == 0 else 'COMPLETED' }}
|
||||
C2 Server IP: {{ ansible_host }}
|
||||
Security Group ID: {{ redirector_state.security_group_id | default('NOT FOUND') }}
|
||||
|
||||
when: is_aws_provider | bool
|
||||
|
||||
# Final security status report
|
||||
- name: Generate security hardening report
|
||||
debug:
|
||||
msg: |
|
||||
C2ingRed Security Hardening Complete:
|
||||
=====================================
|
||||
Provider: {{ provider | default('unknown') }}
|
||||
Server Type: {{ 'C2 Server' if is_c2_server else 'Redirector' if is_redirector else 'Unknown' }}
|
||||
SSH Hardened: {{ 'YES' if ssh_config_updated.changed else 'ALREADY CONFIGURED' }}
|
||||
Fail2ban Configured: {{ 'YES' if fail2ban_config_updated.changed else 'ALREADY CONFIGURED' }}
|
||||
Firewall: {{ 'AWS Security Groups' if is_aws_provider else 'UFW/iptables' }}
|
||||
Log Cleaning: {{ 'ENABLED' if zero_logs | default(false) | bool else 'DISABLED' }}
|
||||
Auto Updates: ENABLED
|
||||
System Limits: CONFIGURED
|
||||
@@ -1,183 +0,0 @@
|
||||
---
|
||||
# Configure security groups and firewall rules for phishing infrastructure
|
||||
|
||||
- name: Configure MTA Front security
|
||||
block:
|
||||
- name: Create MTA Front security group
|
||||
amazon.aws.ec2_security_group:
|
||||
name: "mta-front-{{ deployment_id }}"
|
||||
description: "Security group for MTA Front server"
|
||||
vpc_id: "{{ vpc_id }}"
|
||||
region: "{{ aws_region }}"
|
||||
rules:
|
||||
# Management access
|
||||
- proto: tcp
|
||||
ports: 22
|
||||
cidr_ip: "{{ operator_ip }}/32"
|
||||
rule_desc: "SSH from operator"
|
||||
|
||||
# SMTP services - public facing
|
||||
- proto: tcp
|
||||
ports: 25
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
rule_desc: "SMTP from anywhere"
|
||||
|
||||
- proto: tcp
|
||||
ports: 587
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
rule_desc: "SMTP submission"
|
||||
|
||||
- proto: tcp
|
||||
ports: 465
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
rule_desc: "SMTPS"
|
||||
|
||||
rules_egress:
|
||||
- proto: -1
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
state: present
|
||||
when: deployment_components.mta_front | default(false) | bool
|
||||
|
||||
- name: Configure Gophish security (hidden backend)
|
||||
block:
|
||||
- name: Create Gophish security group
|
||||
amazon.aws.ec2_security_group:
|
||||
name: "gophish-{{ deployment_id }}"
|
||||
description: "Security group for Gophish server (hidden)"
|
||||
vpc_id: "{{ vpc_id }}"
|
||||
region: "{{ aws_region }}"
|
||||
rules:
|
||||
# Management access only
|
||||
- proto: tcp
|
||||
ports: 22
|
||||
cidr_ip: "{{ operator_ip }}/32"
|
||||
rule_desc: "SSH from operator"
|
||||
|
||||
- proto: tcp
|
||||
ports: 3333
|
||||
cidr_ip: "{{ operator_ip }}/32"
|
||||
rule_desc: "Gophish admin interface"
|
||||
|
||||
# Internal communication only
|
||||
- proto: tcp
|
||||
ports: 80
|
||||
cidr_ip: "{{ phishing_redirector_ip }}/32"
|
||||
rule_desc: "HTTP from phishing redirector"
|
||||
|
||||
- proto: tcp
|
||||
ports: 25
|
||||
cidr_ip: "{{ mta_front_ip }}/32"
|
||||
rule_desc: "SMTP from MTA front"
|
||||
|
||||
rules_egress:
|
||||
- proto: -1
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
state: present
|
||||
when: deployment_components.gophish | default(false) | bool
|
||||
|
||||
- name: Configure Phishing Redirector security (public facing)
|
||||
block:
|
||||
- name: Create Phishing Redirector security group
|
||||
amazon.aws.ec2_security_group:
|
||||
name: "phish-redirector-{{ deployment_id }}"
|
||||
description: "Security group for Phishing Redirector"
|
||||
vpc_id: "{{ vpc_id }}"
|
||||
region: "{{ aws_region }}"
|
||||
rules:
|
||||
# Management access
|
||||
- proto: tcp
|
||||
ports: 22
|
||||
cidr_ip: "{{ operator_ip }}/32"
|
||||
rule_desc: "SSH from operator"
|
||||
|
||||
# Public web access
|
||||
- proto: tcp
|
||||
ports: 80
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
rule_desc: "HTTP from anywhere"
|
||||
|
||||
- proto: tcp
|
||||
ports: 443
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
rule_desc: "HTTPS from anywhere"
|
||||
|
||||
rules_egress:
|
||||
- proto: -1
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
state: present
|
||||
when: deployment_components.phishing_redirector | default(false) | bool
|
||||
|
||||
- name: Configure Phishing Web Server security (hidden backend)
|
||||
block:
|
||||
- name: Create Phishing Web Server security group
|
||||
amazon.aws.ec2_security_group:
|
||||
name: "phish-webserver-{{ deployment_id }}"
|
||||
description: "Security group for Phishing Web Server (hidden)"
|
||||
vpc_id: "{{ vpc_id }}"
|
||||
region: "{{ aws_region }}"
|
||||
rules:
|
||||
# Management access only
|
||||
- proto: tcp
|
||||
ports: 22
|
||||
cidr_ip: "{{ operator_ip }}/32"
|
||||
rule_desc: "SSH from operator"
|
||||
|
||||
# Internal communication only
|
||||
- proto: tcp
|
||||
ports: 80
|
||||
cidr_ip: "{{ phishing_redirector_ip }}/32"
|
||||
rule_desc: "HTTP from phishing redirector"
|
||||
|
||||
- proto: tcp
|
||||
ports: 443
|
||||
cidr_ip: "{{ phishing_redirector_ip }}/32"
|
||||
rule_desc: "HTTPS from phishing redirector"
|
||||
|
||||
rules_egress:
|
||||
- proto: -1
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
state: present
|
||||
when: deployment_components.phishing_webserver | default(false) | bool
|
||||
|
||||
- name: Configure Payload Server security (hidden backend)
|
||||
block:
|
||||
- name: Create Payload Server security group
|
||||
amazon.aws.ec2_security_group:
|
||||
name: "payload-server-{{ deployment_id }}"
|
||||
description: "Security group for Payload Server (hidden)"
|
||||
vpc_id: "{{ vpc_id }}"
|
||||
region: "{{ aws_region }}"
|
||||
rules:
|
||||
# Management access only
|
||||
- proto: tcp
|
||||
ports: 22
|
||||
cidr_ip: "{{ operator_ip }}/32"
|
||||
rule_desc: "SSH from operator"
|
||||
|
||||
# Internal communication only
|
||||
- proto: tcp
|
||||
ports: 80
|
||||
cidr_ip: "{{ payload_redirector_ip }}/32"
|
||||
rule_desc: "HTTP from payload redirector"
|
||||
|
||||
- proto: tcp
|
||||
ports: 443
|
||||
cidr_ip: "{{ payload_redirector_ip }}/32"
|
||||
rule_desc: "HTTPS from payload redirector"
|
||||
|
||||
rules_egress:
|
||||
- proto: -1
|
||||
cidr_ip: "0.0.0.0/0"
|
||||
state: present
|
||||
when: deployment_components.payload_server | default(false) | bool
|
||||
|
||||
- name: Display security configuration summary
|
||||
debug:
|
||||
msg:
|
||||
- "Phishing Infrastructure Security Configuration"
|
||||
- "============================================="
|
||||
- "✓ Least privilege access implemented"
|
||||
- "✓ Backend servers hidden from public access"
|
||||
- "✓ Only redirectors/MTA fronts are publicly accessible"
|
||||
- "✓ Operator-only SSH access configured"
|
||||
- "✓ Internal communication secured"
|
||||
@@ -1,223 +0,0 @@
|
||||
---
|
||||
# Common task for configuring proper traffic flow between infrastructure components
|
||||
|
||||
- name: Determine server role in infrastructure
|
||||
set_fact:
|
||||
server_role: >-
|
||||
{% if inventory_hostname in groups['c2servers'] | default([]) %}c2{%
|
||||
elif inventory_hostname in groups['redirectors'] | default([]) %}redirector{%
|
||||
elif inventory_hostname in groups['logservers'] | default([]) %}logserver{%
|
||||
elif inventory_hostname in groups['payloadservers'] | default([]) %}payloadserver{%
|
||||
elif inventory_hostname in groups['phishingservers'] | default([]) %}phishingserver{%
|
||||
elif inventory_hostname in groups['sharedrives'] | default([]) %}sharedrive{%
|
||||
else %}unknown{% endif %}
|
||||
|
||||
# Determine if we're using AWS provider
|
||||
- name: Determine if using AWS provider
|
||||
set_fact:
|
||||
is_aws_provider: "{{ provider | default('unknown') == 'aws' }}"
|
||||
|
||||
# Skip firewall configuration for AWS instances
|
||||
- name: Skip firewall configuration for AWS instances
|
||||
debug:
|
||||
msg: "Skipping host-based firewall configuration for AWS instance. Security Groups are handling this at the infrastructure level."
|
||||
when: is_aws_provider
|
||||
|
||||
# Check if UFW is installed or can be installed
|
||||
- name: Check if UFW is installed
|
||||
command: which ufw
|
||||
register: ufw_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: not is_aws_provider
|
||||
|
||||
# Try to install UFW if not found and we're not on AWS
|
||||
- name: Install UFW if not present
|
||||
apt:
|
||||
name: ufw
|
||||
state: present
|
||||
update_cache: yes
|
||||
register: ufw_install
|
||||
until: ufw_install is success or ufw_install is failed
|
||||
retries: 3
|
||||
delay: 5
|
||||
ignore_errors: yes
|
||||
when: not is_aws_provider and ufw_check.rc != 0
|
||||
|
||||
# Set a fact to track if UFW is available
|
||||
- name: Determine if UFW is available
|
||||
set_fact:
|
||||
ufw_available: "{{ (ufw_check.rc == 0) or (ufw_install is defined and ufw_install is success) }}"
|
||||
when: not is_aws_provider
|
||||
|
||||
# UFW Configuration Block (non-AWS only)
|
||||
- name: Configure C2 server routing with UFW
|
||||
block:
|
||||
- name: Allow SSH only from operator IP
|
||||
ufw:
|
||||
rule: allow
|
||||
port: 22
|
||||
src: "{{ operator_ip }}"
|
||||
proto: tcp
|
||||
|
||||
- name: Allow teamserver access only from operator IP
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ havoc_teamserver_port | default('40056') }}"
|
||||
src: "{{ operator_ip }}"
|
||||
proto: tcp
|
||||
|
||||
- name: Configure required flows for each connected component
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ item.port }}"
|
||||
src: "{{ item.ip }}"
|
||||
proto: tcp
|
||||
loop:
|
||||
- { ip: "{{ redirector_ip }}", port: "80" }
|
||||
- { ip: "{{ redirector_ip }}", port: "443" }
|
||||
- { ip: "{{ redirector_ip }}", port: "{{ havoc_http_port | default('8080') }}" }
|
||||
- { ip: "{{ redirector_ip }}", port: "{{ havoc_https_port | default('9443') }}" }
|
||||
- { ip: "{{ logserver_ip | default(omit) }}", port: "5144" }
|
||||
- { ip: "{{ payloadserver_ip | default(omit) }}", port: "8888" }
|
||||
when: item.ip != omit
|
||||
when:
|
||||
- server_role == 'c2'
|
||||
- not is_aws_provider
|
||||
- ufw_available | default(false) | bool
|
||||
|
||||
# Fallback to iptables if UFW is not available
|
||||
- name: Configure C2 server routing with iptables (fallback)
|
||||
block:
|
||||
- name: Set up basic iptables rules for C2 server
|
||||
shell: |
|
||||
iptables -F
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
# Allow established connections
|
||||
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
# Allow SSH from operator
|
||||
iptables -A INPUT -p tcp --dport 22 -s {{ operator_ip }} -j ACCEPT
|
||||
# Allow Havoc teamserver from operator
|
||||
iptables -A INPUT -p tcp --dport {{ havoc_teamserver_port | default(40056) }} -s {{ operator_ip }} -j ACCEPT
|
||||
# Allow traffic from redirector
|
||||
iptables -A INPUT -p tcp --dport 80 -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 443 -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ havoc_http_port | default(8080) }} -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ havoc_https_port | default(9443) }} -s {{ redirector_ip }} -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport {{ gophish_admin_port }} -s {{ redirector_ip }} -j ACCEPT
|
||||
when: redirector_ip is defined
|
||||
when:
|
||||
- server_role == 'c2'
|
||||
- not is_aws_provider
|
||||
- not (ufw_available | default(false) | bool)
|
||||
|
||||
# Configure redirector routing with UFW when available
|
||||
- name: Configure redirector routing with UFW
|
||||
block:
|
||||
- name: Allow SSH only from operator IP
|
||||
ufw:
|
||||
rule: allow
|
||||
port: 22
|
||||
src: "{{ operator_ip }}"
|
||||
proto: tcp
|
||||
|
||||
- name: Allow public web access
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ item }}"
|
||||
proto: tcp
|
||||
loop:
|
||||
- 80
|
||||
- 443
|
||||
|
||||
- name: Allow shell handler access
|
||||
ufw:
|
||||
rule: allow
|
||||
port: "{{ shell_handler_port | default('4444') }}"
|
||||
proto: tcp
|
||||
when:
|
||||
- server_role == 'redirector'
|
||||
- not is_aws_provider
|
||||
- ufw_available | default(false) | bool
|
||||
|
||||
# Fallback to iptables for redirector if UFW is not available
|
||||
- name: Configure redirector routing with iptables (fallback)
|
||||
block:
|
||||
- name: Set up basic iptables rules for redirector
|
||||
shell: |
|
||||
iptables -F
|
||||
iptables -P INPUT DROP
|
||||
iptables -P FORWARD DROP
|
||||
iptables -P OUTPUT ACCEPT
|
||||
# Allow established connections
|
||||
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||
# Allow SSH from operator
|
||||
iptables -A INPUT -p tcp --dport 22 -s {{ operator_ip }} -j ACCEPT
|
||||
# Allow web traffic from anywhere
|
||||
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
|
||||
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
|
||||
# Allow shell handler port
|
||||
iptables -A INPUT -p tcp --dport {{ shell_handler_port | default('4444') }} -j ACCEPT
|
||||
when:
|
||||
- server_role == 'redirector'
|
||||
- not is_aws_provider
|
||||
- not (ufw_available | default(false) | bool)
|
||||
|
||||
# The rest of your tasks remain unchanged...
|
||||
- name: Configure logging server routing
|
||||
block:
|
||||
- name: Allow SSH only from operator IP
|
||||
ufw:
|
||||
rule: allow
|
||||
port: 22
|
||||
src: "{{ operator_ip }}"
|
||||
proto: tcp
|
||||
|
||||
- name: Allow log ingestion from infrastructure
|
||||
ufw:
|
||||
rule: allow
|
||||
port: 5144 # Logstash port
|
||||
src: "{{ item }}"
|
||||
proto: tcp
|
||||
loop:
|
||||
- "{{ c2_ip }}"
|
||||
- "{{ redirector_ip }}"
|
||||
- "{{ payloadserver_ip | default(omit) }}"
|
||||
- "{{ phishingserver_ip | default(omit) }}"
|
||||
when: item != omit
|
||||
when:
|
||||
- server_role == 'logserver'
|
||||
- not is_aws_provider
|
||||
- ufw_available | default(false) | bool
|
||||
|
||||
- name: Update security group to allow SSH from C2 to redirector
|
||||
block:
|
||||
- name: Allow SSH from C2 to redirector (AWS)
|
||||
amazon.aws.ec2_security_group:
|
||||
name: "{{ redirector_name }}-sg"
|
||||
description: "Security group for redirector {{ redirector_name }}"
|
||||
vpc_id: "{{ vpc_id }}"
|
||||
region: "{{ aws_redirector_region }}"
|
||||
rules:
|
||||
- proto: tcp
|
||||
ports: 22
|
||||
cidr_ip: "{{ c2_ip }}/32"
|
||||
state: present
|
||||
when: provider == "aws"
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Allow SSH from C2 to redirector (UFW)
|
||||
ufw:
|
||||
rule: allow
|
||||
port: 22
|
||||
src: "{{ c2_ip }}"
|
||||
proto: tcp
|
||||
when: provider != "aws" and not is_aws_provider and ufw_available | default(false) | bool
|
||||
|
||||
- name: Allow SSH from C2 to redirector (iptables fallback)
|
||||
shell: |
|
||||
iptables -A INPUT -p tcp --dport 22 -s {{ c2_ip }} -j ACCEPT
|
||||
when: provider != "aws" and not is_aws_provider and not (ufw_available | default(false) | bool)
|
||||
when: server_role == 'redirector' and c2_ip is defined and redirector_ip is defined
|
||||
Reference in New Issue
Block a user