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

This post has been republished via RSS; it originally appeared at: Storage at Microsoft articles.

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 network 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 network 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 Active Directory (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.

 

People tend to think of a username as the only authentication mechanism and, in a workgroup, that is mostly right. Add AD to the mix and the authentication story changes. The act of joining a computer to a domain creates a computer object. The computer object (<hostname>$) is a valid authentication object in AD and can be used to authenticate to Windows and an SMB share. Though it is rare that SMB falls back to the computer, or machine, account, it is possible.

 

By way of example, Hyper-V 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 Hyper-V 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 Domain Controller (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 network 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, Kerberos 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.3\IPC$ "" /user:

Result: No access granted.

JamesKehr_0-1582228625717.png

 

net use \\10.19.0.3\IPC$

Result: No access granted.

JamesKehr_1-1582228625720.png

 

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

 

net use \\10.19.0.3\share

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.3\IPC$ "" /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.3\IPC$

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: CONTOSO\RedUser

11

0.093470

10.19.0.3

10.19.0.2

SMB2

159

Session Setup Response

 

You will note that RedWrk sent the CONTOSO\RedUser 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 Kerberos 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.3\share

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: CONTOSO\RedUser

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.1\IPC$ "" /user:

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

JamesKehr_6-1582228625729.png

 

net use \\10.19.0.1\IPC$

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: CONTOSO\RedUser

18

69.632472

10.19.0.1

10.19.0.2

SMB2

159

Session Setup Response

 

net use \\10.19.0.1\SYSVOL

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): tcp.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

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.