4

I am working on ubuntu 12.04 and 64 bit machine. I was reading a good book on buffer overflows and while playing with one example found one strange moment.

I have this really simple C code:

 void getInput (void){ 
    char array[8];    
    gets (array); 
    printf("%s\n", array); 

 }   
 main() { 
    getInput();    
    return 0;    
 }

in the file overflow.c

I compile it with 32 bit flag cause all example in the book assumed 32 bit machine, I do it like this

 gcc -fno-stack-protector -g -m32 -o ./overflow ./overflow.c

In the code char array was only 8 bytes but looking at disassembly I found that that array starts 16 bytes away from saved EBP on the stack, so I executed this line:

 printf "aaaaaaaaaaaaaaaaaaaa\x10\x10\x10\x20" | ./overflow

And got:

 aaaaaaaaaaaaaaaaaaaa 
 Segmentation fault (core dumped)

Then I opened core file:

 gdb ./overflow core
 #0  0x20101010 in ?? ()
 (gdb) info registers
 eax            0x19    25
 ecx            0xffffffff  -1
 edx            0xf77118b8  -143583048
 ebx            0xf770fff4  -143589388
 esp            0xffef6370  0xffef6370
 ebp            0x61616161  0x61616161
 esi            0x0 0
 edi            0x0 0
 eip            0x20101010  0x20101010

As you see EIP in fact got new value, which I wanted. BUT when I want to put some useful values like this 0x08048410

 printf "aaaaaaaaaaaaaaaaaaaa\x10\x84\x04\x08" | ./overflow

Program crashes as usual but than something strange happens when I'm trying to observe the value in EIP register:

 #0  0xf765be1f in ?? () from /lib/i386-linux-gnu/libc.so.6
 (gdb) info registers
 eax            0x61616151  1633771857
 ecx            0xf77828c4  -143120188
 edx            0x1 1
 ebx            0xf7780ff4  -143126540
 esp            0xff92dffc  0xff92dffc
 ebp            0x61616161  0x61616161
 esi            0x0 0
 edi            0x0 0
 eip            0xf765be1f  0xf765be1f

Suddenly EIP start to look like this 0xf765be1f, it doesn't look like 0x08048410. In fact I noticed that it's enough to put any hexadecimal value starting from 0 to get this crumbled EIP value. Do you know why this might happen? Is it because I'm on 64 bit machine?

UPD

Well guys in comments asked for more information, here is the disassembly of getInput function:

 (gdb) disas getInput
 Dump of assembler code for function getInput:
    0x08048404 <+0>:    push   %ebp
    0x08048405 <+1>:    mov    %esp,%ebp
    0x08048407 <+3>:    sub    $0x28,%esp
    0x0804840a <+6>:    lea    -0x10(%ebp),%eax
    0x0804840d <+9>:    mov    %eax,(%esp)
    0x08048410 <+12>:   call   0x8048310 <gets@plt>
    0x08048415 <+17>:   lea    -0x10(%ebp),%eax
    0x08048418 <+20>:   mov    %eax,(%esp)
    0x0804841b <+23>:   call   0x8048320 <puts@plt>
    0x08048420 <+28>:   leave  
    0x08048421 <+29>:   ret 

3 Answers 3

3

Perhaps code at 0x08048410 was executed, and jumped to the area of 0xf765be1f.

What's in this address? I guess it's a function (libC?), so you can examine its assembly code and see what it would do.

Also note that in the successful run, you managed to overrun EBP, not EIP. EBP contains 0x61616161, which is aaaa, and EIP contains 0x20101010, which is \n\n\n. It seems like the corrupt EBP indirectly got EIP corrupt.
Try to make the overrun 4 bytes longer, and then it should overrun the return address too.

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

7 Comments

Doesn't sound very convincing. How did 0xf765be1f get to EIP anyway? Was there a RET? Anyway, this needs more detailed debugging.
@m0skit0, Once you start corrupting the stack and executing wild addresses, things are very unpredictable. Code at 0x08048410 probably doesn't simply jump to 0xf765be1f, but it might return, as you suggest, or call a function by register.
Well the address 0x08048410 is just the address of the call to gets function inside getInput function, I was just trying to call that function again, which is pretty conclusive evidence that I redirected the flow of the program
I do believe that in both cases both EBP and EIP registers were overwritten correctly, for example when I put a value \x10\x10\x10\x20 at the end of that aaaa string, eip becomes 0x20101010, and if I will change it to \x10\x84\x04\x20" which is almost correct address except last hex value I still get correct representation in EIP - 0x20048410, BUT if I change it to \x10\x84\x04\x08, which is correct valid address of the call to gets function I end up with 0xf75a6e1f in my EIP
That's it I just changed \x20 to \x08 and that was enough to get mumbo-jumbo in EIP
|
1

This is probably due to the fact that modern OS (Linux does at least, I don't know about Windows) and modern libc have mechanisms that do not allow code found in stack to be executed.

2 Comments

Well, it doesn't explain why the first value \x10\x10\x10\x20 was written correctly to the EIP register, while \x10\x84\x04\x08 turned into a mess.
Well it does indeed: in the first example, you weren't trying to jump to a valid address, while in the second you do.
0

Buffer overflow is invoking undefined behavior, therefore anything can happen. Theorizing what might happen is futile.

2 Comments

Well, it doesn't explain why the first value \x10\x10\x10\x20 was written correctly to the EIP register, while \x10\x84\x04\x08 turned into a mess
@RustamIssabekov This might explain why it happened. Here you might find some of exotic stack smashes.

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.