How would you go about finding what process was making SMB requests on a Windows PC? If you’re like me you probably answered either
netstat or PowerShell’s
Get-NetTCPConnection. These are the commands I reach for whenever I needed to link a process to a network connection, but the case isn’t so simple for SMB.
The problem with this approach is that all SMB client traffic goes through the
System process (PID
4), running under the
SYSTEM user account. This can be an issue when, for instance, we’re investigating firewall logs which are telling us that a local PC is trying to make Internet bound SMB requests. Is it malware or a misconfiguration? The first step is working out what is making those connections, and this is where the aforementioned behaviour becomes a hinderance.
Let’s see how this looks in PowerShell. I have an open SMB connection to a local resource via a PowerShell process, what does
netstat tell us?
PS C:\> Get-NetTCPConnection -RemotePort 445 | Select LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess LocalAddress : 10.250.1.100 LocalPort : 2440 RemoteAddress : 10.250.1.25 RemotePort : 445 State : Established OwningProcess : 4
PS C:\> netstat -aon | sls 445 Proto Local Address Foreign Address State PID TCP 10.250.1.100:2440 10.250.1.25:445 ESTABLISHED 4
What is PID
4 on Windows? It is the
System process, and it makes the SMB network client calls on behalf of all other processes.
PS C:\> Get-Process -PID 4 | Select -ExpandProperty ProcessName System
We can further verify this behavior by looking at TCP/IP connections for the System process in Process Explorer.
Does Sysmon Help?
One of my first thoughts was to leverage Sysmon with network connection logging, but this too only shows the System process, not the underlying process that requested the SMB connection.
Ultimately the answer was found using Sysinternals Process Monitor.
Using Process Monitor to find SMB processes
As unfiltered Process Monitor output can be overwhelming, we’ll want to begin by configuring filters to only display events we’re interested in. Primarily we want to capture events with an operation of
IRP_MJ_CREATE, but to clean things up a bit more we also want to only include events beginning with
The presence of an event containing the last mentioned path indicate the SMB connection was successfully established (though I would still use the
netstat commands for verification), while an
IRP_MJ_CREATE operation that only lists the
\\host path indicates a connection was attempted, but not successfully established (i.e., blocked by a firewall, or the remote host not running an SMB service).
This means we can get insight into processes that are making SMB connections which may be blocked by firewalls further up in the network architecture, but we where still want to identify what is initiating the connection attempt in order to determine whether it is malicious or not.
Here are a few screenshots to demonstrate what SMB connections will look like in ProcMon. Firstly, a successful attempt from a PowerShell process.
And a failed connection, notice the lack of entries containing the
This operation is logged after the connection attempt fails, not on the initial request.
And a final verification, we can see the same request being made with
Get-NetTCPConnection, but listed under the
PS C:\> Get-NetTCPConnection -RemoteAddress 10.250.1.55 | Select LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess LocalAddress LocalPort RemoteAddress RemotePort State OwningProcess ------------ --------- ------------- ---------- ----- ------------- 10.250.1.100 33349 10.250.1.55 139 SynSent 4 10.250.1.100 33342 10.250.1.55 445 SynSent 4
We can see the connection hasn’t successfully established by the state being
SynSent, which tells us that the TCP 3 way handshake hasn’t successfully completed.
That’s all for now, hope this has saved you some time!