diff --git a/services/sheesh/Dockerfile b/services/sheesh/Dockerfile new file mode 100644 index 0000000..073dd6a --- /dev/null +++ b/services/sheesh/Dockerfile @@ -0,0 +1,32 @@ +FROM python:3.12-slim + +ARG PASSWORD=root +ENV DEBIAN_FRONTEND=noninteractive +ENV HOME=/home/ctf +WORKDIR /home/ctf/chall + +RUN apt-get update && apt-get install -y --no-install-recommends \ + openssh-server \ + build-essential \ + libffi-dev \ + libssl-dev \ + python3-dev \ + bash \ + && rm -rf /var/lib/apt/lists/* + +RUN useradd -m -d /home/ctf -s /bin/bash ctf && \ + echo "ctf:${PASSWORD}" | chpasswd + +RUN mkdir -p /var/run/sshd + +COPY requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir -r /tmp/requirements.txt + +COPY ./src /home/ctf/chall/src +COPY ./start.sh /start.sh +RUN chmod +x /start.sh /home/ctf/chall/src/run.sh + +RUN chown -R root:root /home/ctf/chall && chmod -R 555 /home/ctf/chall + +EXPOSE 8000 22 +CMD ["/start.sh"] diff --git a/services/sheesh/chall.py b/services/sheesh/chall.py new file mode 100644 index 0000000..cdaf6a2 --- /dev/null +++ b/services/sheesh/chall.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +import os +import binascii +import hashlib +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad, unpad + +seed_bits = 23 +seed_max = 1 << seed_bits +seed_len = (seed_bits + 7) // 8 +key = os.urandom(16) + +def hash(seed_int: int) -> bytes: + sb = seed_int.to_bytes(seed_len, "big") + return hashlib.sha256(sb).digest()[:16] + +seed = int.from_bytes(os.urandom(4), "big") % seed_max +seed2 = int.from_bytes(os.urandom(4), "big") % seed_max +K1 = hash(seed) +K2 = hash(seed2) + +with open("/flag.txt","rb") as f: + FLAG = f.read() + +def read(prompt: str): + s = input(prompt).strip() + try: + return binascii.unhexlify(s) + except Exception: + print("hmm") + return None + +def enc_cfb(pt: bytes) -> bytes: + iv = os.urandom(16) + aes = AES.new(key, AES.MODE_CFB, iv=iv, segment_size=128) + pt2 = pt + FLAG[:len(FLAG)//2] + ct = aes.encrypt(pt2) + return iv + ct + +def enc_cbc(data: bytes, iv1: bytes, iv2: bytes, padd: bool) -> bytes: + x = pad(data, 16) if padd else data + c1 = AES.new(K1, AES.MODE_CBC, iv=iv1).encrypt(x) + c2 = AES.new(K2, AES.MODE_CBC, iv=iv2).encrypt(c1) + return c2 + +def menu(): + print(""" +1. encrypt +2. profit +3. get third +4. exit + """) + +third = 0 +while True: + menu() + op = input("> ").strip() + + if op == "1": + data = read("pt: ") + if data is None: + print() + continue + out = enc_cfb(data) + print("ct: ", out.hex()) + print() + + elif op == "2": + iv1 = os.urandom(16) + iv2 = os.urandom(16) + ct = enc_cbc(FLAG, iv1, iv2, padd=True) + print("iv1: ", iv1.hex()) + print("iv2: ", iv2.hex()) + print("ct: ", ct.hex()) + print() + + elif op == "3": + if third: + print("sheesh") + continue + block = read("pt: ") + if block is None: + print() + continue + if len(block) != 16: + print("hmmm\n") + continue + iv1 = os.urandom(16) + iv2 = os.urandom(16) + ct = enc_cbc(block, iv1, iv2, padd=0) + print("iv1: ", iv1.hex()) + print("iv2: ", iv2.hex()) + print("ct: ", ct.hex()) + third = 1 + print() + + elif op == "4": + break + else: + print("mabokkkk?") diff --git a/services/sheesh/dist/chall.py b/services/sheesh/dist/chall.py new file mode 100644 index 0000000..cdaf6a2 --- /dev/null +++ b/services/sheesh/dist/chall.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +import os +import binascii +import hashlib +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad, unpad + +seed_bits = 23 +seed_max = 1 << seed_bits +seed_len = (seed_bits + 7) // 8 +key = os.urandom(16) + +def hash(seed_int: int) -> bytes: + sb = seed_int.to_bytes(seed_len, "big") + return hashlib.sha256(sb).digest()[:16] + +seed = int.from_bytes(os.urandom(4), "big") % seed_max +seed2 = int.from_bytes(os.urandom(4), "big") % seed_max +K1 = hash(seed) +K2 = hash(seed2) + +with open("/flag.txt","rb") as f: + FLAG = f.read() + +def read(prompt: str): + s = input(prompt).strip() + try: + return binascii.unhexlify(s) + except Exception: + print("hmm") + return None + +def enc_cfb(pt: bytes) -> bytes: + iv = os.urandom(16) + aes = AES.new(key, AES.MODE_CFB, iv=iv, segment_size=128) + pt2 = pt + FLAG[:len(FLAG)//2] + ct = aes.encrypt(pt2) + return iv + ct + +def enc_cbc(data: bytes, iv1: bytes, iv2: bytes, padd: bool) -> bytes: + x = pad(data, 16) if padd else data + c1 = AES.new(K1, AES.MODE_CBC, iv=iv1).encrypt(x) + c2 = AES.new(K2, AES.MODE_CBC, iv=iv2).encrypt(c1) + return c2 + +def menu(): + print(""" +1. encrypt +2. profit +3. get third +4. exit + """) + +third = 0 +while True: + menu() + op = input("> ").strip() + + if op == "1": + data = read("pt: ") + if data is None: + print() + continue + out = enc_cfb(data) + print("ct: ", out.hex()) + print() + + elif op == "2": + iv1 = os.urandom(16) + iv2 = os.urandom(16) + ct = enc_cbc(FLAG, iv1, iv2, padd=True) + print("iv1: ", iv1.hex()) + print("iv2: ", iv2.hex()) + print("ct: ", ct.hex()) + print() + + elif op == "3": + if third: + print("sheesh") + continue + block = read("pt: ") + if block is None: + print() + continue + if len(block) != 16: + print("hmmm\n") + continue + iv1 = os.urandom(16) + iv2 = os.urandom(16) + ct = enc_cbc(block, iv1, iv2, padd=0) + print("iv1: ", iv1.hex()) + print("iv2: ", iv2.hex()) + print("ct: ", ct.hex()) + third = 1 + print() + + elif op == "4": + break + else: + print("mabokkkk?") diff --git a/services/sheesh/docker-compose.yml b/services/sheesh/docker-compose.yml new file mode 100644 index 0000000..e1eb8ca --- /dev/null +++ b/services/sheesh/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3.8" + +services: + sheesh: + container_name: sheesh_container + hostname: sheesh + restart: always + build: + context: . + args: + - PASSWORD=root + ports: + - "12000:8000" + - "12022:22" + environment: + - FLAG=GEMASTIK{local_flag} diff --git a/services/sheesh/requirements.txt b/services/sheesh/requirements.txt new file mode 100644 index 0000000..c21b6ec --- /dev/null +++ b/services/sheesh/requirements.txt @@ -0,0 +1 @@ +pycryptodome \ No newline at end of file diff --git a/services/sheesh/run.sh b/services/sheesh/run.sh new file mode 100644 index 0000000..6ae49cb --- /dev/null +++ b/services/sheesh/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +exec socat tcp-l:8000,reuseaddr,fork exec:"python3 ./chall.py" diff --git a/services/sheesh/start.sh b/services/sheesh/start.sh new file mode 100644 index 0000000..74ea114 --- /dev/null +++ b/services/sheesh/start.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +ssh-keygen -A + +grep -q "^PermitRootLogin" /etc/ssh/sshd_config && \ + sed -i "s/^PermitRootLogin.*/PermitRootLogin no/" /etc/ssh/sshd_config || \ + echo "PermitRootLogin no" >> /etc/ssh/sshd_config + +grep -q "^PasswordAuthentication" /etc/ssh/sshd_config && \ + sed -i "s/^PasswordAuthentication.*/PasswordAuthentication yes/" /etc/ssh/sshd_config || \ + echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config + +echo "AllowUsers ctf" >> /etc/ssh/sshd_config + +/usr/sbin/sshd + +if [ -n "$FLAG" ]; then + echo "$FLAG" > /flag.txt + chmod 644 /flag.txt + chown root:root /flag.txt +fi + +exec su -c "cd /home/ctf/chall/src && ./run.sh" -s /bin/bash ctf