"""
AUTARCH Simulate Module
Attack simulation and security testing
Red team exercises and controlled attack simulations.
"""
import os
import sys
import subprocess
import socket
import hashlib
import random
import string
import time
import ftplib
import base64
import urllib.request
from pathlib import Path
from datetime import datetime
# Module metadata
DESCRIPTION = "Attack simulation & red team tools"
AUTHOR = "darkHal"
VERSION = "1.0"
CATEGORY = "simulate"
sys.path.insert(0, str(Path(__file__).parent.parent))
from core.banner import Colors, clear_screen, display_banner
class Simulator:
"""Attack simulation tools."""
def __init__(self):
pass
def print_status(self, message: str, status: str = "info"):
colors = {"info": Colors.CYAN, "success": Colors.GREEN, "warning": Colors.YELLOW, "error": Colors.RED}
symbols = {"info": "*", "success": "+", "warning": "!", "error": "X"}
print(f"{colors.get(status, Colors.WHITE)}[{symbols.get(status, '*')}] {message}{Colors.RESET}")
def run_cmd(self, cmd: str, timeout: int = 60) -> tuple:
try:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return result.returncode == 0, result.stdout.strip()
except:
return False, ""
def password_audit(self):
"""Audit password strength and check common passwords."""
print(f"\n{Colors.BOLD}Password Audit{Colors.RESET}")
print(f"{Colors.DIM}Test password strength against common patterns{Colors.RESET}\n")
password = input(f"{Colors.WHITE}Enter password to test: {Colors.RESET}")
if not password:
return
print(f"\n{Colors.CYAN}Analyzing password...{Colors.RESET}\n")
score = 0
feedback = []
# Length check
if len(password) >= 16:
score += 3
feedback.append(f"{Colors.GREEN}+ Excellent length (16+){Colors.RESET}")
elif len(password) >= 12:
score += 2
feedback.append(f"{Colors.GREEN}+ Good length (12+){Colors.RESET}")
elif len(password) >= 8:
score += 1
feedback.append(f"{Colors.YELLOW}~ Minimum length (8+){Colors.RESET}")
else:
feedback.append(f"{Colors.RED}- Too short (<8){Colors.RESET}")
# Character diversity
has_upper = any(c.isupper() for c in password)
has_lower = any(c.islower() for c in password)
has_digit = any(c.isdigit() for c in password)
has_special = any(c in '!@#$%^&*()_+-=[]{}|;:,.<>?' for c in password)
if has_upper:
score += 1
feedback.append(f"{Colors.GREEN}+ Contains uppercase{Colors.RESET}")
else:
feedback.append(f"{Colors.RED}- No uppercase letters{Colors.RESET}")
if has_lower:
score += 1
feedback.append(f"{Colors.GREEN}+ Contains lowercase{Colors.RESET}")
else:
feedback.append(f"{Colors.RED}- No lowercase letters{Colors.RESET}")
if has_digit:
score += 1
feedback.append(f"{Colors.GREEN}+ Contains numbers{Colors.RESET}")
else:
feedback.append(f"{Colors.RED}- No numbers{Colors.RESET}")
if has_special:
score += 2
feedback.append(f"{Colors.GREEN}+ Contains special characters{Colors.RESET}")
else:
feedback.append(f"{Colors.YELLOW}~ No special characters{Colors.RESET}")
# Common patterns
common_patterns = ['password', '123456', 'qwerty', 'letmein', 'admin', 'welcome', 'monkey', 'dragon']
if password.lower() in common_patterns:
score = 0
feedback.append(f"{Colors.RED}- Extremely common password!{Colors.RESET}")
# Sequential characters
if any(password[i:i+3].lower() in 'abcdefghijklmnopqrstuvwxyz' for i in range(len(password)-2)):
score -= 1
feedback.append(f"{Colors.YELLOW}~ Contains sequential letters{Colors.RESET}")
if any(password[i:i+3] in '0123456789' for i in range(len(password)-2)):
score -= 1
feedback.append(f"{Colors.YELLOW}~ Contains sequential numbers{Colors.RESET}")
# Keyboard patterns
keyboard_patterns = ['qwerty', 'asdf', 'zxcv', '1qaz', '2wsx']
for pattern in keyboard_patterns:
if pattern in password.lower():
score -= 1
feedback.append(f"{Colors.YELLOW}~ Contains keyboard pattern{Colors.RESET}")
break
# Display results
for line in feedback:
print(f" {line}")
print(f"\n{Colors.BOLD}Score: {max(0, score)}/10{Colors.RESET}")
if score >= 8:
print(f"{Colors.GREEN}Strength: STRONG{Colors.RESET}")
elif score >= 5:
print(f"{Colors.YELLOW}Strength: MODERATE{Colors.RESET}")
else:
print(f"{Colors.RED}Strength: WEAK{Colors.RESET}")
# Hash generation
print(f"\n{Colors.CYAN}Password Hashes:{Colors.RESET}")
print(f" MD5: {hashlib.md5(password.encode()).hexdigest()}")
print(f" SHA1: {hashlib.sha1(password.encode()).hexdigest()}")
print(f" SHA256: {hashlib.sha256(password.encode()).hexdigest()}")
def port_scanner(self):
"""TCP port scanner."""
print(f"\n{Colors.BOLD}Port Scanner{Colors.RESET}")
target = input(f"{Colors.WHITE}Enter target IP/hostname: {Colors.RESET}").strip()
if not target:
return
port_range = input(f"{Colors.WHITE}Port range (e.g., 1-1000) [1-1024]: {Colors.RESET}").strip() or "1-1024"
try:
start_port, end_port = map(int, port_range.split('-'))
except:
self.print_status("Invalid port range", "error")
return
# Resolve hostname
try:
ip = socket.gethostbyname(target)
if ip != target:
print(f"\n{Colors.DIM}Resolved {target} to {ip}{Colors.RESET}")
except:
self.print_status(f"Could not resolve {target}", "error")
return
print(f"\n{Colors.CYAN}Scanning {target} ports {start_port}-{end_port}...{Colors.RESET}\n")
open_ports = []
scanned = 0
total = end_port - start_port + 1
for port in range(start_port, end_port + 1):
scanned += 1
if scanned % 100 == 0:
print(f"\r{Colors.DIM}Progress: {scanned}/{total} ports scanned...{Colors.RESET}", end="")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.5)
result = sock.connect_ex((ip, port))
if result == 0:
open_ports.append(port)
sock.close()
print(f"\r{' ' * 50}\r", end="") # Clear progress line
if open_ports:
print(f"{Colors.GREEN}Open ports found:{Colors.RESET}\n")
services = {
21: "ftp", 22: "ssh", 23: "telnet", 25: "smtp", 53: "dns",
80: "http", 110: "pop3", 143: "imap", 443: "https", 445: "smb",
3306: "mysql", 3389: "rdp", 5432: "postgresql", 8080: "http-proxy"
}
for port in open_ports:
service = services.get(port, "unknown")
print(f" {port:5}/tcp open {service}")
else:
print(f"{Colors.YELLOW}No open ports found in range{Colors.RESET}")
print(f"\n{Colors.DIM}Scanned {total} ports{Colors.RESET}")
def banner_grabber(self):
"""Grab service banners."""
print(f"\n{Colors.BOLD}Banner Grabber{Colors.RESET}")
target = input(f"{Colors.WHITE}Enter target IP/hostname: {Colors.RESET}").strip()
port = input(f"{Colors.WHITE}Enter port [80]: {Colors.RESET}").strip() or "80"
if not target:
return
try:
port = int(port)
except:
self.print_status("Invalid port", "error")
return
print(f"\n{Colors.CYAN}Grabbing banner from {target}:{port}...{Colors.RESET}\n")
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
sock.connect((target, port))
# Send HTTP request for web ports
if port in [80, 443, 8080, 8443]:
sock.send(b"HEAD / HTTP/1.1\r\nHost: " + target.encode() + b"\r\n\r\n")
else:
sock.send(b"\r\n")
banner = sock.recv(1024).decode('utf-8', errors='ignore')
sock.close()
if banner:
print(f"{Colors.GREEN}Banner:{Colors.RESET}")
for line in banner.split('\n')[:15]:
print(f" {line.strip()}")
else:
print(f"{Colors.YELLOW}No banner received{Colors.RESET}")
except socket.timeout:
self.print_status("Connection timed out", "warning")
except ConnectionRefusedError:
self.print_status("Connection refused", "error")
except Exception as e:
self.print_status(f"Error: {e}", "error")
def payload_generator(self):
"""Generate various payloads for testing."""
print(f"\n{Colors.BOLD}Payload Generator{Colors.RESET}")
print(f"{Colors.DIM}Generate test payloads for security testing{Colors.RESET}\n")
print(f" {Colors.YELLOW}[1]{Colors.RESET} XSS Payloads")
print(f" {Colors.YELLOW}[2]{Colors.RESET} SQL Injection Payloads")
print(f" {Colors.YELLOW}[3]{Colors.RESET} Command Injection Payloads")
print(f" {Colors.YELLOW}[4]{Colors.RESET} Path Traversal Payloads")
print(f" {Colors.YELLOW}[5]{Colors.RESET} SSTI Payloads")
print()
choice = input(f"{Colors.WHITE}Select payload type: {Colors.RESET}").strip()
payloads = {
"1": [ # XSS
'',
'
',
'