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/Pailier.py b/services/phew/Pailier.py new file mode 100644 index 0000000..ef7cafc --- /dev/null +++ b/services/phew/Pailier.py @@ -0,0 +1,47 @@ +from Crypto.Util.number import * +from math import lcm +import random + +class pailier: + def __init__(self): + self.primes = [getPrime(512) for _ in range(2)] + self.n = 1 + self.phi = 1 + self.mul = 1 + for i in range(2): + self.n *= self.primes[i] + self.phi *= (self.primes[i] - 1) + self.n2 = self.n * self.n + self.g = [pow(random.randrange(1, self.n2), self.primes[i], self.n2) for i in range(2)] + for x in self.g: + self.mul = (self.mul * x) % self.n2 + self.miu = inverse(self.L(pow(self.mul, self.phi, self.n2)), self.n) + self.alpha = [None, None] + for idx in range(2): + while True: + a = random.randrange(2, self.n - 1) + if GCD(a, self.n) == 1: + self.alpha[idx] = a + break + self.beta = [random.randrange(0, self.n), random.randrange(0, self.n)] + + def L(self, val): + return (val - 1) // self.n + + def pubkey(self): + return (self.n, self.g) + + def encrypt(self, msg: int) -> int: + r = random.randrange(0, self.n - 1) + gb = self.g[random.randrange(0, 2)] + gm = pow(gb, msg, self.n2) + rn = pow(r, self.n, self.n2) + return (gm * rn) % self.n2 + + def decrypt(self, ct: int) -> int: + raw = self.L(pow(ct, self.phi, self.n2)) % self.n + raw = (raw * self.miu) % self.n + t = pow(ct % self.n, (self.n - 1) // 2, self.n) if (self.n % 2 == 1) else 0 + idx = 0 if t == 1 else 1 + return (self.alpha[idx] * raw + self.beta[idx]) % self.n + diff --git a/services/phew/chall.py b/services/phew/chall.py new file mode 100644 index 0000000..c97146c --- /dev/null +++ b/services/phew/chall.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +from Pailier import * +from Crypto.Util.number import * +with open("/flag.txt", "rb") as f: + flag = f.read() +flag = bytes_to_long(flag) +cipher = pailier() +while True: + print("1. encrypt") + print("2. bingo") + print("3. decrypt") + print("4. exit") + inp = int(input("> ")) + if inp==1: + print("pt (hex)") + inp = input("> ") + ct = cipher.encrypt(int(inp,16)) + print('ct : ','{0:x}'.format(ct)) + elif inp==2: + ct = cipher.encrypt(flag) + print('ct : ','{0:x}'.format(ct)) + elif inp==3: + print("ct (hex)") + inp = input("> ") + pt = cipher.decrypt(int(inp,16)) + print('pt : ','{0:x}'.format(pt)) + else: + exit() diff --git a/services/phew/dist/Pailier.py b/services/phew/dist/Pailier.py new file mode 100644 index 0000000..ef7cafc --- /dev/null +++ b/services/phew/dist/Pailier.py @@ -0,0 +1,47 @@ +from Crypto.Util.number import * +from math import lcm +import random + +class pailier: + def __init__(self): + self.primes = [getPrime(512) for _ in range(2)] + self.n = 1 + self.phi = 1 + self.mul = 1 + for i in range(2): + self.n *= self.primes[i] + self.phi *= (self.primes[i] - 1) + self.n2 = self.n * self.n + self.g = [pow(random.randrange(1, self.n2), self.primes[i], self.n2) for i in range(2)] + for x in self.g: + self.mul = (self.mul * x) % self.n2 + self.miu = inverse(self.L(pow(self.mul, self.phi, self.n2)), self.n) + self.alpha = [None, None] + for idx in range(2): + while True: + a = random.randrange(2, self.n - 1) + if GCD(a, self.n) == 1: + self.alpha[idx] = a + break + self.beta = [random.randrange(0, self.n), random.randrange(0, self.n)] + + def L(self, val): + return (val - 1) // self.n + + def pubkey(self): + return (self.n, self.g) + + def encrypt(self, msg: int) -> int: + r = random.randrange(0, self.n - 1) + gb = self.g[random.randrange(0, 2)] + gm = pow(gb, msg, self.n2) + rn = pow(r, self.n, self.n2) + return (gm * rn) % self.n2 + + def decrypt(self, ct: int) -> int: + raw = self.L(pow(ct, self.phi, self.n2)) % self.n + raw = (raw * self.miu) % self.n + t = pow(ct % self.n, (self.n - 1) // 2, self.n) if (self.n % 2 == 1) else 0 + idx = 0 if t == 1 else 1 + return (self.alpha[idx] * raw + self.beta[idx]) % self.n + diff --git a/services/phew/dist/chall.py b/services/phew/dist/chall.py new file mode 100644 index 0000000..c97146c --- /dev/null +++ b/services/phew/dist/chall.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 + +from Pailier import * +from Crypto.Util.number import * +with open("/flag.txt", "rb") as f: + flag = f.read() +flag = bytes_to_long(flag) +cipher = pailier() +while True: + print("1. encrypt") + print("2. bingo") + print("3. decrypt") + print("4. exit") + inp = int(input("> ")) + if inp==1: + print("pt (hex)") + inp = input("> ") + ct = cipher.encrypt(int(inp,16)) + print('ct : ','{0:x}'.format(ct)) + elif inp==2: + ct = cipher.encrypt(flag) + print('ct : ','{0:x}'.format(ct)) + elif inp==3: + print("ct (hex)") + inp = input("> ") + pt = cipher.decrypt(int(inp,16)) + print('pt : ','{0:x}'.format(pt)) + else: + exit() diff --git a/services/phew/dist/flag.txt b/services/phew/dist/flag.txt new file mode 100644 index 0000000..3511f21 --- /dev/null +++ b/services/phew/dist/flag.txt @@ -0,0 +1 @@ +GEMASTIK{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} \ No newline at end of file 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/flag.txt b/services/phew/flag.txt new file mode 100644 index 0000000..3511f21 --- /dev/null +++ b/services/phew/flag.txt @@ -0,0 +1 @@ +GEMASTIK{AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA} \ No newline at end of file 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