Skip to content

Commit

Permalink
Add smb session support to scanner modules
Browse files Browse the repository at this point in the history
  • Loading branch information
dwelch-r7 committed Dec 5, 2023
1 parent f38be9c commit 34b24cd
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 366 deletions.
1 change: 1 addition & 0 deletions lib/msf/core/optional_session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def initialize(info = {})

def session
return nil unless framework.features.enabled?(Msf::FeatureManager::SMB_SESSION_TYPE)

super
end
end
47 changes: 31 additions & 16 deletions modules/auxiliary/scanner/smb/pipe_auditor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report

include Msf::OptionalSession

def initialize
super(
'Name' => 'SMB Session Pipe Auditor',
'Description' => 'Determine what named pipes are accessible over SMB',
'Author' => 'hdm',
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'SessionTypes' => %w[SMB]
)

deregister_options('RPORT', 'SMBDirect')
Expand All @@ -30,26 +33,32 @@ def run_host(ip)

pipes = []

[[139, false], [445, true]].each do |info|
if session
print_status("Using existing session #{session.sid}")
client = session.client
datastore['RPORT'] = session.port
self.simple = ::Rex::Proto::SMB::SimpleClient.new(client.dispatcher.tcp_socket, client: client)
self.simple.connect("\\\\#{session.address}\\IPC$")
pipes += check_pipes
else
[[139, false], [445, true]].each do |info|

datastore['RPORT'] = info[0]
datastore['SMBDirect'] = info[1]
datastore['RPORT'] = info[0]
datastore['SMBDirect'] = info[1]

begin
connect
smb_login()
check_named_pipes.each do |pipe_name, _|
pipes.push(pipe_name)
begin
connect
smb_login
pipes += check_pipes
disconnect
break
rescue Rex::Proto::SMB::Exceptions::SimpleClientError, Rex::ConnectionError => e
vprint_error("SMB client Error with RPORT=#{info[0]} SMBDirect=#{info[1]}: #{e.to_s}")
end

disconnect()

break
rescue Rex::Proto::SMB::Exceptions::SimpleClientError, Rex::ConnectionError => e
vprint_error("SMB client Error with RPORT=#{info[0]} SMBDirect=#{info[1]}: #{e.to_s}")
end
end


if(pipes.length > 0)
print_good("Pipes: #{pipes.join(", ")}")
# Add Report
Expand All @@ -64,5 +73,11 @@ def run_host(ip)
end
end


def check_pipes
pipes = []
check_named_pipes.each do |pipe_name, _|
pipes.push(pipe_name)
end
pipes
end
end
80 changes: 46 additions & 34 deletions modules/auxiliary/scanner/smb/pipe_dcerpc_auditor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report

include Msf::OptionalSession

def initialize
super(
'Name' => 'SMB Session Pipe DCERPC Auditor',
'Description' => 'Determine what DCERPC services are accessible over a SMB pipe',
'Author' => 'hdm',
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'SessionTypes' => %w[SMB]
)

deregister_options('RPORT')
Expand Down Expand Up @@ -251,48 +254,57 @@ def initialize

# Fingerprint a single host
def run_host(ip)
ports = [139, 445]

[[139, false], [445, true]].each do |info|

datastore['RPORT'] = info[0]
datastore['SMBDirect'] = info[1]
if session
print_status("Using existing session #{session.sid}")
client = session.client
self.simple = ::Rex::Proto::SMB::SimpleClient.new(client.dispatcher.tcp_socket, client: client)
ports = [simple.port]
self.simple.connect("\\\\#{simple.address}\\IPC$") # smb_login connects to this share for some reason and it doesn't work unless we do too
end

begin
connect()
smb_login()
ports.each do |port|
datastore['RPORT'] = port

@@target_uuids.each do |uuid|
begin
unless session
connect()
smb_login()
end

handle = dcerpc_handle(
uuid[0], uuid[1],
'ncacn_np', ["\\#{datastore['SMBPIPE']}"]
)
@@target_uuids.each do |uuid|

