Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor smb lookupsid module #19170

Merged
merged 5 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ GEM
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.5)
ruby_smb (3.3.7)
ruby_smb (3.3.8)
bindata (= 2.4.15)
openssl-ccm
openssl-cmac
Expand Down
2 changes: 1 addition & 1 deletion LICENSE_GEMS
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ ruby-prof, 1.4.2, "Simplified BSD"
ruby-progressbar, 1.13.0, MIT
ruby-rc4, 0.1.5, MIT
ruby2_keywords, 0.0.5, "ruby, Simplified BSD"
ruby_smb, 3.3.7, "New BSD"
ruby_smb, 3.3.8, "New BSD"
rubyntlm, 0.6.3, MIT
rubyzip, 2.3.2, "Simplified BSD"
sawyer, 0.9.2, MIT
Expand Down
24 changes: 1 addition & 23 deletions lib/msf/core/exploit/remote/ms_icpr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ module Msf

module Exploit::Remote::MsIcpr

include Msf::Exploit::Remote::SMB::Client::Authenticated
include Msf::Exploit::Remote::SMB::Client::Ipc
include Msf::Exploit::Remote::DCERPC
include Msf::Auxiliary::Report

# [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)
OID_NTDS_CA_SECURITY_EXT = '1.3.6.1.4.1.311.25.2'.freeze
Expand Down Expand Up @@ -109,27 +108,6 @@ def request_certificate(opts = {})

module_function

def connect_ipc
begin
connect
rescue Rex::ConnectionError => e
raise MsIcprConnectionError, e.message
end

begin
smb_login
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
raise MsIcprAuthenticationError, "Unable to authenticate ([#{e.class}] #{e})."
end
report_service(icpr_service_data)

begin
simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")
rescue RubySMB::Error::RubySMBError => e
raise MsIcprConnectionError, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e})."
end
end

def connect_icpr(tree)
vprint_status('Connecting to ICertPassage (ICPR) Remote Protocol')
icpr = tree.open_file(filename: 'cert', write: true, read: true)
Expand Down
112 changes: 112 additions & 0 deletions lib/msf/core/exploit/remote/ms_lsad.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
###
#
# This mixin provides methods to open, and close policy handles, and to query policy info on the remote SMB server.
#
# -*- coding: binary -*-

module Msf

module Exploit::Remote::MsLsad

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

class MsLsadError < StandardError; end
class MsLsadConnectionError < MsLsadError; end
class MsLsadAuthenticationError < MsLsadError; end
class MsLsadUnexpectedReplyError < MsLsadError; end

LSA_UUID = '12345778-1234-abcd-ef00-0123456789ab'.freeze
LSA_VERS = '0.0'.freeze
LSARPC_ENDPOINT = RubySMB::Dcerpc::Lsarpc.freeze

# The currently connected LSARPC pipe
attr_reader :lsarpc_pipe

def map_security_principal_to_string(security_principal)
case security_principal
when 1
'User'
when 2
'Group'
when 3
'Domain'
when 4
'Alias'
when 5
'Well-Known Group'
when 6
'Deleted Account'
when 7
'Invalid'
when 8
'Unknown'
when '9'
'Computer'
when 10
'Label'
else
'Unknown - Not a valid Security Principal'
end
end

def open_policy2(impersonation_level, security_context_tracking_mode, access_mask)
self.lsarpc_pipe.lsar_open_policy2(
system_name: simple.peerhost,
object_attributes: {
security_quality_of_service: {
impersonation_level: impersonation_level,
security_context_tracking_mode: security_context_tracking_mode
}
},
access_mask: access_mask
)
end

def query_information_policy(policy_handle, information_class)
self.lsarpc_pipe.lsar_query_information_policy(
policy_handle: policy_handle,
information_class: information_class
)
end

def close_policy(policy_handle)
self.lsarpc_pipe.lsar_close_handle(
policy_handle: policy_handle
) if (self.lsarpc_pipe && policy_handle)
end

def disconnect_lsarpc
begin
self.lsarpc_pipe.close if self.lsarpc_pipe&.is_connected?
rescue RubySMB::Error::UnexpectedStatusCode, RubySMB::Error::CommunicationError => e
wlog e
end
end

