SMB and Null Sessions: Why Your Pen Test is Probably Wrong

Hi everyone, James Kehr here with a guest post. One of the SMB cases we get regularly at Microsoft Support is, “my pen test says you allow Null sessions!” Followed by a string of CVE numbers; like, CVE-1999-0519 and CVE-1999-0520. Which can sometimes lead to, “Why hasn't Microsoft fixed this? It's been 20 years!” This post will show why this is probably a false positive on modern Windows. And if it's not, someone may have done something very bad to your Windows installation.

Null sessions

One of the technologies I have worked with the most during my time at Microsoft is SMB. You may also know SMB by one of the other common names: CIFS and Samba. While these are technically three different things, many people use the terms interchangeably to describe the same file system protocol. Why? That's a long story involving IBM, Microsoft, Linux, and about 35 years of history. All you need to know is that at Microsoft we use the term SMB (Server Message Block).

But if you must know, the simplified version goes something like this: SMB is the protocol, CIFS is an old dialect of SMB, and Samba is the Linux/Unix-like implementation of the SMB protocol. People and companies get familiar with one of those terms and stick to it, which has made the three names interchangeable outside of technical documentation.

What is a Null Session you may ask? A null session implies that access to a resource, most commonly the IPC$ “Windows Named Pipe” share, was granted without authentication. Also known as anonymous or guest access. Windows has not allowed null or anonymous access for a very long time.

Credentials and SMB

Most intrusion detection software doesn't seem to understand how Windows auth works over SMB in an (AD) environment, and that is usually the cause of the false positive. Windows and SMB really want people to make a successful connection to a file share and they go out of their way to try every possible credential available to complete the connection.

By way of example, can be setup to access virtual hard drives over SMB 3 without using S2D or a SAN. This setup uses the machine account of the host(s) to access the SMB share rather than a user or a service account.

When no account is explicitly provided SMB will try implicit credentials. First, the logged-on user's account, and then, sometimes, the computer object. Some shares and third-party file servers with certain permissions will allow computer accounts to connect. You may have limited or no usable access, but it will authenticate.

Using implicit credentials is not a null session connection since credentials are being provided; even though, they were not explicitly provided. This means the SMB session is being authorized, and therefore not a null session.

What are implicit and explicit credentials, exactly? An explicit credential is one that is provided as part of authentication. It's like clicking the “Connect using different credentials” checkbox when mapping a drive with File Explorer, or /user with “net use”.  Implicit credentials are the opposite of that. When no explicit credential is provided it is implied that the operating system should use the credentials of the current logged-on user.

The Test

You don't believe me, do you? The pen test said it's a null session. You even ran the commands to prove it. Now you think Microsoft is up to their old tricks. The 20-year-old null session bug still isn't fixed!

Fine, let me prove it to you. These are all tests anyone can run to confirm. I'll use Wireshark, the industry standard packet capture and analysis tool, with three main tests for your edification.

  1. Workgroup to Workgroup – Two non-domain joined Windows 10 1903 (Spring 2019 Update) systems. All updates installed, through Oct 2019. No changes made other than setting up a file share.
  2. Workstation to Workstation – Two domain joined Windows 10 1903 (Spring 2019 Update) systems. All updates installed, through Oct 2019. No changes made other than domain join and setting up a file share.
  3. Workstation to (DC) – One domain joined workstation to the DC. Workstation running fully patched Win10 1903, DC running fully patched Windows Server 2019. Default domain policies, no hardening, no extra policies or configuration.

There are two commands commonly used to test null sessions, and I'll be testing both, plus one extra scenario-based test. This first command explicitly sets a NULL user (/user:) and password (“”)

net use <IP ADDRESS>IPC$ "" /user:

The second command sets no explicit credentials. This is where the more interesting behavior will happen because it leaves room for Windows to try implicit credentials.

net use <IP ADDRESS>IPC$

A normal share for non-IPC$ testing.

net use <IP Address>share

For domain testing I'll use the domain's SYSVOL share.

net use <DC>SYSVOL

Understanding IPC$

The inter-process communication share (“IPC$”) is a special case. It's the share that allows remote Named Pipe access. Names Pipes are an old-school method used to allow two services to talk with each other, even over a connection. IPC$ functionality has been around for ages and default access rules to IPC$ has changed with each release of Windows. Older versions of Windows may behave differently than these tests.

