7

Do I always have to overwrite EIP to get to write on the stack in a buffer overflow? How's the memory organized? I can't find a proper graph with google

10

You don't always have to overwrite the return address in order to exploit a stack based buffer overflow (also has a great diagram of the stack layout). With a stack based buffer overflow you can corrupt other variables declared in the local scope of the function which can produce interesting results.

For instance lets say there is an authentication funcation:

//I like to think of the return address as sitting on top of every function.
//void * ret;
boolean login(char * password){
  boolean is_logged_in=False;
  char buf[5];
  strcpy(buf,password);
  if(strmp(buf, MASTER_PASSWORD)==0){
     is_Logged_int=True;
  }
  return is_logged_in;
}

The stack layout is such that is_logged_in is above buf. The stack frame, which contains the return address is somewhere above is_logged_in. The return address will become the EIP only when the function returns. But it isn't necessary for the attacker to corrupt the stack frame in order for the attacker to take advantage of this buffer overflow. Simply overwriting the value of is_logged_in with a value that equals True will allow the attacker to authenticate without knowing the value of MASTER_PASSWORD.

In this buffer overflow vulnerability, the use of: ASLR, NX Zones, and Stack Canaries does not prevent exploitation. In fact it is also likely that the same exact exploit will work regardless of platform (windows/linux/arm/x86...).

(Disclaimer: I think I read about this exploitation method in "Hacking: The Art of Exploitation")

4

That's the other way round: you overflow a stack buffer so that you get to overwrite the field with which EIP will be loaded when the function returns.

In usual architectures, the stack grows downwards, so that the "return address" pushed on the stack when the function was called lies a few bytes after the local variables. By overflowing a local buffer, you get to overwrite what lies after in RAM, i.e. the return address. When the function returns, the corresponding ret opcode loads the return address into EIP, which means that execution jumps at that address.

  • Why do I see something like "EIP: 0c0c0c0c" when the debugger get fired up? Is the debugger alerting me that EIP was trying to jump to 0c0c0c0c ? – John Smith Oct 23 '12 at 17:02
  • It should mean that the return address was overwritten with "0c0c0c0c"; when the function returned, it tried to jump at that address. Most addresses in RAM are unmapped, and such a jump triggers an exception (a segfault, or whatever it is called on your OS), and possibly launch a debugger. – Thomas Pornin Oct 23 '12 at 17:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.