4

I was testing out a buffer overflow and the following strange thing happened:

enter image description here

The return address is at 0xbffff7bc which I discovered from testing. I replaced it with the value I wanted 0xbffff636.

When return is called it seems to direct to a different address than the one I added. From the back trace it can be seen that it tested all the addresses next to that one.

However, it replaced 0xbffff636 with 0xbffff71b. Clearly it didn't change the other addresses it tried to return to in the backtrace 1 through 6, but 0 is incorrect. It seems that #0 should have been 0xbffff636 but it got edited, as all the other addresses after it were tested.

What is a possible reason for why the address changed?

EDIT/UPDATE

This shows what's at address 0xbffff636 it's the middle of a NOP sled. The buffer is 500 bytes the return address is at 540 offset. enter image description here

I am currently at a break point at the return statement, and what's strange is that doing a backtrace at the point shows that 0xbffff636 was tried as a return point, but I haven't returned yet. When I continue and return the backtrace turns into the backtrace I posted originally with '0xbff636` becoming '0xbffff71b'. Thought I might add that.

UPDATE2 Here's the relevant part of the code from the book: enter image description here

Instead of just continuing I continue to 'next' through the program till I left the function recv_line that copied data to a buffer(called request) it was passed. That function returned fine since I didn't touch it's address. Now I continued through the handler function above until I got to the end and this is what I saw: enter image description here enter image description here

It seems to not find 0xbfff636 to valid when it first sees it. I have done overflows in this environment before, so I am pretty sure no protections are on.

Note: I'm compiling with -g debug flag. I run the process as sudo. Then attach to the running process with gdb

4

Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP) are techniques used to prevent buffer overflows to be successfully exploited.

ASLR uses random offset locations where a system executable is loaded into memory.

DEP marks areas of memory as either executable or non-executable and allows data only to be executed in the executable marked memory locations.

When the two are combined, it becomes amazingly difficult to exploit vulnerabilities in applications using shell code.

However, it is not impossible. There are ways where these techniques can be bypassed. The following link is a whitepaper that explains a situation where ASLR and DEP are bypassed: https://www.exploit-db.com/docs/17914.pdf

  • I probably should of added this:I tested this exploit in an environment that comes with the book 'Hacking the art of Exploitation 2nd addition' so I believe both ASLR and DEP are disabled. And I tested other overflows before in this environment that worked but not this one. Does this mean that ASRL and DEP are still enabled or could something else be causing this? Thank you – dylan7 Jan 7 '16 at 6:35
  • @dylan7 What is the environment you're using to test these buffer overflows? Many of us might not have that book. – Mark Buffalo Jan 7 '16 at 19:16
  • It's 32 bit ubuntu running on virtual box. It is set up for testing so all defenses ASLR and DEP are disabled. – dylan7 Jan 7 '16 at 19:18
3

After further investigation it turned out that when constructing the payload using Python's print statement one 0a newline was added right before the shellcode and after the last NOP resulting in unexcutable code. I figured this out by experimenting with the book's C program which created the exact same payload but worked when I ran it. After using Perl's print statement to create the payload file, no 0a were added and the exploit succeeded. It was subtle but I caught it.

1

Did you start from an instruction mid way through the stack? If you do this then the value that was already in memory could be returned if it was not deleted as expected.

This is one possible explanation of the behaviour.

There is a brilliant example of this in the last 3rd of this video.

  • I'm not sure I follow what you're saying. Could you explain in a bit more detail what the video shows? – RoraΖ Jan 7 '16 at 15:29
  • At 1.04 he disassemble one of the functions, and over flows the stack before getting getting the stack to jump to an instruction. In the example he gives he get printf to take his value in memory and then print it. Then he attempts to print the variable x which runs a returns a random value from the elsewhere in the stack as it did not have a valid value to return. Probably better jumping to 1.04 and having a look. – TheJulyPlot Jan 7 '16 at 16:05

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.