begin
dcerpc_bind(handle)
print_line("UUID #{uuid[0]} #{uuid[1]} OPEN VIA #{datastore['SMBPIPE']}")
# Add Report
report_note(
:host => ip,
:proto => 'tcp',
:sname => 'smb',
:port => rport,
:type => "UUID #{uuid[0]} #{uuid[1]}",
:data => "UUID #{uuid[0]} #{uuid[1]} OPEN VIA #{datastore['SMBPIPE']}"
handle = dcerpc_handle_target(
uuid[0], uuid[1],
'ncacn_np', ["\\#{datastore['SMBPIPE']}"], self.simple.address
)
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
#print_line("UUID #{uuid[0]} #{uuid[1]} ERROR 0x%.8x" % e.error_code)
rescue ::Exception => e
#print_line("UUID #{uuid[0]} #{uuid[1]} ERROR #{$!}")

begin
dcerpc_bind(handle)
print_line("UUID #{uuid[0]} #{uuid[1]} OPEN VIA #{datastore['SMBPIPE']}")
# Add Report
report_note(
:host => ip,
:proto => 'tcp',
:sname => 'smb',
:port => rport,
:type => "UUID #{uuid[0]} #{uuid[1]}",
:data => "UUID #{uuid[0]} #{uuid[1]} OPEN VIA #{datastore['SMBPIPE']}"
)
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
print_line("UUID #{uuid[0]} #{uuid[1]} ERROR 0x%.8x" % e.error_code)
rescue StandardError => e
print_line("UUID #{uuid[0]} #{uuid[1]} ERROR #{$!}")
end
end
end

disconnect()
disconnect()

return
rescue ::Exception
print_line($!.to_s)
end
return
rescue ::Exception
print_line($!.to_s)
end
end
end

Expand Down
25 changes: 17 additions & 8 deletions modules/auxiliary/scanner/smb/smb_enum_gpp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::SMB::Client::Authenticated
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
include Msf::OptionalSession

# Aliases for common classes
SIMPLE = Rex::Proto::SMB::Client
Expand Down Expand Up @@ -36,7 +37,8 @@ def initialize
['URL', 'http://blogs.technet.com/grouppolicy/archive/2009/04/22/passwords-in-group-policy-preferences-updated.aspx'],
['URL', 'https://labs.portcullis.co.uk/blog/are-you-considering-using-microsoft-group-policy-preferences-think-again/']
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'SessionTypes' => %w[SMB]
)
register_options([
OptString.new('SMBSHARE', [true, 'The name of the share on the server', 'SYSVOL']),
Expand Down Expand Up @@ -164,10 +166,17 @@ def smb_download(ip, fd, path)
def run_host(ip)
print_status('Connecting to the server...')
begin
connect
smb_login
print_status("Mounting the remote share \\\\#{ip}\\#{datastore['SMBSHARE']}'...")
tree = simple.client.tree_connect("\\\\#{ip}\\#{datastore['SMBSHARE']}")
if session
print_status("Using existing session #{session.sid}")
client = session.client
self.simple = ::Rex::Proto::SMB::SimpleClient.new(client.dispatcher.tcp_socket, client: client)
else
connect
smb_login
end

print_status("Mounting the remote share \\\\#{simple.address}\\#{datastore['SMBSHARE']}'...")
tree = simple.client.tree_connect("\\\\#{simple.address}\\#{datastore['SMBSHARE']}")

corp_domain = tree.list.map { |entry| entry.file_name.value.to_s.encode }.detect { |entry| entry != '.' && entry != '..' }
fail_with(Failure::NotFound, 'Could not find the domain folder') if corp_domain.nil?
Expand All @@ -188,12 +197,12 @@ def run_host(ip)
sub_folders.each do |sub_folder|
next if sub_folder == '.' || sub_folder == '..'
gpp_locations.each do |gpp_l|
check_path(ip,"#{corp_domain}\\Policies\\#{sub_folder}\\#{gpp_l}")
check_path(simple.address,"#{corp_domain}\\Policies\\#{sub_folder}\\#{gpp_l}")
end
end
rescue ::Exception => e
print_error("#{rhost}: #{e.class} #{e}")
ensure
print_error("#{simple.address}: #{e.class} #{e}")
u ensure
disconnect
end
end
Expand Down
Loading

0 comments on commit 34b24cd

Please sign in to comment.