LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (https://www.linuxquestions.org/questions/linux-security-4/)
-   -   Buffer Overflow (https://www.linuxquestions.org/questions/linux-security-4/buffer-overflow-148408/)

pymehta 02-20-2004 10:24 AM

Buffer Overflow
 
Hello!

I am using fedora core with compiler
gcc (GCC) 3.3.2 20031022 (Red Hat Linux 3.3.2-1

I am trying to write a buffer overwrite program(As my assignment). In that,
I am filling buffer with 'A's. This overflows fine, but the content of the IP register is
shown as something else then '4141414141414141' (Which is Ascii for 'A's.)
BP is showing '4141414141414141' fine.

Is this a new feature of gcc? How to circumvent it?

Thanx

cjcuk 02-21-2004 05:49 AM

You will need to give the program.

Without seeing the program it sounds like one of two possibilities:
1) the overflow is not stretching far enough along the stack - if you are trying to be precise realize that GCC 3.something added padding to the stack to prevent {one,five} byte overwrites; if you are a following some tutorial online, it might not cover this.
2) the program has not returned from the function and, thus, eip has not changed, yet.

Those are just guesses though, I would need to see the code for more of an idea.

pymehta 02-21-2004 09:00 AM

Ya, I am trying to follow online tutorial,

http://infosecwriters.com/texts.php?op=display&id=134

following is the code and trace. notice that I am overrunning by 12 bytes, and precise
overrunning is not even giving segmentation fault.

Thanks


#include <stdio.h>
int main(int argc, char **argv)
{
char buff[512];
if(argc < 2)
{
printf("Usage: %s \n", argv[0]);
exit(0);
}
strcpy(buff, argv[1]);
printf("Your name: %s\n", buff);
return 0;
}

$ /a.out `perl -e'print "A" x 524'`
Your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
$ gdb -c core.2349
GNU gdb Red Hat Linux (5.3.90-0.20030710.41rh)
...
Program terminated with signal 11, Segmentation fault.
#0 0x008e6703 in ?? ()
(gdb) info reg
eax 0xf6 246
ecx 0xa04da0 10505632
edx 0x218 536
ebx 0xa06998 10512792
esp 0xbff52920 0xbff52920
ebp 0x41414141 0x41414141
esi 0xbff529a5 -1074452059
edi 0xbff529b0 -1074452048
eip 0x8e6703 0x8e6703
eflags 0x10286 66182
cs 0x23 35

cjcuk 02-21-2004 09:46 AM

Yes, your problem is definitely to do with stack frame padding. Open up GDB and run the command `disass main', you are looking for:

Code:

(gdb) disass main
Dump of assembler code for function main:
0x08048344 <main+0>:    push  %ebp
0x08048345 <main+1>:    mov    %esp,%ebp
0x08048347 <main+3>:    sub    $0x228,%esp
0x0804834d <main+9>:    and    $0xfffffff0,%esp

This is the main function setting up it's stack frame, above the stack frame of it's parent. You will notice that on my system GCC-3.3.1 has created a stack frame that is 552 bytes. You need to take this into account.

As you can see you have managed to overwrite the saved %ebp value, but have not reached %eip. Here is the output for you of two invocations:

Code:

(gdb) r `perl -e 'print "A" x 524'`
[ ... ]
Program received signal SIGSEGV, Segmentation fault.
0x4002e915 in __libc_start_main () from /lib/libc.so.6
(gdb) info reg
[ ... ]
esp            0xbffff490      0xbffff490
ebp            0x41414141      0x41414141
[ ... ]
eip            0x4002e915      0x4002e915

Code:

(gdb) r `perl -e 'print "A" x 552'`
[ ... ]
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg
[ ... ]
esp            0xbfffe960      0xbfffe960
ebp            0x41414141      0x41414141
[ ... ]
eip            0x41414141      0x41414141

The general lesson to learn from this is to always review what the compiler has created. It is very difficult to understand this properly without some base understanding of how memory works and assembly code (you do not need to be able to write it, but approximate reading of it is useful). The other thing is, when you are looking to overwrite the %eip via a simple technique such as this then you should open up the calling function and find the `return location' (as in, what value the saved %eip will contain). Using this `return location' you can take a view of memory and find the exact address that the system intends to pop back into the instruction pointer. From there it is simple to work out how much you need to write. I took a glance at the tutorial you are studying, and it does not seem to cover scenarios such as this -- you should maybe look for a more general tutorial, one without the assumptions made.

pymehta 02-21-2004 10:40 AM


Thanx for help.
However, There are two main differences in my trace. First, the stack frame is of 520 bytes.

(gdb) disas main
Dump of assembler code for function main:
0x080483b0 <main+0>: push %ebp
0x080483b1 <main+1>: mov %esp,%ebp
0x080483b3 <main+3>: sub $0x208,%esp
0x080483b9 <main+9>: and $0xfffffff0,%esp

Second, I have tried overrunning by different margins, small and large, but it gives the same result.

(gdb) r `perl -e'print "A" x 600'`
...
Your name: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
0x0804841f in main (argc=Cannot access memory at address 0x41414149
) at begtut.c:13
13 }

