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

Note when SMBv1 is supported to the user #19131

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

nrathaus
Copy link
Contributor

This improves the feedback listed here: #17402

Verification

List the steps needed to make sure this thing works

  • Run using docker-compose up, SMBv1 supported server, and SMBv1 not supported and see difference in outcome
  • Start msfconsole
  • use smb_version
  • run 172.24.0.2

docker-compose with SMBv1:

version: "3"

services:
  sambav1:
    image: dperson/samba:latest
    container_name: samba
    restart: unless-stopped
    command: '-g "ntlm auth = yes" -g "server min protocol = NT1" -S -s "Files;/mnt/files;yes;yes"'
    ports:
      - 139:139
      - 445:445
    environment:
      - TZ=PST8PDT
    volumes:
      - files:/mnt/files

volumes:
  files:

docker-compose without SMBv1:

version: "3"

services:
  sambav1:
    image: dperson/samba:latest
    container_name: samba
    restart: unless-stopped
    command: '-s "Files;/mnt/files;yes;yes"'
    ports:
      - 139:139
      - 445:445
    environment:
      - TZ=PST8PDT
    volumes:
      - files:/mnt/files

volumes:
  files:

Comment on lines 202 to 205
desc = "SMB Detected (versions:#{info[:versions].join(', ')}) (preferred dialect:#{info[:preferred_dialect]})"
if info[:versions].include?(1)
desc << ' (SMBv1: true)'
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be covered on the previous line where (version: includes 1? This seems redundant. I would expect a server that supports SMBv1 to show (versions:1) or (versions:1,2), etc.

@smcintyre-r7 smcintyre-r7 self-assigned this Apr 24, 2024
@nrathaus
Copy link
Contributor Author

nrathaus commented Apr 24, 2024 via email

@smcintyre-r7
Copy link
Contributor

I think that issue was to say that the host operating system information isn't extracted from the NTLM challenge/response when SMBv1 isn't in use. I think we could address it, though it may require an update to RubySMB if the NTLM challenge/response, isn't readily accessible.

I could probably help if you were interested in working on that.

@adfoster-r7
Copy link
Contributor

I think that issue was to say that the host operating system information isn't extracted from the NTLM challenge/response when SMBv1 isn't in use.

Yip; it looks like from the original ticket I was hoping that the host information was extracted from the NTLMSSP_CHALLENGE response:

I would have expected the Windows 10.0 Build 14393 metadata to be present
I think the information should be extractable from the STATUS_MORE_PROCESSING_REQUIRED, NTLMSSP_CHALLENGE response

Sorry for the confusion in the original ticket

@nrathaus
Copy link
Contributor Author

nrathaus commented Apr 24, 2024 via email

@adfoster-r7
Copy link
Contributor

Requirements for completing the task would be extracting extra details from the NTLM negotiation and showing it to the user, i.e the mockup:

- [*] 192.168.123.13:445    - SMB Detected (versions:2, 3) (preferred dialect:SMB 3.1.1) (compression capabilities:) (encryption capabilities:AES-128-GCM) (signatures:required) (uptime:3m 46s) (guid:{3863d7d4-26ca-4913-8ff3-d4e27787e43d}) (authentication domain:ADF3)
+ [*] 192.168.123.13:445    - SMB Detected (versions:2, 3) (Windows 10.0 Build 14393 x64) (preferred dialect:SMB 3.1.1) (compression capabilities:) (encryption capabilities:AES-128-GCM) (signatures:required) (uptime:3m 46s) (guid:{3863d7d4-26ca-4913-8ff3-d4e27787e43d}) (authentication domain:ADF3) 
                                                           ^^^^^^^^^^^ Added ^^^^^^^^^^^^

Running the module against a windows box should provide the details that we can log out for the user, I'm not sure what samba gives you

@nrathaus
Copy link
Contributor Author

I think what you are asking to add already exists:

msf6 auxiliary(scanner/smb/smb_version) > run 172.22.0.2

[*] 172.22.0.2:445        - SMB Detected (versions:1, 2, 3) (preferred dialect:SMB 3.1.1) (compression capabilities:) (encryption capabilities:AES-128-GCM) (signatures:optional) (guid:{63613736-3062-3034-6238-653700000000}) (authentication domain:67ACB040B8E7)
[*] 172.22.0.2:445        -   Host could not be identified: Windows 6.1 (Samba 4.12.2)
[*] 172.22.0.2:           - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

NOTE the part about Windows 6.1 (Samba 4.12.2)

compliance-r7
compliance-r7 previously approved these changes Apr 25, 2024
Copy link

@compliance-r7 compliance-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only pom.xml has changed, approved!

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Apr 25, 2024

Running smb_version against a windows target with SMB v1,v2,v3 enabled outputs the target build information ✅

msf6 auxiliary(scanner/smb/smb_version) > rerun rhost=192.168.123.136 username=vagrant password=vagrant
[*] Reloading module...

[*] 192.168.123.136:445   - Force SMB1 since SMB fingerprint needs native_lm/native_os information
[*] 192.168.123.136:445   - SMB Detected (versions:1, 2, 3) (preferred dialect:SMB 3.1.1) (compression capabilities:) (encryption capabilities:AES-128-GCM) (signatures:optional) (uptime:3m 45s) (guid:{eafd6aa4-cdfe-41c7-a1c5-340d151af52a}) (authentication domain:WINDEV)Windows 2016 Standard (build:14393) (name:WINDEV)
[+] 192.168.123.136:445   -   Host is running SMB Detected (versions:1, 2, 3) (preferred dialect:SMB 3.1.1) (compression capabilities:) (encryption capabilities:AES-128-GCM) (signatures:optional) (uptime:3m 45s) (guid:{eafd6aa4-cdfe-41c7-a1c5-340d151af52a}) (authentication domain:WINDEV)Windows 2016 Standard (build:14393) (name:WINDEV)
                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[*] 192.168.123.136:      - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Disabling SMB v1 on the windows target:

Set-SmbServerConfiguration -EnableSMB1Protocol $false

Running the same module against the target with SMB v1 disabled no longer shows the target build information ❌

msf6 auxiliary(scanner/smb/smb_version) > rerun rhost=192.168.123.136 username=vagrant password=vagrant 
[*] Reloading module...

[*] 192.168.123.136:445   - Force SMB1 since SMB fingerprint needs native_lm/native_os information
[*] 192.168.123.136:445   - SMB Detected (versions:2, 3) (preferred dialect:SMB 3.1.1) (compression capabilities:) (encryption capabilities:AES-128-GCM) (signatures:optional) (uptime:4m 52s) (guid:{eafd6aa4-cdfe-41c7-a1c5-340d151af52a}) (authentication domain:WINDEV)
[*] 192.168.123.136:445   -   Host could not be identified
[*] 192.168.123.136:      - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

We can see that that build information is missing on the re-scan; but from wireshark it looks like it should be available just fine in the NTLMSSP_CHALLENGE packet:

image

@nrathaus
Copy link
Contributor Author

This information is processed in these two lines of code:

        response = smb2_ntlmssp_negotiate
        challenge_packet = smb2_ntlmssp_challenge_packet(response)

@nrathaus
Copy link
Contributor Author

Specifically, the:
packet = RubySMB::SMB2::Packet::SessionSetupResponse.read(raw_response)

@nrathaus
Copy link
Contributor Author

There seems to be no parsing of the GSS-API Generic Security Service Application Program Interface section of the data

@nrathaus
Copy link
Contributor Author

nrathaus commented Apr 25, 2024

There seems to be some thought placed into the code to support GSS?

        def set_type2_blob(type1_message)
          gss_blob = RubySMB::Gss.gss_type2(type1_message)
          self.security_buffer_length = gss_blob.length
          self.buffer = gss_blob
        end

But no one is calling this function

@nrathaus
Copy link
Contributor Author

Parsing this data while coding it in Ruby is at the moment beyond my technical skills

@smcintyre-r7
Copy link
Contributor

You should be able to parse it using RubyNTLM / Net::NTLM. It's possible the entire message isn't available outside of RubySMB and RubySMB would need to be updated to parse the message when it's available, extract and save the necessary fields.

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Apr 25, 2024

iirc there's also all of the required parsers over in the ruby_smb library for that octet string/buffer, i.e. these methods:

https://github.com/rapid7/ruby_smb/blob/681f67763491639365acd6c18b3d3ce4f70388ce/lib/ruby_smb/peer_info.rb

And the binary model:

https://github.com/rapid7/ruby_smb/blob/681f67763491639365acd6c18b3d3ce4f70388ce/lib/ruby_smb/ntlm.rb#L48

But if RubyNTLM is easier to reach for in this context, that sounds good to me 💯

@nrathaus
Copy link
Contributor Author

Is RubyNTLM being shipped/used by metasploit atm? or do I need to copy-paste the code there into the smb.rb that comes with Metasploit?

@smcintyre-r7
Copy link
Contributor

smcintyre-r7 commented Apr 26, 2024

It's already included with Metasploit https://github.com/rapid7/metasploit-framework/blob/master/metasploit-framework.gemspec#L84

It's worth noting though, that for the actual authentication workflow we use our own client from RubySMB because it includes some changes we haven't been able to get merged into the upstream library. Most notably, it supports anonymous authentication which is required in certain contexts by Metasploit such as exploiting zerologon.

For what's going on here though, you just need to use the parsing code. I only point this out to provide context that for the actual processing we have to use our version.

@smcintyre-r7 smcintyre-r7 marked this pull request as draft April 29, 2024 15:52
@compliance-r7 compliance-r7 dismissed their stale review April 29, 2024 15:52

Dismissing stale review

Copy link

@compliance-r7 compliance-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only pom.xml has changed, approved!

Copy link
Contributor

@adfoster-r7 adfoster-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's some changes to make here to support the requirements 👍

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

Successfully merging this pull request may close these issues.

None yet

4 participants