2

I am trying my luck with buffer overflows, however, I am stuck at one point. I overwrite the return address, so that EIP will point into the address of the nop sled of my shellcode. However, when ret is run, I get the error: Cannot access memory at address 0x90909094. Can anybody see what is wrong?

A dump from memory:

(gdb) x/8wx $esp
0xbffff18c: 0xbffff470  0xbffff400  0x00000000  0x08048559
0xbffff19c: 0xb7fc6ff4  0x08048550  0x00000000  0x00000000
(gdb) x/8wx 0xbffff470
0xbffff470: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff480: 0x90909090  0x90909090  0x90909090  0x90909090
(gdb) nexti
Cannot access memory at address 0x90909094
(gdb) i r eip
 eip            0xbffff470  0xbffff470

As you can see, the return address is 0xbffff470 and on that location, my nop sled is placed. However, as soon as I run the next instruction (which is ret), I get an error. What is wrong here? Edit: I am using x86-32

Edit: I found the answer in another post: GDB ret "cannot access memory at address" Basically, the problem is right before the address esp is set to equals ebp, when in my case will be 0x90909090.. Thus, a quick solve is to not use 'A's as padding, but rather just the address in every word.

Community
  • 1
  • 1
user1090614
  • 2,575
  • 6
  • 22
  • 27
  • Is this x86-32? I didn't know anybody still used that! :) Tag your question [x86-32] or [x86-64] so people know which one you're using. If you're using x86-64, one bug is obvious: you should be looking at `%rip` and `%rsp`, not just `%eip` and `%esp`. Is that all it is? – Quuxplusone Feb 19 '14 at 19:22
  • 2
    Assuming that you haven't made any mistakes, is there any chance that the cpu's data execute protection is enabled and preventing instructions from being run in non-code segements? – rcgldr Feb 19 '14 at 19:47
  • @rcgldr I think not? If I compile with -z execstack and -fno-stack-protector it should be all good? – user1090614 Feb 19 '14 at 21:06
  • @Quuxplusone I am using x86-32 – user1090614 Feb 19 '14 at 21:09
  • If the goal is to change the return address, then you could set eax to the desired return address, then after mov esp,ebp, use mov [esp],eax, ret. – rcgldr Feb 20 '14 at 02:14

1 Answers1

0

OP answers his own question (more or less):

Edit: I found the answer in another post: GDB ret "cannot access memory at address" Basically, the problem is right before the address esp is set to equals ebp, when in my case will be 0x90909090.. Thus, a quick solve is to not use 'A's as padding, but rather just the address in every word.

In other words, the problem was that he had overwritten some of the current function's stack frame, but hadn't overwritten the actual point on the stack where the return address was stored.

// let's say his function ended with a "return 0"...
xorl %eax, %eax
// now here is where he did the "x/8wx" debugger command...
// but then the function epilogue goes and does the usual thing:
movl  %esp, %ebp
popl  %ebp
// and so here, at the actual return, %esp no longer points
// to the same bytes he saw with "x/8wx"
ret

The linked answer suggests that his debugger might have some sort of glitch with the leave instruction (which is equivalent to the movl/popl described above), such that the debugger was telling the OP that he was stopped at the ret instruction but really the processor hadn't executed the leave yet.

Equivalently, the debugger might have an aversion to breakpointing in the middle of a function prologue or epilogue, such that if you try to set a breakpoint in the middle of the epilogue, it's secretly adjusted to the beginning of the epilogue.

Community
  • 1
  • 1
Quuxplusone
  • 23,928
  • 8
  • 94
  • 159