147 lines
3.9 KiB
Ruby
147 lines
3.9 KiB
Ruby
#
|
|
# $Id$
|
|
# $Revision$
|
|
#
|
|
|
|
module Msf
|
|
class Plugin::TokenHunter < Msf::Plugin
|
|
|
|
class TokenCommandDispatcher
|
|
include Msf::Ui::Console::CommandDispatcher
|
|
|
|
def name
|
|
'Token Hunter'
|
|
end
|
|
|
|
def commands
|
|
{
|
|
'token_hunt_user' => 'Scan all connected Meterpreter sessions for active tokens corresponding to one or more users'
|
|
}
|
|
end
|
|
|
|
def cmd_token_hunt_user(*args)
|
|
opts = Rex::Parser::Arguments.new(
|
|
'-h' => [ false, 'This help menu'],
|
|
'-f' => [ true, 'A file containing a list of users to search for (one per line)']
|
|
)
|
|
|
|
opt_userfile = nil
|
|
opt_users = []
|
|
|
|
opts.parse(args) do |opt, _idx, val|
|
|
case opt
|
|
when '-h'
|
|
print_line('Usage: token_hunt_user [options] <username> [username] .. [username]')
|
|
print_line(opts.usage)
|
|
return
|
|
when '-f'
|
|
opt_userfile = val
|
|
else
|
|
opt_users << val
|
|
end
|
|
end
|
|
|
|
if opt_userfile
|
|
::File.open(opt_userfile, 'rb') do |fd|
|
|
fd.each_line do |line|
|
|
line.strip!
|
|
next if line.empty?
|
|
next if line =~ /^#/
|
|
|
|
opt_users << line
|
|
end
|
|
end
|
|
end
|
|
|
|
opt_users.uniq!
|
|
|
|
tokens_del = {}
|
|
tokens_imp = {}
|
|
|
|
framework.sessions.each_key do |sid|
|
|
session = framework.sessions[sid]
|
|
next if session.type != 'meterpreter'
|
|
|
|
print_status(">> Scanning session #{session.sid} / #{session.session_host}")
|
|
|
|
if !session.incognito
|
|
session.core.use('incognito')
|
|
end
|
|
|
|
if !session.incognito
|
|
print_status("!! Failed to load incognito on #{session.sid} / #{session.session_host}")
|
|
next
|
|
end
|
|
|
|
res = session.incognito.incognito_list_tokens(0)
|
|
next unless res
|
|
|
|
res['delegation'].split("\n").each do |user|
|
|
opt_users.each do |needle|
|
|
ndom, nusr = needle.split('\\')
|
|
if !nusr
|
|
nusr = ndom
|
|
ndom = nil
|
|
end
|
|
|
|
if (!user.nil? && ndom && (user.strip.downcase == needle.strip.downcase))
|
|
print_status("FOUND: #{session.sid} - #{session.session_host} - #{user} (delegation)")
|
|
next
|
|
end
|
|
|
|
_fdom, fusr = user.split('\\')
|
|
|
|
if (!fusr.nil? && !ndom && (fusr.strip.downcase == nusr.strip.downcase))
|
|
print_status("FOUND: #{session.sid} - #{session.session_host} - #{user} (delegation)")
|
|
end
|
|
end
|
|
|
|
tokens_del[user] ||= []
|
|
tokens_del[user] << session.sid
|
|
end
|
|
|
|
res['impersonation'].split("\n").each do |user|
|
|
opt_users.each do |needle|
|
|
ndom, nusr = needle.split('\\')
|
|
if !nusr
|
|
nusr = ndom
|
|
ndom = nil
|
|
end
|
|
|
|
if (!user.nil? && ndom && (user.strip.downcase == needle.strip.downcase))
|
|
print_status(">> Found #{session.sid} - #{session.session_host} - #{user} (impersonation)")
|
|
next
|
|
end
|
|
|
|
_fdom, fusr = user.split('\\')
|
|
if (!fusr.nil? && !ndom && (fusr.strip.downcase == nusr.strip.downcase))
|
|
print_status(">> Found #{session.sid} - #{session.session_host} - #{user} (impersonation)")
|
|
end
|
|
end
|
|
|
|
tokens_imp[user] ||= []
|
|
tokens_imp[user] << session.sid
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def initialize(framework, opts)
|
|
super
|
|
add_console_dispatcher(TokenCommandDispatcher)
|
|
end
|
|
|
|
def cleanup
|
|
remove_console_dispatcher('Token Hunter')
|
|
end
|
|
|
|
def name
|
|
'token_hunter'
|
|
end
|
|
|
|
def desc
|
|
'Search all active Meterpreter sessions for specific tokens'
|
|
end
|
|
end
|
|
end
|