(gdb) info reg
eax 0x0 0
ecx 0xa04da0 10505632
edx 0x264 612
ebx 0xa06998 10512792
esp 0xbfe8df2c 0xbfe8df2c
ebp 0x41414141 0x41414141
esi 0xbfe8dfb4 -1075257420
edi 0xbfe8dfc0 -1075257408
eip 0x804841f 0x804841f
eflags 0x10282 66178
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x33 51
(gdb)


cjcuk 02-21-2004 12:05 PM

Okay, here is something simple to try. All of this is not necessary, but it should make it easy to highlight where the issue lies. Grab yourself a breakpoint just after the strcpy call:

Code:

(gdb) disas main
[ ... ]
0x080483f3 <main+79>:  call  0x80482d0
0x080483f8 <main+84>:  [ ... ]
[ ... ]
(gdb) break *0x080483f8
Breakpoint 1 at 0x80483f8

Run the program filling the buffer perfectly (ie, 512 x `A'). After it breaks get the value of %ebp:

Code:

(gdb) r `perl -e 'print "A" x 512'`
[ ... ]
Breakpoint 1, 0x080483f8 in main ()
(gdb) info reg $ebp
ebp            0xbfffe588      0xbfffe588

Note that down, and then we will view a chunk of memory, with %ebp sitting in the middle:

Code:

(gdb) x/28x $ebp-48
0xbfffe558:    0x41414141      0x41414141      0x41414141      0x41414141
0xbfffe568:    0x41414141      0x41414141      0x41414141      0x41414141
0xbfffe578:    0x41414141      0x41414141      0x40145800      0x40015060
0xbfffe588:    0xbfffe5a8      0x4002e91e      0x00000002      0xbfffe5d4
0xbfffe598:    0xbfffe5e0      0x400154f0      0x00000002      0x080482e0
0xbfffe5a8:    0x00000000      0x08048301      0x080483a4      0x00000002
0xbfffe5b8:    0xbfffe5d4      0x08048420      0x08048450      0x4000b250

Now, you can see the approaching army of A's headed for %ebp. The address that you are after is %ebp+4 (0x4002e91e in my case).

I hope I have kept that as clear as possible.

320mb 02-21-2004 12:12 PM

Have you read....."Smashing the stack for fun and profit"??
do a google.......it should help in your understanding of the Stack overflow.

pymehta 02-24-2004 01:19 PM

Well,

I completed writing program and it turned out that it works fine when I compile it on RH7 and RH9.0 and then run on my machine. When I execute a buffer exploit compiled on my machine, It breaks on the ret instruction.

This makes me guess, that there is indeed some new trick in the GCC that shipped with fedora core.

Thanx for replies.


All times are GMT -5. The time now is 09:14 PM.