Posted: Wed Nov 11, 2009 2:23 am Post subject: ret instruction crashing on invalid ebp
Hi,
I'm trying to write a stack-based buffer overflow on Ubuntu 9.10. I think I've managed to do everything correct, certainly I've gotten the shell code injected into the memoryspace and I have set ebp+4 to point to the start of my shell code.
I've disabled stack smashing protection, but I'm running into a really weird issue I was hoping someone could help me with:
Obviously in order to write to ebp+4, I had to corrupt ebp (so it's now 0x41414141). Everything is fine until I reach the ret instruction, when the system segfaults because address 0x41414141 obviously could not be read.
What I don't get is, why is it reading it?
This is the output of info reg:
Code:
0x80484c5 <Authenticate+113>: ret
(gdb) info reg
eax 0x0 0
ecx 0x71c4c0 7455936
edx 0x71d340 7459648
ebx 0x71bff4 7454708
esp 0xbffff43c 0xbffff43c
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x80484c5 0x80484c5 <Authenticate+113>
eflags 0x246 [ PF ZF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) nexti
Cannot access memory at address 0x41414145
Before leave: I have a valid (modified) return address at ebp+4. Valid EBP, ESP, EIP, etc.
After leave: ebp has been re-loaded from the stack, and it's the invalid data that I'm going to modify in the shellcode... Except ret gets called and is trying to offset from ebp, and I don't understand why.
Joined: 21 Sep 2003 Posts: 16777097 Location: Portugal
Posted: Wed Nov 11, 2009 2:26 pm Post subject:
It was a long night and I have no sleep on me, but let's give it a try...
Are you sure you have a valid return address at *(ebp + 4) before leave? What is the value of *esp after leave? That is, what's in the top of the stack before you execute ret?
It seems to me as though *esp == 0x41414145, and that's what ret is trying to return to. DId you perhaps set *(ebp + 4) = *ebp + 4 by mistake?
As you can see, $esp remains valid and its contents are also correct. $ebp+4 contains the address I want to jump to.
I'm seriously suspecting that the kernel is checking that ebp points to a valid memory address for security reasons, but I'm not 100% certain.
I'm on Ubuntu 9.10 with stack smashing disabled. Kernel is 2.6.31-14-generic. I've Googled ebp validation/protection/etc. but haven't come up with anything.
At any rate, my attack is definitely being done correctly because instead of overwriting it with AAAA I overwrote it with the address of my shell code (same as what I overwrote in $ebp+4) and that got past the RET instruction:
Code:
0x80484c4 <Authenticate+112>: leave
(gdb)
0x080484c5 in Authenticate (
user=0xeb80cdc9 <Address 0xeb80cdc9 out of bounds>,
pass=0xc0315b16 <Address 0xc0315b16 out of bounds>)
at ./SecureApplication.c:21
21 }
1: x/i $pc
0x80484c5 <Authenticate+113>: ret
(gdb)
0xbffff408 in ?? ()
1: x/i $pc
0xbffff408: nop
(gdb)
Program received signal SIGILL, Illegal instruction.
0xbffff408 in ?? ()
1: x/i $pc
0xbffff408: nop
(gdb)
Program terminated with signal SIGILL, Illegal instruction.
The program no longer exists.
It properly jumped to the correct location in memory (the NOP sled), but then some other protection kicked in.
Now, I'm not 100% certain, but I think it's NX that preventing it from running. Because if I replace $ebp+4 (the new return address) with the entry point of another already existing function, the attack will carry out just fine, run through that function, and only then segfault.
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum