0

I am trying to understand the buffer overflow exploit and more specifically, how it can be used to run own code - e.g. by starting our own malicious application or anything similar.

While I do understand the idea of the buffer overflow exploit using the gets() function (overwriting the return address with a long enough string and then jumping to the said address), there are a few things I am struggling to understand in real application, those being:

  • Do I put my own code into the string just behind the return address? If so, how do I know the address to jump to? And if not, where do I jump and where is the actual code located?

  • Is the actual payload that runs the code my own software that's running and the other program just jumps into it or are all the instructions provided in the payload? Or more specifically, what does the buffer overflow exploit implementation actually look like?

  • What can I do when the address (or any instruction) contains 0? gets() function stops reading when it reads 0 so how is it possible to get around this problem?

As a homework, I am trying to exploit a very simple program that just asks for an input with gets() (ASLR turned off) and then prints it. While I can find the memory address of the function which calls it and the return, I just can't figure out how to actually implement the exploit.

2
  • You usually look for an instruction like jmp to rsp in one of the shared libraries. Since shared libraries are always loaded at known addresses you can externally determine the address of one such function. Commented Nov 18, 2017 at 14:56
  • This could have been a good match for Sec.SE Commented Nov 18, 2017 at 21:00

1 Answer 1

1

You understand how changing the return address lets you jump to an arbitrary location.

But as you have correctly identified you don't know where you have loaded the code you want to execute. You just copied it into a local buffer(which was mostly some where on the stack).

But there is something that always points to this stack and it is the stack pointer register. (Lets assume x64 and it would be %rsp).

Assuming your custom code is on the top of the stack. (It could be at an offset but that too can be managed similarly).

Now we need an instruction that 1. Allows us to jump to the esp 2. Is located at a fixed address.

So most binaries use some kind of shared libraries. On windows you have kernel32.dll. In all the programs this library is loaded, it is always mapped at the same address. So you know the exact location of every instruction in this library.

All you have to do is disassemble one such library and find an instruction like

jmp *%rsp // or a sequence of instructions that lets you jump to an offset

Then the address of this instruction is what you will place where the return address is supposed to be. The function will return then and then jump to the stack (ofcourse you need an executable stack for this). Then it will execute your arbitrary code.

Hope that clears some confusion on how to get the exploit running.

To answer your other questions -

Yes you can place your code in the buffer directly. Or if you can find the exact code you want to execute (again in a shared library), you can simply jump to that.

Yes, gets would stop at \n and 0. But usually you can get away by changing your instructions a bit to write code that doesn't use these bytes at all.

You try different instructions and check the assembled bytes.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, making me realize that I can simply jump to ESP (which can be the starting point of the buffer) suddenly helped me to realize how it all works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.