module_function

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

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

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

self.lsarpc_pipe
rescue RubySMB::Dcerpc::Error::FaultError => e
elog(e.message, error: e)
raise MsLsadUnexpectedReplyError, "Connection failed (DCERPC fault: #{e.status_name})"
end
end

protected

attr_writer :lsarpc_pipe

end

end
22 changes: 22 additions & 0 deletions lib/msf/core/exploit/remote/ms_lsat.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
###
#
# This mixin provides methods to look-up security identifiers on the remote SMB server.
#
# -*- coding: binary -*-

module Msf

module Exploit::Remote::MsLsat

def lookup_sids(policy_handle, sids, lookup_level)
sids = [sids] unless sids.is_a?(Array)

self.lsarpc_pipe.lsar_lookup_sids(
policy_handle: policy_handle,
sids: sids,
lookup_level: lookup_level
)
end

end
end
30 changes: 1 addition & 29 deletions 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::SMB::Client::Authenticated
include Msf::Exploit::Remote::SMB::Client::Ipc

class MsSamrError < StandardError; end
class MsSamrConnectionError < MsSamrError; end
Expand All @@ -22,34 +22,6 @@ class MsSamrBadConfigError < MsSamrError; end

module_function

def connect_ipc
begin
connect
rescue Rex::ConnectionError => e
raise MsSamrConnectionError, e.message
end

begin
smb_login
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
raise MsSamrAuthenticationError, "Unable to authenticate ([#{e.class}] #{e})."
end
report_service(
host: rhost,
port: rport,
host_name: simple.client.default_name,
proto: 'tcp',
name: 'smb',
info: "Module: #{fullname}, last negotiated version: SMBv#{simple.client.negotiated_smb_version} (dialect = #{simple.client.dialect})"
)

begin
simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")
rescue RubySMB::Error::RubySMBError => e
raise MsSamrConnectionError, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e})."
end
end

def connect_samr(tree)
begin
vprint_status('Connecting to Security Account Manager (SAM) Remote Protocol')
Expand Down
4 changes: 2 additions & 2 deletions lib/msf/core/exploit/remote/smb/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ def smb_login(simple_client = self.simple)
datastore['NTLM::SendNTLM'],
datastore['SMB::Native_OS'],
datastore['SMB::Native_LM'],
{:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost}
{ :use_spn => datastore['NTLM::SendSPN'], :name => simple_client.peerhost }
)
# XXX: Any reason to connect to the IPC$ share in this method?
simple_client.connect("\\\\#{datastore['RHOST']}\\IPC$")
simple_client.client.tree_connect("\\\\#{simple_client.peerhost}\\IPC$")
end

# This method returns the native operating system of the peer
Expand Down
54 changes: 54 additions & 0 deletions lib/msf/core/exploit/remote/smb/client/ipc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
###
#
# This mixin provides a method to connect to an IPC share on the remote SMB server.
#
# -*- coding: binary -*-

module Msf

module Exploit::Remote::SMB::Client::Ipc

include Msf::Exploit::Remote::SMB::Client::Authenticated
include Msf::Auxiliary::Report

class SmbIpcError < StandardError; end
class SmbIpcConnectionError < SmbIpcError; end
class SmbIpcAuthenticationError < SmbIpcError; end

module_function

def connect_ipc
begin
if session
self.simple = session.simple_client
ipc_tree = simple.client.tree_connect("\\\\#{simple.peerhost}\\IPC$")
else
connect
# smb_login does a tree_connect to the IPC share already.
ipc_tree = smb_login
end
rescue Rex::ConnectionError => e
raise SmbIpcConnectionError, e.message
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
raise SmbIpcAuthenticationError, "Unable to authenticate ([#{e.class}] #{e})."
end

report_service(
host: simple.peerhost,
port: simple.peerport,
host_name: simple.client.default_name,
proto: 'tcp',
name: 'smb',
info: "Module: #{fullname}, last negotiated version: SMBv#{simple.client.negotiated_smb_version} (dialect = #{simple.client.dialect})"
)

ipc_tree
end

def disconnect_ipc(ipc_tree)
ipc_tree.disconnect! if ipc_tree
end

end

end
Loading