Skip to content

Commit

Permalink
Add support for configurable RPORT, session & default rports to looku…
Browse files Browse the repository at this point in the history
…psid
  • Loading branch information
sjanusz-r7 committed May 14, 2024
1 parent 75b8455 commit 6911c35
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 38 deletions.
2 changes: 1 addition & 1 deletion lib/msf/core/exploit/remote/ms_icpr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Msf

module Exploit::Remote::MsIcpr

include Msf::Exploit::Remote::MsIpc
include Msf::Exploit::Remote::SMB::Client::Ipc
include Msf::Exploit::Remote::DCERPC

# [2.2.2.7.7.4 szOID_NTDS_CA_SECURITY_EXT](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/e563cff8-1af6-4e6f-a655-7571ca482e71)
Expand Down
14 changes: 6 additions & 8 deletions lib/msf/core/exploit/remote/ms_lsarpc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def close_policy(policy_handle)
def disconnect_lsarpc
begin
self.lsarpc_pipe.close if self.lsarpc_pipe&.is_connected?
rescue RubySMB::Error::UnexpectedStatusCode => e
rescue RubySMB::Error::UnexpectedStatusCode, RubySMB::Error::CommunicationError => e
wlog e
end
end
Expand All @@ -97,16 +97,14 @@ def disconnect_lsarpc

def connect_lsarpc(tree)
begin
vprint_status('Connecting to LSARPC')
self.lsarpc_pipe = tree.open_file(filename: 'LSARPC', write: true, read: true)
vprint_status('Connecting to Local Security Authority Remote Protocol')
self.lsarpc_pipe = tree.open_file(filename: 'lsarpc', write: true, read: true)

raise MsLsarpcConnectionError.new('Could not open LSARPC pipe on remote SMB server.') unless lsarpc_pipe
raise MsLsarpcConnectionError.new('Could not open lsarpc pipe on remote SMB server.') unless lsarpc_pipe

self.lsarpc_pipe.extend(LSARPC_ENDPOINT) unless lsarpc_pipe.is_a?(LSARPC_ENDPOINT)

vprint_status('Binding to \\LSARPC...')
vprint_status('Binding to \\lsarpc...')
self.lsarpc_pipe.bind(endpoint: LSARPC_ENDPOINT)
vprint_good('Bound to \\LSARPC')
vprint_good('Bound to \\lsarpc')

self.lsarpc_pipe
rescue RubySMB::Dcerpc::Error::FaultError => e
Expand Down
2 changes: 1 addition & 1 deletion lib/msf/core/exploit/remote/ms_samr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module Msf

module Exploit::Remote::MsSamr

include Msf::Exploit::Remote::MsIpc
include Msf::Exploit::Remote::SMB::Client::Ipc

class MsSamrError < StandardError; end
class MsSamrConnectionError < MsSamrError; end
Expand Down
117 changes: 90 additions & 27 deletions modules/auxiliary/scanner/smb/smb_lookupsid.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,41 @@ def initialize
)
end

# Fingerprint a single host
def run_host(ip)
sids_table = Rex::Text::Table.new(
'Indent' => 4,
'Header' => "SMB Lookup SIDs Output",
'Columns' =>
[
'Type',
'Name',
'RID'
],
'SortIndex' => 2, # Sort by RID
)
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)
Expand Down Expand Up @@ -95,29 +117,31 @@ def run_host(ip)
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
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|
sids_table << [ map_security_principal_to_string(sid[:type]), sid[:name], rid ]
output << [ map_security_principal_to_string(sid[:type]), sid[:name], rid ]
end
rescue RubySMB::Dcerpc::Error::LsarpcError => e
# Ignore unmapped RIDs
Expand All @@ -127,9 +151,11 @@ def run_host(ip)
end
end

print_line
print_status sids_table.to_s
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}")
Expand All @@ -138,4 +164,41 @@ def run_host(ip)
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
2 changes: 1 addition & 1 deletion spec/acceptance/smb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
lines: {
all: {
required: [
"PIPE(LSARPC) LOCAL",
"PIPE(lsarpc) LOCAL",
/User( *)(Administrator|nobody)/,
/Group( *)(None|Domain (Admins|Users|Guests|Computers))/,
],
Expand Down

0 comments on commit 6911c35

Please sign in to comment.