Today we’ll be studying “egg hunters” as of part 4 of the FuzzySecurity tutorials. Basically this technique is useful when the buffer remaining for your shell code is too small to do anything useful. So far we’ve been lucky and we had huge buffers to inject the shell code, but some time, you may be left with a couple of bytes only. With a “egg hunter”, instead of storing your shell code, you store a small function that will look for “magic bytes” in memory. Your shell code somewhere else in executable memory and tagged with these “magic bytes” so that your egg hunter finds it and executes it. Pretty straight forward.
Exploiting Kolibri Web Server
So my goal today was to test out the egg hunter example from the tutorial. However I got cocky and try to exploit the web server by smashing SEH rather than a normal buffer overflow. Everything went fine until I had to call the address containing the POP-POP-RET.
The problem I’m running into is when looking for a “POP POP RET”, all the results are within Kolibri.exe, and all addresses starts with a null byte, i.e. “\x08\x89\x51\x00”. That means our payload will terminate at the null byte. I thought this wouldn’t be much of a problem, since [SEH] is an address anyway, the only difficulty would be that I may have to put the payload in the buffer prior to the [nSEH], and have a short jmp into the buffer placed into the [nSEH]. Now for some reason, it seems that SEH catches the exception, but never jumps to my POP-POP-RET address; it just terminates the program.
So I got stuck here for today. More to follow tomorrow
"HEAD /"+smash+" HTTP/1.1\r\n"
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; he; rv:18.104.22.168) Gecko/20101026 Firefox/3.6.12\r\n"
Today I’ve followed part 3 of the FuzzySecurity tutorial, which went pretty smoothly now that all the VMs and software have been setup and fixed. In the end, I was successful in binding a shell to a port. Yet, I had the feeling that I often have when learning by tutorial: it works now, but would I actually be able to replicate this while exploiting another application? And what really happened? I mean I have loaded my shell code, but yet, I don’t have a clear understanding of what SEH really is. So after completing the tutorial, I actually took time to try to figure out what exactly happened.
The Structure Exception Handler (SEH)
The SEH is a Windows native mechanism to handle both hardware and software exceptions in Windows at both kernel and user spaces. So when the normal flow of an application is interrupted, the SEH comes in to handle the management of the interruption. Basically, this is the native component of Windows which triggers the try…catch… statement you use in your programs. So how does SEH works?
As depicted above, the SEH is a linked list in memory, in which each nodes contains 2 pointers; one pointer to the next node in the list and one pointer to the function who handles this specific exception. There is a node for each exception handled by the current function. These nodes are basically all your “catch (FileNotFoundException)…catch(NullPointerException)” etc…. Each node of the linked list stores the pointer to the Structure Exception Handler and a pointer to the next Structure Exception Handle. The root node, the default exception handler is actually stored in the stack. So in this tutorial, when we smash the stack, we gain control of those 2 pointers, which we will use to jump to our shell code.
So in this case, what is happening is that we smash the stack with “A”s, overwriting EIP with an invalid pointer (0x41414141). Since this is not a valid value, an “Illegal Instruction”/”Access Violation” exception is thrown and thus triggers the SEH handler code. This means the code pointed by the “SEH Handler” [SEH] part of the stack will be called, which is actually a call to the next node in the SEH linked list.
By writing an address pointing to “POP POP RET” instructions at [SEH] and having it executed them, we will load the stack address of [nSEH] into EIP and as such, execute the op code at [nSEH]. So if we insert a short JMP to the address of our shell code (0xEB06 [shellcode]) at the address pointed by [nSEH], we’re done.
This technique won’t work with SafeSEH and SEHOP.
Moving on with Exploiting DVDX Player
You should have no issue generating the Playlist file to overflow the EIP register and trigger a exception.
Then by replacing the long string of “A” by a Metasploit pattern and !mona findmsp, we can find the offsets, as in past tutorials;
Since we’re interested in exploiting SEH in this tutorial, we’re interested at which offset the SEH is being overwritten by the Metasploit pattern. In this case, it’s overwritten at 608 bytes and we have 1384 bytes of buffer for our shell code. That means that the nSEH is at 608 bytes and SEH at 612: “A”*608 + [nSEH] + [SEH] + [Shellcode].
To link with what we’ve read in the first section, here is what happens: Our string of 608 “A” will crash the EIP and cause an exception, jumping directly to the contents of [SEH]. [SEH] must contain an address. [SEH] is located at [ESP]+8 at execution. Remember that the ESP is an indirect pointer to the top of the stack, and the stack grows downwards. By POPping two times and returning, we will load the stack address of [nSEH] into the EIP and execute whatever instruction at this address. To be perfectly honest, I’ll need to further understand this part….
Accordingly, we will look in memory for a “POP POP RET” combination using “!mona seh“. Mona will return quite a few results. We will prefer results located in DLLs owned by DVDX Player, since they are OS-independent.
We’ve picked up 0x640345e7 (“\xe7\x45\x03\x64”) since it’s located within DVDX Player and contains no invalid bytes. We now got the [SEH] part of our payload:
Now for [nSEH], we’ll need to put a “jmp [offset]” instruction in it. Our shell code begins right after the [SEH] (4 bytes) and our jmp instruction is 2 bytes. The short jump op code is 0xEB, followed by the number of bytes to jump from EIP, i.e. 6 bytes. So the instruction to insert at [nSEH] is “\xeb6\x90\x90”:
All that is left is the shellcode, which is a quick NOP slide and a shell bind. Done! Excited, I plug the payload into DVDX Player and fail miserably to have have the shell code executed. I used the same shell code as the previous tutorial in an attempt to minimize the number of things that can go wrong. By doing so, everything went wrong. Well not exactly everything, but the previous shell code had byte “0x1A” in it, which created additional READ exception in the code once the shell code loaded. So I regenerated the code without bytes 0x00, 0x0A, 0x0D and 0x1A and everything went perfect. Or almost. When running the shell code, Windows asked me to unblock port 4444 to listen to inbound connection. I guess using a reverse shell or a “download and execute” is quieter…
I wonder if anything I wrote made any sense since I’ve been so focus into this exploit today. The ascii diagram from FuzzySecurity summarize the principle well enough:
Well enough for today, my frontal lobe is overheating. More tomorrow…