Network setup:

Subnet: 10.19.0.0/24

Server:    10.19.0.1

RedWrk:    10.19.0.2

BlueWrk:   10.19.0.3

Domain User accounts:

RedUser

BlueUser

Domain:

CONSTOSO

Local accounts:

LclRed

LclBlue

Computer names:

RedWrk

BlueWrk

How SMB Connects

There's a bit of basic knowledge that may be needed before we proceed. There are three key SMB commands used for authentication and authorization: Negotiate, Session Setup, and Tree Connect.

  • Negotiate – This command determines what dialect of SMB (major.minor version) will be used, discovers basic settings, and can perform some pre-authentication, depending on dialect.
  • Session Setup – This is where authentication is performed. Credentials, tickets, or security tokens are exchanged here, and general authorization is either granted or denied at this step.
  • Tree Connect – This is where authorization to a share happens. Tree Connect takes the security account from Session Setup and uses that to determine whether access to the individual share(s) should be granted.

Because of the way SMB works, it's possible to authenticate successfully but not get access to any resources. This is why it's important to look under the proverbial covers to see what's really going on before making final judgement.

On to the tests…

Workgroup to Workgroup

This is the basic home scenario. Two computers used by a regular folks who just want things to work without ever opening a settings console in their entire life.

Command:

net use 10.19.0.3IPC$ "" /user:

Result: No access granted.

JamesKehr_0-1582228625717.png

net use 10.19.0.3IPC$

Result: No access granted.

JamesKehr_1-1582228625720.png

NOTE: Windows refused to complete the connection without supplying credentials.

net use 10.19.0.3share

Result: No access granted.

JamesKehr_2-1582228625722.png

NOTE: Windows refused to complete the connection without supplying credentials.

This is all expected behavior because RedWrk and BlueWrk have no inherent trust between each other. No centralized authentication method means that each workgroup member must rely on their local security database, which does not contain details about the other workgroup member(s) unless those details are explicitly added. This means that all anonymous and implicit authentication methods will fail.

Workstation to Workstation (Domain-joined)

RedWrk and BlueWrk were joined to the domain for the next step. The same “net use” commands were run from RedWrk to BlueWrk. This is where things start to get interesting for us.

Command:

net use 10.19.0.3IPC$ "" /user:

Result: No change in behavior.

JamesKehr_3-1582228625726.png

This first example, with “/user:”, is an explicit null credential, which is denied by Windows.

net use 10.19.0.3IPC$

JamesKehr_4-1582228625727.png

“Ah ha! It worked! Vindication!” I hear you cry. “That's a null session!”

Um, no.

Remember when I said Windows really wants to make that connection work? Well, we really do, and when no credential is entered Windows will automatically try the user's domain credential. This is the implicit credential I've been talking about.

Let's look at the packet capture. Specifically, the Session Setup part, where authentication happens.

No. Time Source Destination Protocol Length Info
10 0.061281 10.19.0.2 10.19.0.3 SMB2 661 Session Setup Request, NTLMSSP_AUTH, User: CONTOSORedUser
11 0.093470 10.19.0.3 10.19.0.2 SMB2 159 Session Setup Response

You will note that RedWrk sent the CONTOSORedUser account, even though we didn't explicitly set that credential. This is the same mechanism that allows you to connect to your work shared drives through Windows Explorer without explicitly entering your Windows credentials, just in command line form.

Since valid domain credentials were passed and accepted, this is not a null session. Even though it may look like one on the surface.

You may notice that SMB is using NTLM authentication and not in some tests. This can happen when an IP address is used instead of a hostname or FQDN (Fully Qualified Domain Name). This is because an IP address is not a valid Kerberos object.

net use 10.19.0.3share

JamesKehr_5-1582228625728.png

Same story as the previous command. SMB used the domain account of the logged-on user and the connection was successful.

Here's the packet capture data:

10 0.027866 10.19.0.2 10.19.0.3 SMB2 639 Session Setup Request, NTLMSSP_AUTH, User: CONTOSORedUser
11 0.035118 10.19.0.3 10.19.0.2 SMB2 159 Session Setup Response

Workstation to Domain Controller

Command:

