Files
CoM-c2itall/modules/c2/deploy_c2.py
T
Operator 98103466d8 Initial public portfolio release
Sanitized version of red team infrastructure automation platform.
Operational content (implant pipelines, lures, credential capture)
replaced with documented stubs. Architecture and infrastructure
automation code intact.
2026-06-23 16:12:14 -04:00

317 lines
11 KiB
Python

#!/usr/bin/env python3
"""
C2 infrastructure deployment module
"""
import os
import sys
import logging
# Add the project root to the path so we can import utils
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
from utils.common import (
COLORS, clear_screen, print_banner, generate_deployment_id,
setup_logging, get_public_ip, confirm_action, wait_for_input,
archive_old_logs
)
from utils.provider_utils import select_provider, gather_provider_config
from utils.ssh_utils import generate_ssh_key
from utils.naming_utils import get_deployment_name_with_options
def gather_c2_parameters():
"""Collect parameters specific to C2 deployments"""
clear_screen()
print_banner()
print(f"{COLORS['WHITE']}C2 INFRASTRUCTURE SETUP{COLORS['RESET']}")
print(f"{COLORS['WHITE']}========================{COLORS['RESET']}")
config = {}
# Generate deployment ID
config['deployment_id'] = generate_deployment_id()
print(f"Deployment ID: {COLORS['CYAN']}{config['deployment_id']}{COLORS['RESET']}")
# Provider selection
provider = select_provider()
if not provider:
return None
config['provider'] = provider
# Get provider-specific configuration
provider_config = gather_provider_config(provider)
if not provider_config:
return None
config.update(provider_config)
# C2-specific configuration
print(f"\n{COLORS['BLUE']}C2 Configuration{COLORS['RESET']}")
# Domain configuration
domain = input(f"Domain for C2 infrastructure [required]: ")
if not domain:
print(f"{COLORS['RED']}A domain is required for C2 deployments{COLORS['RESET']}")
return None
config['domain'] = domain
# Subdomain configuration
config['c2_subdomain'] = input("C2 server subdomain [default: mail]: ") or "mail"
# Instance naming options
config['redirector_name'] = get_deployment_name_with_options(
deployment_type='redirector',
deployment_id=config['deployment_id'],
prefix='r-'
)
config['c2_name'] = get_deployment_name_with_options(
deployment_type='c2',
deployment_id=config['deployment_id'],
prefix='s-'
)
# C2 Framework selection
print(f"\n{COLORS['BLUE']}C2 Framework Selection:{COLORS['RESET']}")
print(f"1) Havoc")
print(f"2) Cobalt Strike")
print(f"3) Sliver")
print(f"4) Mythic")
print(f"5) Custom")
framework_choice = input("Select C2 framework [default: 1]: ") or "1"
frameworks = {
"1": "havoc",
"2": "cobaltstrike",
"3": "sliver",
"4": "mythic",
"5": "custom"
}
config['c2_framework'] = frameworks.get(framework_choice, "havoc")
# Email for Let's Encrypt
default_email = f"admin@{config['domain']}"
config['letsencrypt_email'] = input(f"Email for Let's Encrypt [default: {default_email}]: ") or default_email
# Get operator IP for security
suggested_ip = get_public_ip()
if suggested_ip:
operator_ip = input(f"Your public IP for secure access [detected: {suggested_ip}]: ") or suggested_ip
else:
operator_ip = input("Your public IP for secure access: ")
config['operator_ip'] = operator_ip
# SSH key generation
ssh_key_path = generate_ssh_key(config['deployment_id'])
if not ssh_key_path:
print(f"{COLORS['RED']}Failed to generate SSH key{COLORS['RESET']}")
return None
config['ssh_key_path'] = f"{ssh_key_path}.pub"
# SMTP Configuration for email services
print(f"\n{COLORS['BLUE']}SMTP Configuration{COLORS['RESET']}")
config['smtp_auth_user'] = input("SMTP authentication username [default: admin]: ") or "admin"
import secrets
import string
def generate_random_password(length=16):
alphabet = string.ascii_letters + string.digits + "!@#$%^&*"
password = ''.join(secrets.choice(alphabet) for _ in range(length))
return password
default_password = generate_random_password()
smtp_password = input(f"SMTP authentication password [default: random generated]: ")
config['smtp_auth_pass'] = smtp_password if smtp_password else default_password
print(f"{COLORS['GREEN']}SMTP Credentials:{COLORS['RESET']}")
print(f" Username: {config['smtp_auth_user']}")
print(f" Password: {config['smtp_auth_pass']}")
print(f"{COLORS['YELLOW']}Note: These credentials will be saved in the deployment info file{COLORS['RESET']}")
# Security Configuration
print(f"\n{COLORS['BLUE']}Security Configuration{COLORS['RESET']}")
zero_logs_choice = input("Enable zero-logs configuration? (y/n) [default: y]: ").lower()
config['zero_logs'] = zero_logs_choice != 'n' # Default to True unless explicitly 'n'
# Post-deployment options
config['ssh_after_deploy'] = confirm_action("SSH into instance after deployment?", default=True)
return config
def c2_menu():
"""Display the C2 submenu and handle user selection"""
while True:
clear_screen()
print_banner()
print(f"{COLORS['WHITE']}C2 INFRASTRUCTURE MENU{COLORS['RESET']}")
print(f"{COLORS['WHITE']}======================={COLORS['RESET']}")
print(f"1) C2 Server Only {COLORS['GREEN']}*QUICK*{COLORS['RESET']} {COLORS['GRAY']}(Basic setup){COLORS['RESET']}")
print(f"2) Havoc C2 Server {COLORS['GRAY']}(Modern C2 framework){COLORS['RESET']}")
print(f"3) Sliver Server {COLORS['GRAY']}(Go-based C2){COLORS['RESET']}")
print(f"4) Cobalt Strike Server {COLORS['GRAY']}(Commercial C2){COLORS['RESET']}")
print(f"5) Mythic Server {COLORS['GRAY']}(Cross-platform C2){COLORS['RESET']}")
print(f"6) C2 + Redirector {COLORS['GRAY']}(C2 with traffic redirection){COLORS['RESET']}")
print(f"7) Full C2 Infrastructure {COLORS['GRAY']}(Complete multi-tier setup){COLORS['RESET']}")
print(f"99) Return to Main Menu")
choice = input(f"\nSelect an option: ")
if choice == "1":
deploy_c2_only()
elif choice == "2":
deploy_havoc_c2()
elif choice == "3":
deploy_sliver_c2()
elif choice == "4":
deploy_cobaltstrike_c2()
elif choice == "5":
deploy_mythic_c2()
elif choice == "6":
deploy_c2_with_redirector()
elif choice == "7":
deploy_full_c2()
elif choice == "99":
return
else:
print(f"\n{COLORS['RED']}Invalid option. Please try again.{COLORS['RESET']}")
wait_for_input()
def deploy_c2_only():
"""Deploy C2 server only"""
config = gather_c2_parameters()
if not config:
return
config['deployment_type'] = 'c2_only'
config['c2_only'] = True
print(f"\n{COLORS['GREEN']}Deploying C2 server only...{COLORS['RESET']}")
execute_c2_deployment(config)
def deploy_c2_with_redirector():
"""Deploy C2 server with redirector"""
config = gather_c2_parameters()
if not config:
return
# Additional redirector configuration
config['redirector_subdomain'] = input("Redirector subdomain [default: cdn]: ") or "cdn"
config['deployment_type'] = 'c2_with_redirector'
config['deploy_redirector'] = True
print(f"\n{COLORS['GREEN']}Deploying C2 server with redirector...{COLORS['RESET']}")
execute_c2_deployment(config)
def deploy_full_c2():
"""Deploy full C2 infrastructure"""
config = gather_c2_parameters()
if not config:
return
# Additional configuration for full deployment
config['redirector_subdomain'] = input("Redirector subdomain [default: cdn]: ") or "cdn"
config['deployment_type'] = 'full_c2'
config['deploy_redirector'] = True
config['deploy_tracker'] = confirm_action("Deploy email tracker?", default=False)
print(f"\n{COLORS['GREEN']}Deploying full C2 infrastructure...{COLORS['RESET']}")
execute_c2_deployment(config)
def deploy_havoc_c2():
"""Deploy Havoc C2 server specifically"""
config = gather_c2_parameters()
if not config:
return
config['c2_framework'] = 'havoc'
config['deployment_type'] = 'havoc_c2'
print(f"\n{COLORS['GREEN']}Deploying Havoc C2 server...{COLORS['RESET']}")
execute_c2_deployment(config)
def deploy_cobaltstrike_c2():
"""Deploy Cobalt Strike server specifically"""
config = gather_c2_parameters()
if not config:
return
config['c2_framework'] = 'cobaltstrike'
config['deployment_type'] = 'cobaltstrike_c2'
# Cobalt Strike specific configuration
license_path = input("Path to Cobalt Strike license file [optional]: ")
if license_path:
config['cobaltstrike_license'] = license_path
print(f"\n{COLORS['GREEN']}Deploying Cobalt Strike server...{COLORS['RESET']}")
execute_c2_deployment(config)
def deploy_sliver_c2():
"""Deploy Sliver C2 server specifically"""
config = gather_c2_parameters()
if not config:
return
config['c2_framework'] = 'sliver'
config['deployment_type'] = 'sliver_c2'
print(f"\n{COLORS['GREEN']}Deploying Sliver C2 server...{COLORS['RESET']}")
execute_c2_deployment(config)
def deploy_mythic_c2():
"""Deploy Mythic C2 server specifically"""
config = gather_c2_parameters()
if not config:
return
config['c2_framework'] = 'mythic'
config['deployment_type'] = 'mythic_c2'
print(f"\n{COLORS['GREEN']}Deploying Mythic C2 server...{COLORS['RESET']}")
execute_c2_deployment(config)
def execute_c2_deployment(config):
"""Execute C2 infrastructure deployment"""
clear_screen()
print_banner()
print(f"\n{COLORS['GREEN']}Starting C2 deployment...{COLORS['RESET']}")
# Archive old logs before starting new deployment
print(f"Archiving old logs...")
archive_old_logs(max_logs_to_keep=5) # Keep last 5 deployments
# Set up logging
log_file = setup_logging(config['deployment_id'], "c2_deployment")
# Display configuration summary
print(f"\n{COLORS['CYAN']}Deployment Summary:{COLORS['RESET']}")
print(f"Deployment Type: {config['deployment_type']}")
print(f"Deployment ID: {config['deployment_id']}")
print(f"Provider: {config['provider']}")
print(f"Domain: {config['domain']}")
print(f"C2 Framework: {config['c2_framework']}")
# Confirm deployment
if not confirm_action(f"\n{COLORS['YELLOW']}Proceed with C2 deployment?{COLORS['RESET']}", default=False):
print(f"\n{COLORS['YELLOW']}Deployment cancelled.{COLORS['RESET']}")
return
# Execute the actual deployment using the deployment engine
from utils.deployment_engine import deploy_infrastructure
success = deploy_infrastructure(config)
if success:
print(f"\n{COLORS['GREEN']}C2 infrastructure deployed successfully!{COLORS['RESET']}")
if config.get('ssh_after_deploy'):
from utils.ssh_utils import ssh_to_instance
ssh_to_instance(config)
else:
print(f"\n{COLORS['RED']}C2 infrastructure deployment failed.{COLORS['RESET']}")
wait_for_input()
if __name__ == "__main__":
c2_menu()