fixed havoc config template
This commit is contained in:
@@ -173,6 +173,12 @@ def interactive_setup(deployment_id=None):
|
|||||||
# Ask if user wants to use cross-provider deployment
|
# Ask if user wants to use cross-provider deployment
|
||||||
cross_provider = input("\nDo you want to deploy redirector and C2 on different providers? (y/n) [default: n]: ").lower() == 'y'
|
cross_provider = input("\nDo you want to deploy redirector and C2 on different providers? (y/n) [default: n]: ").lower() == 'y'
|
||||||
|
|
||||||
|
# If not cross-provider, ask if they want multi-region deployment upfront
|
||||||
|
use_multi_region = False
|
||||||
|
if not cross_provider:
|
||||||
|
use_multi_region = input("\nDo you want to deploy redirector and C2 in different regions? (y/n) [default: n]: ").lower() == 'y'
|
||||||
|
config['use_multi_region'] = use_multi_region
|
||||||
|
|
||||||
if cross_provider:
|
if cross_provider:
|
||||||
print("\nSelect redirector provider:")
|
print("\nSelect redirector provider:")
|
||||||
for i, provider in enumerate(PROVIDERS, 1):
|
for i, provider in enumerate(PROVIDERS, 1):
|
||||||
@@ -249,34 +255,34 @@ def interactive_setup(deployment_id=None):
|
|||||||
for i, region in enumerate(aws_regions, 1):
|
for i, region in enumerate(aws_regions, 1):
|
||||||
print(f" {i}. {region}")
|
print(f" {i}. {region}")
|
||||||
|
|
||||||
# Select region for redirector if this is the redirector provider
|
# Handle region selection based on deployment type
|
||||||
if provider == config.get('redirector_provider', config['provider']):
|
if cross_provider or use_multi_region:
|
||||||
region_input = input("\nSelect region for redirector (number or leave blank for random): ")
|
# Select specific regions for redirector/C2 if this provider is used for them
|
||||||
if region_input:
|
if provider == config.get('redirector_provider', config['provider']):
|
||||||
try:
|
region_input = input("\nSelect region for redirector (number or leave blank for random): ")
|
||||||
region_choice = int(region_input)
|
if region_input:
|
||||||
if 1 <= region_choice <= len(aws_regions):
|
try:
|
||||||
config['redirector_region'] = aws_regions[region_choice - 1]
|
region_choice = int(region_input)
|
||||||
else:
|
if 1 <= region_choice <= len(aws_regions):
|
||||||
print(f"Invalid choice, using random region")
|
config['redirector_region'] = aws_regions[region_choice - 1]
|
||||||
except ValueError:
|
else:
|
||||||
print("Invalid input, using random region")
|
print(f"Invalid choice, using random region")
|
||||||
|
except ValueError:
|
||||||
|
print("Invalid input, using random region")
|
||||||
|
|
||||||
# Select region for C2 if this is the C2 provider
|
if provider == config.get('c2_provider', config['provider']):
|
||||||
if provider == config.get('c2_provider', config['provider']):
|
region_input = input("\nSelect region for C2 (number or leave blank for random): ")
|
||||||
region_input = input("\nSelect region for C2 (number or leave blank for random): ")
|
if region_input:
|
||||||
if region_input:
|
try:
|
||||||
try:
|
region_choice = int(region_input)
|
||||||
region_choice = int(region_input)
|
if 1 <= region_choice <= len(aws_regions):
|
||||||
if 1 <= region_choice <= len(aws_regions):
|
config['c2_region'] = aws_regions[region_choice - 1]
|
||||||
config['c2_region'] = aws_regions[region_choice - 1]
|
else:
|
||||||
else:
|
print(f"Invalid choice, using random region")
|
||||||
print(f"Invalid choice, using random region")
|
except ValueError:
|
||||||
except ValueError:
|
print("Invalid input, using random region")
|
||||||
print("Invalid input, using random region")
|
else:
|
||||||
|
# Single region for both if not using multi-region
|
||||||
# If not cross-provider and no specific regions selected, use general region
|
|
||||||
if not cross_provider and not (config.get('redirector_region') or config.get('c2_region')):
|
|
||||||
region_input = input("\nSelect region (number or leave blank for random): ")
|
region_input = input("\nSelect region (number or leave blank for random): ")
|
||||||
if region_input:
|
if region_input:
|
||||||
try:
|
try:
|
||||||
@@ -301,34 +307,34 @@ def interactive_setup(deployment_id=None):
|
|||||||
for i, region in enumerate(linode_regions, 1):
|
for i, region in enumerate(linode_regions, 1):
|
||||||
print(f" {i}. {region}")
|
print(f" {i}. {region}")
|
||||||
|
|
||||||
# Select region for redirector if this is the redirector provider
|
# Handle region selection based on deployment type
|
||||||
if provider == config.get('redirector_provider', config['provider']):
|
if cross_provider or use_multi_region:
|
||||||
region_input = input("\nSelect region for redirector (number or leave blank for random): ")
|
# Select specific regions for redirector/C2 if this provider is used for them
|
||||||
if region_input:
|
if provider == config.get('redirector_provider', config['provider']):
|
||||||
try:
|
region_input = input("\nSelect region for redirector (number or leave blank for random): ")
|
||||||
region_choice = int(region_input)
|
if region_input:
|
||||||
if 1 <= region_choice <= len(linode_regions):
|
try:
|
||||||
config['redirector_region'] = linode_regions[region_choice - 1]
|
region_choice = int(region_input)
|
||||||
else:
|
if 1 <= region_choice <= len(linode_regions):
|
||||||
print(f"Invalid choice, using random region")
|
config['redirector_region'] = linode_regions[region_choice - 1]
|
||||||
except ValueError:
|
else:
|
||||||
print("Invalid input, using random region")
|
print(f"Invalid choice, using random region")
|
||||||
|
except ValueError:
|
||||||
|
print("Invalid input, using random region")
|
||||||
|
|
||||||
# Select region for C2 if this is the C2 provider
|
if provider == config.get('c2_provider', config['provider']):
|
||||||
if provider == config.get('c2_provider', config['provider']):
|
region_input = input("\nSelect region for C2 (number or leave blank for random): ")
|
||||||
region_input = input("\nSelect region for C2 (number or leave blank for random): ")
|
if region_input:
|
||||||
if region_input:
|
try:
|
||||||
try:
|
region_choice = int(region_input)
|
||||||
region_choice = int(region_input)
|
if 1 <= region_choice <= len(linode_regions):
|
||||||
if 1 <= region_choice <= len(linode_regions):
|
config['c2_region'] = linode_regions[region_choice - 1]
|
||||||
config['c2_region'] = linode_regions[region_choice - 1]
|
else:
|
||||||
else:
|
print(f"Invalid choice, using random region")
|
||||||
print(f"Invalid choice, using random region")
|
except ValueError:
|
||||||
except ValueError:
|
print("Invalid input, using random region")
|
||||||
print("Invalid input, using random region")
|
else:
|
||||||
|
# Single region for both if not using multi-region
|
||||||
# If not cross-provider and no specific regions selected, use general region
|
|
||||||
if not cross_provider and not (config.get('redirector_region') or config.get('c2_region')):
|
|
||||||
region_input = input("\nSelect region (number or leave blank for random): ")
|
region_input = input("\nSelect region (number or leave blank for random): ")
|
||||||
if region_input:
|
if region_input:
|
||||||
try:
|
try:
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
+20
-137
@@ -1,12 +1,10 @@
|
|||||||
{% set random_hex = lookup('password', '/dev/null chars=hex_lower length=8') %}
|
|
||||||
|
|
||||||
Teamserver {
|
Teamserver {
|
||||||
Host = "0.0.0.0"
|
Host = "0.0.0.0"
|
||||||
Port = {{ havoc_teamserver_port | default(40056) }}
|
Port = {{ havoc_teamserver_port | default(40056) }}
|
||||||
|
|
||||||
Build {
|
Build {
|
||||||
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
|
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
|
||||||
Compiler86 = "/usr/bin/i686-w64-mingw32-gcc"
|
Compiler86 = "/usr/bin/x86_64-w64-mingw32-gcc"
|
||||||
Nasm = "/usr/bin/nasm"
|
Nasm = "/usr/bin/nasm"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,147 +17,53 @@ Operators {
|
|||||||
{% for operator in havoc_operators %}
|
{% for operator in havoc_operators %}
|
||||||
user "{{ operator.name }}" {
|
user "{{ operator.name }}" {
|
||||||
Password = "{{ operator.password }}"
|
Password = "{{ operator.password }}"
|
||||||
# Secret is not in documentation, removed or comment it out
|
|
||||||
# Secret = "{{ operator.secret | default(lookup('password', '/dev/null chars=hex_lower length=32')) }}"
|
|
||||||
}
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
|
|
||||||
Listeners {
|
Listeners {
|
||||||
Http {
|
|
||||||
Name = "http"
|
|
||||||
KillDate = "{{ havoc_killdate | default('2030-01-01') }}"
|
|
||||||
WorkingHours = "{{ havoc_working_hours | default('0:00-23:59') }}"
|
|
||||||
{% if havoc_hosts is defined %}
|
|
||||||
Hosts = [
|
|
||||||
{% for host in havoc_hosts %}
|
|
||||||
"{{ host }}"{% if not loop.last %},{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
]
|
|
||||||
{% else %}
|
|
||||||
Hosts = ["0.0.0.0"]
|
|
||||||
{% endif %}
|
|
||||||
HostBind = "0.0.0.0"
|
|
||||||
HostRotation = "{{ havoc_host_rotation | default('round-robin') }}"
|
|
||||||
PortBind = {{ havoc_http_port | default(8080) }}
|
|
||||||
{% if havoc_portconn is defined %}
|
|
||||||
PortConn = {{ havoc_portconn }}
|
|
||||||
{% endif %}
|
|
||||||
{% if havoc_user_agent is defined %}
|
|
||||||
UserAgent = "{{ havoc_user_agent }}"
|
|
||||||
{% else %}
|
|
||||||
UserAgent = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:{{ random_hex[1] | int + 90 }}.0) Gecko/20100101 Firefox/{{ random_hex[2] | int + 95 }}.0"
|
|
||||||
{% endif %}
|
|
||||||
Headers = [
|
|
||||||
{% if havoc_http_headers is defined %}
|
|
||||||
{% for header in havoc_http_headers %}
|
|
||||||
"{{ header }}"{% if not loop.last %},{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
"Accept: */*",
|
|
||||||
"Accept-Language: en-US,en;q=0.9",
|
|
||||||
"X-Requested-With: XMLHttpRequest"
|
|
||||||
{% endif %}
|
|
||||||
]
|
|
||||||
Uris = [
|
|
||||||
{% if havoc_http_uris is defined %}
|
|
||||||
{% for uri in havoc_http_uris %}
|
|
||||||
"{{ uri }}"{% if not loop.last %},{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
"/api/v{{ random_hex[6] | int + 1 }}",
|
|
||||||
"/dashboard",
|
|
||||||
"/content/{{ random_hex[1:4] }}",
|
|
||||||
"/wp-includes/{{ random_hex[1:6] }}.js"
|
|
||||||
{% endif %}
|
|
||||||
]
|
|
||||||
Secure = false
|
|
||||||
{% if havoc_proxy_enabled | default(false) %}
|
|
||||||
Proxy {
|
|
||||||
Host = "{{ havoc_proxy_host }}"
|
|
||||||
Port = {{ havoc_proxy_port }}
|
|
||||||
Username = "{{ havoc_proxy_username | default('') }}"
|
|
||||||
Password = "{{ havoc_proxy_password | default('') }}"
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
}
|
|
||||||
|
|
||||||
Http {
|
Http {
|
||||||
Name = "https"
|
Name = "https"
|
||||||
KillDate = "{{ havoc_killdate | default('2030-01-01') }}"
|
KillDate = "{{ havoc_killdate | default('2030-01-01') }}"
|
||||||
WorkingHours = "{{ havoc_working_hours | default('0:00-23:59') }}"
|
WorkingHours = "{{ havoc_working_hours | default('0:00-23:59') }}"
|
||||||
{% if havoc_hosts is defined %}
|
|
||||||
Hosts = [
|
Hosts = [
|
||||||
{% for host in havoc_hosts %}
|
"{{ redirector_subdomain }}.{{ domain }}"
|
||||||
"{{ host }}"{% if not loop.last %},{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
]
|
]
|
||||||
{% else %}
|
|
||||||
Hosts = ["0.0.0.0"]
|
|
||||||
{% endif %}
|
|
||||||
HostBind = "0.0.0.0"
|
HostBind = "0.0.0.0"
|
||||||
HostRotation = "{{ havoc_host_rotation | default('round-robin') }}"
|
HostRotation = "round-robin"
|
||||||
PortBind = {{ havoc_https_port | default(443) }}
|
PortBind = {{ havoc_https_port | default(443) }}
|
||||||
{% if havoc_user_agent is defined %}
|
PortConn = {{ havoc_https_port | default(443) }}
|
||||||
UserAgent = "{{ havoc_user_agent }}"
|
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
|
||||||
{% else %}
|
|
||||||
UserAgent = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:{{ random_hex[1] | int + 90 }}.0) Gecko/20100101 Firefox/{{ random_hex[2] | int + 95 }}.0"
|
|
||||||
{% endif %}
|
|
||||||
Headers = [
|
Headers = [
|
||||||
{% if havoc_https_headers is defined %}
|
|
||||||
{% for header in havoc_https_headers %}
|
|
||||||
"{{ header }}"{% if not loop.last %},{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
"Accept: */*",
|
"Accept: */*",
|
||||||
"Accept-Language: en-US,en;q=0.9",
|
"Accept-Language: en-US,en;q=0.9"
|
||||||
"X-Requested-With: XMLHttpRequest"
|
|
||||||
{% endif %}
|
|
||||||
]
|
]
|
||||||
Uris = [
|
Uris = [
|
||||||
{% if havoc_https_uris is defined %}
|
"/api/v2",
|
||||||
{% for uri in havoc_https_uris %}
|
|
||||||
"{{ uri }}"{% if not loop.last %},{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% else %}
|
|
||||||
"/api/v{{ random_hex[6] | int + 2 }}",
|
|
||||||
"/content",
|
"/content",
|
||||||
"/static/{{ random_hex[2:5] }}",
|
"/static/css",
|
||||||
"/wp-content/plugins/{{ random_hex[1:6] }}"
|
"/wp-content/plugins"
|
||||||
{% endif %}
|
|
||||||
]
|
]
|
||||||
|
Response {
|
||||||
|
Headers = [
|
||||||
|
"Content-Type: application/json",
|
||||||
|
"Cache-Control: no-store, private",
|
||||||
|
"X-Content-Type-Options: nosniff"
|
||||||
|
]
|
||||||
|
}
|
||||||
Secure = true
|
Secure = true
|
||||||
|
|
||||||
Cert {
|
Cert {
|
||||||
Cert = "{{ havoc_cert_path | default('/root/Tools/Havoc/data/certs/havoc.crt') }}"
|
Cert = "/etc/letsencrypt/live/{{ domain }}/fullchain.pem"
|
||||||
Key = "{{ havoc_key_path | default('/root/Tools/Havoc/data/certs/havoc.key') }}"
|
Key = "/etc/letsencrypt/live/{{ domain }}/privkey.pem"
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if havoc_proxy_enabled | default(false) %}
|
|
||||||
Proxy {
|
|
||||||
Host = "{{ havoc_proxy_host }}"
|
|
||||||
Port = {{ havoc_proxy_port }}
|
|
||||||
Username = "{{ havoc_proxy_username | default('') }}"
|
|
||||||
Password = "{{ havoc_proxy_password | default('') }}"
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if havoc_smb_enabled | default(false) %}
|
|
||||||
Smb {
|
|
||||||
Name = "smb"
|
|
||||||
PipeName = "{{ havoc_smb_pipename | default('havoc-' ~ random_hex[0:6]) }}"
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Demon {
|
Demon {
|
||||||
Sleep = {{ havoc_sleep | default(random_hex[0:2] | int % 5 + 2) }}
|
Sleep = {{ havoc_sleep | default(5) }}
|
||||||
Jitter = {{ havoc_jitter | default(random_hex[2:4] | int % 30 + 20) }}
|
Jitter = {{ havoc_jitter | default(30) }}
|
||||||
{% if havoc_trust_x_forwarded_for is defined %}
|
|
||||||
TrustXForwardedFor = {{ havoc_trust_x_forwarded_for | lower }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
Injection {
|
Injection {
|
||||||
{% if havoc_spawn64 is defined %}
|
{% if havoc_spawn64 is defined %}
|
||||||
@@ -175,24 +79,3 @@ Demon {
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if havoc_service_enabled | default(false) %}
|
|
||||||
Service {
|
|
||||||
Endpoint = "{{ havoc_service_endpoint | default('/api/service') }}"
|
|
||||||
Password = "{{ havoc_service_password | default(lookup('password', '/dev/null chars=ascii_letters,digits length=32')) }}"
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if havoc_webhook_discord_enabled | default(false) %}
|
|
||||||
Webhook {
|
|
||||||
Discord {
|
|
||||||
Url = "{{ havoc_webhook_discord_url }}"
|
|
||||||
{% if havoc_webhook_discord_avatar_url is defined %}
|
|
||||||
AvatarUrl = "{{ havoc_webhook_discord_avatar_url }}"
|
|
||||||
{% endif %}
|
|
||||||
{% if havoc_webhook_discord_user is defined %}
|
|
||||||
User = "{{ havoc_webhook_discord_user }}"
|
|
||||||
{% endif %}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
Reference in New Issue
Block a user