Our Blog

We are passionate about modern day security

May 09

The first public exploit we released was for the Eudora Qualcomm IMAP server, commonly known as Worldmail. This exploit was classified as a Structured Exception Handler (SEH) buffer overflow, and can be triggered from an unauthenticated internet based attacker.

This write-up will detail the technicalities behind the exploit, and also the learning opportunties faced while developing our first public exploit.

Firstly, a server-side SEH overflow vulnerability can be represented with the following pseudocode:

try
    accept a socket connection
    accept input
    do something with the input  <-- too much input - goto except
except 
    return an error message to the socket <-- crash happens here

An SEH overflow will cause some sort of exception within the exception handling code. When the controllable input is placed within the exception handler and is not handled appropriately, this may lead to more than one possible outcome. As attackers, we would want the target application to crash.

Now I know what you are thinking, a crash is useless, I want a shell! If it crashes using our crafted input, there is a possibility that we can control the crash. By controling the crash, instead of terminating the application, we may be able to determine what code is being executed instead.

In the Worldmail example, the crash occurs when the application is attempting to process the data between the braces {. After approximately 769 characters within the braces, you start to overwrite the SEH chain.

The resulting psudocode would resemble the following:

{
1
2
...
768
769
NSEH <-- 4 bytes
SEH <-- 4 bytes
{

The NSEH is intended to point to the address of the next exception handler. Overwriting this alone probably won’t achieve attacker much in terms of code execution. However, you will notice that SEH is right next to NSEH, this is the one you want to control in most circumstances.

Back in the day, you could overwrite the SEH to point to a JMP instruction and land at your shellcode. From Windows XP SP2, the steps required a little more effort, a mitigation was introduced that would fill all of the registers with 00000000 when an exception occurred. This meant that you could not merely JMP to your shellcode anymore.

Instead, we had to find a way to perform a series of POP instructions, to remove the nulls from the top of the stack. Fortunately for us, the exact POP; POP; RETN; series of instructions was found within an included Worldmail DLL. This was considered a WIN for us. Not only would we have demonstrated we can now control the program execution flow, but we are also now able to place code within the NSEH which will be executed following the PPR.

However, the NSEH is only 4 bytes in size, if we make the size any larger, it will affect our SEH offset. Fortunately for us, 4 bytes is large enough for a SHORT JMP byte sequence. We want this SHORT JMP sequence to allow us to jump over the SEH, where we can place some more code.

So far, the pseudocode resembled the following:

{
1
2
...
768
769
SHORT JMP
PPR
SHELLCODE
{

Now we are getting somewhere, we can now trigger the SEH overflow, control the execution flow and perform a PPR and land back to our code stored within the NSEH. This code will now perform a SHORT JMP over the SEH and land in our shellcode.

The problem we now face, is that bindshell shellcode is typically >300 bytes in size. Our available space for our shellcode is not nearly enough.

We do however, have a total of 769 bytes of space inside our initial buffer before we hit the NSEH, so if we can create, or use some existing code to jump back into our initial buffer, we can store a bindshell there.

Rather than perform the calculation to jump back far enough, we decided it would be more fun to use Matt Millers egghunt-shellcode instead. If you are interested in how this works, we suggest reading the linked PDF document.

Our final pseudocode exploit would resemble the following:

{
1
2
...
EGG
SHELLCODE
...
768
769
SHORT JMP
PPR
EGGHUNTER
}

The full original exploit code can be found at the following Exploit-DB URL. https://www.exploit-db.com/exploits/18354

Since this exploit was created, the code has proven reliable, the kind hoped for, but less expected of public code. What we have noticed however, is that the INT 2E Windows syscall does not perform the same function it previously did. As a result, on the latest versions of Windows, this exploit code may not be as reliable as it once was.

Fortunately however, an updated version of the exploit has been included within the available exploits as part of the nullsploit exploitation engine. This can be found within the tools section of this site, or at the following link: nullsploit-engine.




You May Also Enjoy