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

Improvements in SMB2 dialect negotiation #2208

wants to merge 8 commits into from

Improvements in SMB2 dialect negotiation #2208

wants to merge 8 commits into from


Copy link

There are a few weaknesses in the current handling of SMB 2 dialect negotiation:

  • Scripts smb-protocols and smb2-capabilities lack a check whether SMB 2 is supported by the target. Instead, they immediately start with probing one dialect revision at a time. The effect is that for older SMB 2 implementations, such as Windows 7, they are sending probes for dialects that are guaranteed to fail. The issue is even more pronounced with targets that do not support SMB 2 at all, such as XP. In this case, a native SMB2 probe does not result in any response from the target so the script pauses until the probe times out. The time-out is set to 10s, which means that in total the script is guaranteed to take at least 50s under these conditions (with 5 supported dialects).

  • Script smb2-security-mode iterates through SMB 2 dialects until it succeeds with negotiating a session with the target. If the target supports only the latest dialects, such as 3.1.1, then the script performance is notably degraded.

  • Script smb2-vuln-uptime hard-codes one specific SMB 2 dialect to use. If the target does not support it then the script fails. Other scripts, such as smb2-time, do not explicitly force a dialect but they leave the dialect negotiation completely up to function smb2.negotiate_v2, which again defaults to a single specific dialect so these scripts might suffer the same fate.

This proposed code implements the following changes:

  • Scripts that are looping through all dialects by design are now guarded with early SMB 2 negotiation, which determines the highest supported dialect revision and, implicitly, whether SMB 2 is supported at all. This means that the dialect loop can be terminated early, as soon as the highest revision is reached.

  • Scripts that do not have to force a specific dialect with the target are now relying on function smb2.negotiate_v2, which has been modified to propose all supported dialects to the target by default, maximizing the chance that the negotiation succeeds.

  • Various duplicated instances of the list of supported SMB 2 dialect revision codes have been centralized and replaced with calls to function smb2.dialects. Similarly, duplicated code for converting integer revision codes to human-friendly strings has been replaced with calls to function smb2.dialect_name.

  • Cosmetically, all SMB 2 dialect names have been modified to match official revisions: 2.0.2, 2.1, 3.0, 3.0.2, and 3.1.1. The same revisions were previously called 2.02, 2.10, 3.00, 3.02, and 3.11.

Performance Comparison

test / target Win XP Pro SP3 Win 7 Pro SP1 Win 10 Ent 1909 Samba 4.12.5 (SMB3 only)
SMB 2 dialects none 2.0.2 - 2.1 2.0.2 - 3.1.1 3.1.1
smb-protocols -40s (-79%) -3s (-39%) 0s (0%) 0s (0%)
smb2-capabilities -40s (-79%) -2s (-30%) 0s (0%) 0s (0%)
smb2-security-mode -40s (-79%) 0s (0%) 0s (0%) -2s (-83%)
smb2-time 0s (0%) 0s (0%) 0s (0%) old version fails
smb2-vuln-uptime 0s (0%) 0s (0%) 0s (0%) old version fails

@cldrn In some cases it was not clear why the current code was designed this way so there is a decent chance that I have missed some important aspect. Could you please review?

Do not try individual dialects if SMB2 is not supported at all
Do not test for dialects with revision codes higher than what was agreed to by the target
This is expensive if the target does not support lower dialect revisions
Otherwise the script fails with targets that do not support the particular dialect
Otherwise the script fails with targets that do not support the particular dialect
Copy link

This PR will be committed on/after January 15 unless concerns are raised.

Copy link

The patch has been committed as r38184.

@nmap-bot nmap-bot closed this in 58617a7 Jan 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet

Successfully merging this pull request may close these issues.

smb-protocols runs for ~300 seconds when only SMBv1 is enabled
1 participant