net use 10.19.0.1IPC$ "" /user:

Result: No change in behavior. Null sessions are not allowed.

JamesKehr_6-1582228625729.png

net use 10.19.0.1IPC$

This command works because the Windows user credentials were passed. No NULL sessions here.

17 69.625346 10.19.0.2 10.19.0.1 SMB2 639 Session Setup Request, NTLMSSP_AUTH, User: CONTOSORedUser
18 69.632472 10.19.0.1 10.19.0.2 SMB2 159 Session Setup Response
net use 10.19.0.1SYSVOL

What have we here?

JamesKehr_7-1582228625730.png

Everything in the packet capture looks like it should connect, but SYSVOL is a special case.

The SYSVOL and NETLOGON shares require Keberos authentication on modern Windows. This can be changed by policy, but we only recommend it when you have a legacy system that you just can't convince management to get rid of. Kerberos is really the way to go.

A switch to the domain name, which switches to Kerberos, and it logs right in:

JamesKehr_8-1582228625731.png

Here is the data from Wireshark:

33 20.178302 10.19.0.2 10.19.0.1 KRB5 1379 TGS-REQ
34 20.178941 10.19.0.1 10.19.0.2 KRB5 1408 TGS-REP
36 20.179357 10.19.0.2 10.19.0.1 SMB2 3063 Session Setup Request
40 20.183650 10.19.0.1 10.19.0.2 SMB2 314 Session Setup Response

SMB2 (Server Message Block Protocol version 2)

    SMB2 Header

    Session Setup Response (0x01)

        [Preauth Hash: ce5e61ef7c41ea76682c8bda4ff803ba7f74123a15736201…]

        StructureSize: 0x0009

        Session Flags: 0x0000

        Blob Offset: 0x00000048

        Blob Length: 184

        Security Blob: a181b53081b2a0030a0100a10b06092a864882f712010202…

            GSS-API Generic Security Service Application Program Interface

                Simple Protected Negotiation

                    negTokenTarg

                        negResult: accept-completed (0)

                        supportedMech: 1.2.840.48018.1.2.2 (MS KRB5 – Microsoft Kerberos 5)

                        responseToken: 60819706092a864886f71201020202006f8187308184a003…

                        krb5_blob: 60819706092a864886f71201020202006f8187308184a003…

The Caveat…

This behavior is not necessarily default in older versions of Windows. This article covers some of the legacy Windows behavior, and how anonymous IPC$ access can be prevented.

Knowing is Half the Battle

Pen tests can only go into so much depth in its analysis. Collecting and analyzing packets is beyond the abilities of most products. When in doubt, validate for yourself whether it's a false positive or a true positive.

  • Download and install Wireshark on a test system where nothing else is running. This makes reading the data easier.
  • Start a Wireshark capture.
  • Reproduce the issue by running the appropriate command from the pen test.
  • Stop the Wireshark capture.
  • Add the following as the display filter (case sensitive): .port==445
    • This filter works if you want to see both SMB and Kerberos traffic: tcp.port==445 or tcp.port==88
  • Look at the SMB Session Setup for a user account or Kerberos ticket.

A false positive can be identified when a valid authentication was passed under the covers using the implicit credential behavior of Windows.

Other false positives we see revolve around using the registry to verify SMB settings and SMB encryption. SMB settings should be verified via PowerShell, *SmbServerConfiguration and *SmbClientConfiguration, and through packet capture analysis to make sure the feature is working properly; especially, when dealing with older versions of Windows and non-Windows file server which may not support the newest features, or have the full SMB protocol suite enabled.

SMB encryption is one of those settings. Not only must both client and server support SMB3 and be encryption enabled, but file share or server must explicitly enable encryption. What is the best way to see whether SMB encryption and other security features are working? You guessed it, packet capture.

Trying to determine accurate results from pen testing without a packet capture is like trying to discover life in the deep ocean by staring really hard at the ocean surface from a boat deck. Sure, you might see a little ocean life, but you won't know what's really going on until you dive down below the surface. So the next time you get back failed test for SMB on a pen test, remember to check those packets to make sure the test is accurate.

I hope you found this useful. 

– James Kehr, Escalation Engineer, MS Networking Support

 

This article was originally published by Microsoft's ITOps Talk Blog. You can find the original article here.