diff --git a/services/phew/Dockerfile b/services/phew/Dockerfile new file mode 100644 index 0000000..0d0920d --- /dev/null +++ b/services/phew/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/phew/chall.py b/services/phew/chall.py new file mode 100644 index 0000000..a7bea1b --- /dev/null +++ b/services/phew/chall.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +import os, sys, json, random, hashlib, hmac +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad +with open("/flag.txt", "rb") as f: + flag = f.read() + +menu = ( + "1) encrypt\n" + "2) profit\n" + "3) nyerah\n" + ">> " +) + + +k = 1024 +n = 169 + +rng = random.SystemRandom() + +def rand(k_bits: int) -> int: + return rng.randrange(1, 1 << k_bits) + +def gen(n: int, k_bits: int): + a = [rand(k_bits) for _ in range(n)] + return a + +def b2b(b: bytes) -> list[int]: + out = [] + for byte in b: + for i in range(8): + out.append((byte >> i) & 1) + return out + +def pack(bits) -> bytes: + out = bytearray() + for i in range(0, len(bits), 8): + chunk = bits[i:i+8] + val = 0 + for j, bit in enumerate(chunk): + val |= (bit & 1) << j + out.append(val) + return bytes(out) + +def gen_key(x_bits: list[int], saltx: bytes, salty: bytes, length: int = 16) -> bytes: + material = pack(x_bits) + prk = hashlib.pbkdf2_hmac("sha256", material, saltx, 131072, dklen=32) + return hmac.new(prk, b"afk-players-wanted-now" + salty + b"\x01", hashlib.sha256).digest()[:length] + +def enc(k: bytes, data: bytes): + iv = os.urandom(16) + ct = AES.new(k, AES.MODE_CBC, iv).encrypt(pad(data, 16)) + return iv, ct + +def add(a, x_bits) -> int: + return sum(ai for ai, xi in zip(a, x_bits) if xi) + +def main(): + a = gen(n, k) + x_bits = b2b(flag) + if len(x_bits) < n: + x_bits += [rng.randrange(0, 2) for _ in range(n - len(x_bits))] + else: + x_bits = x_bits[:n] + + s = add(a, x_bits) + + saltx = os.urandom(16) + salty = os.urandom(16) + key = gen_key(x_bits, saltx, salty) + + iv, ct = enc(key, flag) + + header = { + "n": n, + "k_bits": k, + } + print(json.dumps(header, separators=(",", ":")), flush=True) + + while True: + try: + print(menu, end="", flush=True) + line = sys.stdin.readline() + if not line: + break + try: + choice = int(line.strip()) + except ValueError: + print("sheesh") + continue + + if choice == 1: + print("data: ", end="", flush=True) + dline = sys.stdin.readline() + if not dline: + break + try: + data = bytes.fromhex(dline.strip()) + except Exception: + print("hmmm") + continue + iv, ct = enc(key, data) + print(iv.hex()) + print(ct.hex()) + + elif choice == 2: + print(json.dumps({"a": a}, separators=(",", ":"))) + print(str(s)) + print(saltx.hex()) + print(salty.hex()) + print(iv.hex()) + print(ct.hex()) + + elif choice == 3: + print("bubay") + return + + else: + print("tidak ada yang mustahil, hehehe") + + except Exception: + print("zzz") + +if __name__ == "__main__": + main() diff --git a/services/phew/dist/chall.py b/services/phew/dist/chall.py new file mode 100644 index 0000000..a7bea1b --- /dev/null +++ b/services/phew/dist/chall.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +import os, sys, json, random, hashlib, hmac +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad +with open("/flag.txt", "rb") as f: + flag = f.read() + +menu = ( + "1) encrypt\n" + "2) profit\n" + "3) nyerah\n" + ">> " +) + + +k = 1024 +n = 169 + +rng = random.SystemRandom() + +def rand(k_bits: int) -> int: + return rng.randrange(1, 1 << k_bits) + +def gen(n: int, k_bits: int): + a = [rand(k_bits) for _ in range(n)] + return a + +def b2b(b: bytes) -> list[int]: + out = [] + for byte in b: + for i in range(8): + out.append((byte >> i) & 1) + return out + +def pack(bits) -> bytes: + out = bytearray() + for i in range(0, len(bits), 8): + chunk = bits[i:i+8] + val = 0 + for j, bit in enumerate(chunk): + val |= (bit & 1) << j + out.append(val) + return bytes(out) + +def gen_key(x_bits: list[int], saltx: bytes, salty: bytes, length: int = 16) -> bytes: + material = pack(x_bits) + prk = hashlib.pbkdf2_hmac("sha256", material, saltx, 131072, dklen=32) + return hmac.new(prk, b"afk-players-wanted-now" + salty + b"\x01", hashlib.sha256).digest()[:length] + +def enc(k: bytes, data: bytes): + iv = os.urandom(16) + ct = AES.new(k, AES.MODE_CBC, iv).encrypt(pad(data, 16)) + return iv, ct + +def add(a, x_bits) -> int: + return sum(ai for ai, xi in zip(a, x_bits) if xi) + +def main(): + a = gen(n, k) + x_bits = b2b(flag) + if len(x_bits) < n: + x_bits += [rng.randrange(0, 2) for _ in range(n - len(x_bits))] + else: + x_bits = x_bits[:n] + + s = add(a, x_bits) + + saltx = os.urandom(16) + salty = os.urandom(16) + key = gen_key(x_bits, saltx, salty) + + iv, ct = enc(key, flag) + + header = { + "n": n, + "k_bits": k, + } + print(json.dumps(header, separators=(",", ":")), flush=True) + + while True: + try: + print(menu, end="", flush=True) + line = sys.stdin.readline() + if not line: + break + try: + choice = int(line.strip()) + except ValueError: + print("sheesh") + continue + + if choice == 1: + print("data: ", end="", flush=True) + dline = sys.stdin.readline() + if not dline: + break + try: + data = bytes.fromhex(dline.strip()) + except Exception: + print("hmmm") + continue + iv, ct = enc(key, data) + print(iv.hex()) + print(ct.hex()) + + elif choice == 2: + print(json.dumps({"a": a}, separators=(",", ":"))) + print(str(s)) + print(saltx.hex()) + print(salty.hex()) + print(iv.hex()) + print(ct.hex()) + + elif choice == 3: + print("bubay") + return + + else: + print("tidak ada yang mustahil, hehehe") + + except Exception: + print("zzz") + +if __name__ == "__main__": + main() diff --git a/services/phew/docker-compose.yml b/services/phew/docker-compose.yml new file mode 100644 index 0000000..48b947b --- /dev/null +++ b/services/phew/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3.8" + +services: + phew: + container_name: phew_container + hostname: phew + restart: always + build: + context: . + args: + - PASSWORD=root + ports: + - "13000:8000" + - "13022:22" + environment: + - FLAG=GEMASTIK{local_flag} diff --git a/services/phew/requirements.txt b/services/phew/requirements.txt new file mode 100644 index 0000000..c21b6ec --- /dev/null +++ b/services/phew/requirements.txt @@ -0,0 +1 @@ +pycryptodome \ No newline at end of file diff --git a/services/phew/run.sh b/services/phew/run.sh new file mode 100644 index 0000000..6ae49cb --- /dev/null +++ b/services/phew/run.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +exec socat tcp-l:8000,reuseaddr,fork exec:"python3 ./chall.py" diff --git a/services/phew/start.sh b/services/phew/start.sh new file mode 100644 index 0000000..7b40126 --- /dev/null +++ b/services/phew/start.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +ssh-keygen -A + +# Configure SSH +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 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..1b507bf --- /dev/null +++ b/services/sheesh/chall.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import os, sys, json, random, hashlib, hmac +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad +with open("/flag.txt", "rb") as f: + flag = f.read() + +B = 16 +opts = ( + "1) encrypt\n" + "2) profit\n" + "3) nyerah\n" + ">> " +) + +def exp(prk: bytes, info: bytes, L: int) -> bytes: + return hmac.new(prk, info + b"\x01", hashlib.sha256).digest()[:L] + +def enc(k: bytes, data: bytes): + iv = os.urandom(B) + ct = AES.new(k, AES.MODE_CBC, iv).encrypt(pad(data, B)) + return iv, ct + +def inp_hex(prompt: str) -> bytes: + print(prompt, end="", flush=True) + s = sys.stdin.readline() + if not s: + raise EOFError + return bytes.fromhex(s.strip()) + +def rand(rng, d, lo, hi): + while True: + v = [rng.randint(lo, hi) for _ in range(d)] + if any(v): + return v + +def syst(rng): + d = rng.choice([2, 3]) + m = rng.randint(5, 8) + x = rand(rng, d, -3, 3) + rows = [] + for _ in range(m): + base = rand(rng, d, -3, 3) + r = rng.randint(1, 7) + scaled = [r * a for a in base] + e = rng.randint(0, 1) + bi = sum(ai * xi for ai, xi in zip(scaled, x)) + e + rows.append((scaled, bi)) + rng.shuffle(rows) + A = [row for (row, _) in rows] + B = [b for (_, b) in rows] + pub = {"dim": d, "A": A, "b": B} + return pub, tuple(x) + +def bundle(): + rng = random.Random(os.urandom(16)) + systems = [] + hidden = [] + for _ in range(4): + pub, x = syst(rng) + systems.append(pub) + hidden.append(x) + return {"systems": systems}, tuple(hidden) + +def get_key(saltx: bytes, salty: bytes, b): + parts = [] + for x in b: + parts.append(",".join(str(t) for t in x)) + material = "|".join(parts).encode() + prk = hashlib.pbkdf2_hmac("sha256", material, saltx, 131072, dklen=32) + return exp(prk, b"g3m4zzzt1q" + salty, 16) + +def main(): + a, b = bundle() + print(json.dumps(a, separators=(",", ":")), flush=True) + saltx = os.urandom(16) + salty = os.urandom(16) + key = get_key(saltx, salty, b) + iv, ct = enc(key, flag) + while True: + try: + print(opts, end="", flush=True) + line = sys.stdin.readline() + if not line: + break + try: + choice = int(line.strip()) + except ValueError: + print("sheesh") + continue + + if choice == 1: + data = inp_hex("data: ") + iv, ct = enc(key, data) + print(iv.hex()) + print(ct.hex()) + + elif choice == 2: + print(iv.hex()) + print(ct.hex()) + print(saltx.hex()) + print(salty.hex()) + + elif choice == 3: + print("bubay") + return + + else: + print("when you feel like quitting, remember why you started :v (yapping)") + + except Exception: + print("zzz") + +if __name__ == "__main__": + main() diff --git a/services/sheesh/dist/chall.py b/services/sheesh/dist/chall.py new file mode 100644 index 0000000..1b507bf --- /dev/null +++ b/services/sheesh/dist/chall.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +import os, sys, json, random, hashlib, hmac +from Crypto.Cipher import AES +from Crypto.Util.Padding import pad +with open("/flag.txt", "rb") as f: + flag = f.read() + +B = 16 +opts = ( + "1) encrypt\n" + "2) profit\n" + "3) nyerah\n" + ">> " +) + +def exp(prk: bytes, info: bytes, L: int) -> bytes: + return hmac.new(prk, info + b"\x01", hashlib.sha256).digest()[:L] + +def enc(k: bytes, data: bytes): + iv = os.urandom(B) + ct = AES.new(k, AES.MODE_CBC, iv).encrypt(pad(data, B)) + return iv, ct + +def inp_hex(prompt: str) -> bytes: + print(prompt, end="", flush=True) + s = sys.stdin.readline() + if not s: + raise EOFError + return bytes.fromhex(s.strip()) + +def rand(rng, d, lo, hi): + while True: + v = [rng.randint(lo, hi) for _ in range(d)] + if any(v): + return v + +def syst(rng): + d = rng.choice([2, 3]) + m = rng.randint(5, 8) + x = rand(rng, d, -3, 3) + rows = [] + for _ in range(m): + base = rand(rng, d, -3, 3) + r = rng.randint(1, 7) + scaled = [r * a for a in base] + e = rng.randint(0, 1) + bi = sum(ai * xi for ai, xi in zip(scaled, x)) + e + rows.append((scaled, bi)) + rng.shuffle(rows) + A = [row for (row, _) in rows] + B = [b for (_, b) in rows] + pub = {"dim": d, "A": A, "b": B} + return pub, tuple(x) + +def bundle(): + rng = random.Random(os.urandom(16)) + systems = [] + hidden = [] + for _ in range(4): + pub, x = syst(rng) + systems.append(pub) + hidden.append(x) + return {"systems": systems}, tuple(hidden) + +def get_key(saltx: bytes, salty: bytes, b): + parts = [] + for x in b: + parts.append(",".join(str(t) for t in x)) + material = "|".join(parts).encode() + prk = hashlib.pbkdf2_hmac("sha256", material, saltx, 131072, dklen=32) + return exp(prk, b"g3m4zzzt1q" + salty, 16) + +def main(): + a, b = bundle() + print(json.dumps(a, separators=(",", ":")), flush=True) + saltx = os.urandom(16) + salty = os.urandom(16) + key = get_key(saltx, salty, b) + iv, ct = enc(key, flag) + while True: + try: + print(opts, end="", flush=True) + line = sys.stdin.readline() + if not line: + break + try: + choice = int(line.strip()) + except ValueError: + print("sheesh") + continue + + if choice == 1: + data = inp_hex("data: ") + iv, ct = enc(key, data) + print(iv.hex()) + print(ct.hex()) + + elif choice == 2: + print(iv.hex()) + print(ct.hex()) + print(saltx.hex()) + print(salty.hex()) + + elif choice == 3: + print("bubay") + return + + else: + print("when you feel like quitting, remember why you started :v (yapping)") + + except Exception: + print("zzz") + +if __name__ == "__main__": + main() 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