Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

buffer overflow exploit: Why does "jmp esp" need to be located in a DLL?

I am trying to understand classical buffer overflow exploits where an input buffer overwrites the stack, the function return address that is saved on the stack and upper memory regions (where you usually place the shell code). There are many examples of this on the internet and I think I have understood this pretty well:

  1. You put more data in some input buffer that the developer has made fixed size

  2. Your input overwrites the function arguments and the return address to the calling function on the stack

  3. That address is loaded into EIP when the OS tries to return from the function the overflow happened in and that is what allows you to get data you control into the EIP register (when not reading carefully some articles you get the impression you can overwrite CPU registers. Of course, this is not the case, you can only overwrite the stack but the CPU will load addresses from the stack into its registers)
  4. If the exploit is well designed the value loaded into EIP will make the program jump to the beginning of the shell code (see point 5)
  5. The next thing I think I have understood well is the "JMP ESP" mechanism. When replicating the crash in your lab environment you look for a place in memory that contains the "JMP ESP" instruction and you overwrite the EIP (now my wording is not precise, I know...) with that address. That address needs to be identical no matter how often you run this, at what time, which thread is executing your stuff etc., at least for the same OS version and the address must not contain any forbidden bytes. The code will jump to that address (at the same time the stack is reduced by 4 bytes) so "jmp esp" will jump to the next address in my overflow buffer after the place where I had put the value to overwrite EIP with and that is usually the place where the shellcode goes, maybe prepended with NOPs.

Now comes the question.

All articles I've read so far are looking for the address of the "JMP ESP" instructions in a DLL (which must not be relocatable, not compiled with ASLR, etc.). Why not looking in exe itself for a "jmp esp"? Why does it need to be in a DLL?

I have run the "!mona modules" command in Immunity Debugger and the only module displayed that satisfies all these conditions is the exe itself. When I look in popular exploit databases the address is always in loaded DLLs.

I cannot see any obvious reason for this. The exe can also be located at the same address in memory the same way a DLL can. What is the difference?

like image 440
kaidentity Avatar asked Dec 19 '15 09:12

kaidentity


2 Answers

Found another resource on this: As I wrote in a comment before, the addresses of the exe usually contain a zero:

http://resources.infosecinstitute.com/in-depth-seh-exploit-writing-tutorial-using-ollydbg/#commands

A module you can consider using is the main executable itself, which is quite often not subject to any compiler based exploit protections, especially when the application has been written by a third party developer and not Microsoft. Using the main executable has one major flaw however, in that it almost always starts with a zero byte. This is a problem because the zero byte is a string terminator in C/C++, and using zero bytes as part of strings used to overflow a buffer will often result in the string being terminated at that point, potentially preventing the buffer from being appropriately overflowed and breaking the exploit.

like image 155
kaidentity Avatar answered Oct 22 '22 08:10

kaidentity


In position independent code jump addresses are relative to the program-counter, while in non-relocatable code they are absolute. DLLs in Windows do not generally use position independent code. Exploits that rely on knowing the offset of the executable code in the binary require non-relocatable code.

like image 32
Clifford Avatar answered Oct 22 '22 09:10

Clifford