Closed cdelafuente-r7 closed 2 years ago
Also is this ready to be landed after it's been reviewed and tested, or is there another PR that needs to made in parallel to update MSF modules or something else along those lines?
Thanks for reviewing this PR and for your feedback @smcintyre-r7. I'll make the suggested changes as soon as possible.
Absolutely, at least one MSF module (I need to look into it closely) will need to be updated with these changes. So, this PR can be landed but a new gem should not be released until MSF is updated.
I believe I've fixed all the comments from the code review. I just left the comment about ArgumentError
open with additional information.
Thanks @smcintyre-r7 and @jmartin-r7 for the review and testing. I've pushed some fixes and improvements as suggested.
I push some fixes related to issues found in the Windows Secrets Dump
module:
referent ID
value in the NDR structures. Whereas every other Windows use 0x00020000
as an initial value and increment it by 4 (NDR 32 bit protocol) for every subsequent pointer, on Win2003, the initial value seems to be 0x00000001
and it is incremented by 1. Every Windows version earlier than Win2003 seems to accept any value anyway, but Win2003 SMB server break if the initial referent ID is not 0x00000001
.samr_enumerate_users_in_domain
was incomplete and was not handling STATUS_MORE_ENTRIES
response.I also removed openssl
dependency in ruby_smb.gemspec
and rebased to be up-to-date with master.
This PR adds new structures needed for the
Windows Secrets Dump
module future improvements. This adds support to new DCERPC structures and implements a standalone Client. This also includes a redesign of the NDR structures.Note that only partial
specs
were added to this PR. The missingspecs
will be added in a separate PR.New NDR design
The file
lib/ruby_smb/dcerpc/ndr.rb
has been heavily updated and the NDR protocol implementation has been completely redesigned to match the complexity of the newDRSR
structures. This is an attempt to match the NDR transfer syntax definition as close as possible, taking into account Microsoft additions as specified in [MS-RPCE]: Remote Procedure Call Protocol Extensions. This new implementation improves the handling of pointers and constructed types like arrays, strings and embedded structures. It also automatically handles alignment (only 32-bit NDR is supported at the moment).New DCERPC client
The new DCERPC client (
lib/ruby_smb/dcerpc/client.rb
) follows the same design as the SMB Client, except it communicates with the remote server directly over TCP (NCACN_IP_TCP
). It takes care of connecting to the correct endpoint based on theendpoint
argument, which is one of the module classes defined inlib/ruby_smb/dcerpc/
.If an already connected socket is not provided (through the
tcp_socket
argument),connect
will ask the remote Endpoint Mapper Interface which port the service is listening from. It will then connect a newTCPSocket
to this port.The client also supports authentication (NTLM only at the moment), signing and encryption. Calling
bind
will take care of binding to the remote server interface endpoint and performing authentication. With NTLM, once the three-legs authentication handshake is done, the session key is stored. This key will be used to sign the subsequent messages sent withdcerpc_request
. The authentication, signing and encryption processes are transparent and can be enabled by passing a username and password to the client and the appropriateauth_level
andauth_type
tobind
(see 2.2.1.1.8 Authentication Levels and 2.2.1.1.7 Security Providers). For now, only NTLM security provider is supported with integrity and privacy authentication levels:New structures
The partial implementations of the following DCERPC structures were added:
Endpoint Mapper Interface
File:
lib/ruby_smb/dcerpc/epm.rb
Documentation: 2.2.1.2 Endpoint Mapper Interface Extensions Related structures: EpmEptMapThis endpoint is used by the client to retrieve the port number a service is listening from.
The Directory Replication Service (DRS) Remote Protocol
File:
lib/ruby_smb/dcerpc/drsr.rb
Documentation: [MS-DRSR]: Directory Replication Service (DRS) Remote Protocol Related structures: IDL_DRSBind, IDL_DRSUnbind, IDL_DRSCrackNames, IDL_DRSDomainControllerInfo, IDL_DRSGetNCChangesThis endpoint is used to retrieve information from the Domain Controller using the Active Directory replication mechanism.
Security Account Manager (SAM) Remote Protocol
File:
lib/ruby_smb/dcerpc/samr.rb
Documentation: [MS-SAMR]: Security Account Manager (SAM) Remote Protocol (Client-to-Server) Related structures: SamrConnect, SamrCloseHandle, SamrEnumerateUsersInDomain, SamrGetAliasMembership, SamrGetGroupsForUser, SamrLookupDomainInSamServer, SamrOpenDomain, SamrOpenUser, SamrRidToSid,This endpoint is used to retrieve account and domain information on the remote host (e.g. enumerate users in a domain, get group membership for a specific user, etc.).
Workstation Service Remote Protocol
File:
lib/ruby_smb/dcerpc/wkssvc.rb
Documentation: [MS-WKST]: Workstation Service Remote Protocol Related structures: NetrWkstaGetInfoThis endpoint is used to get details about a remote computer environment, including platform-specific information, the names of the domain and local computer, and the operating system version.
Updated structures
Many existing structures were also updated to use the new NDR protocol implementation. This will potentially break existing code using the old version. In my knowledge, only the Metasploit
Windows Secrets Dump
and theNetlogon Weak Cryptographic Authentication
modules are affected and will be fixed in a separate PR. Other external projects using RubySMB DCERPC implementation will need to be reviewed and updated.Testing
The scripts in
examples/
folder can be used to test. Specifically, the following scripts were added to make sure the new structures behave as expected.SAMR module
DRSR module (this script uses the new DCERPC client)
You can get a valid
SID
using theexamples/enum_domain_users.rb
script.WKST module
SVCCTL module
Note that, when a script uses SMB as a transport layer, SMBv3 will be used by default and, therefore, the communication will be encrypted. This can be an issue if you want to capture the network packets (with Wireshark for example) for inspection. An easy way to avoid encryption is to force SMBv2. This can be done by adding
2
as the last argument of the script:An alternative would be to modify each script and set the option
always_encrypt
to false:TODO