Hi again, time for more Powershell!
This all started with me troubleshooting on a customer's server, and cursing Microsoft's decision to spread the output of "netstat -naob" across two lines. Likely they made that decision out of spite - you know, just so I can't grep the information that I actually need out of it.
Which got me to thinking about doing this in Powershell. It'll be easy I thought, just slam together the output of:
Get-Process
Get-NetTCPConnection
Get-NetUDPEndpoint
Join them up into one list, and dump the output right?
Hmm... except that to do a Get-Process with the associated account info (the -IncludeUserName option), you need elevated rights. So that means I need a check for that. And wait, the fields don't *exactly* match up, and the Get-NetUDPEndpoint doesn't actually spell out what's listening, we need to stuff that into the field ... OK, it did get a bit complicated once I got into it. The final script for both TCP and UDP is below. Note that you'll only get the account info if you run it with admin rights:
$Processes = @{}
# first check if we're running elevated or not, so we don't error out on the Get-Process command
# note that account info is only retrieved if we are elevated
if ((New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
{
# Elevated - get account info per process
Get-Process -IncludeUserName | ForEach-Object {
$Processes[$_.Id] = $_
}
}
else
{
# Not Elevated - don't collect per-process account info
Get-Process | ForEach-Object {
$Processes[$_.Id] = $_
}
}
# Query Listening TCP Ports and Connections
$Ports = Get-NetTCPConnection |
Select-Object LocalAddress,
RemoteAddress,
@{Name="Proto";Expression={"TCP"}},
LocalPort,RemotePort,State,
@{Name="PID"; Expression={ $_.OwningProcess }},
@{Name="UserName"; Expression={ $Processes[[int]$_.OwningProcess].UserName }},
@{Name="ProcessName"; Expression={ $Processes[[int]$_.OwningProcess].ProcessName }},
@{Name="Path"; Expression={ $Processes[[int]$_.OwningProcess].Path }} |
Sort-Object -Property LocalPort, UserName
# Query Listening UDP Ports (No Connections in UDP)
$UDPPorts += Get-NetUDPEndpoint |
Select-Object LocalAddress,RemoteAddress,
@{Name="Proto";Expression={"UDP"}},
LocalPort,RemotePort,State,
@{Name="PID"; Expression={ $_.OwningProcess}},
@{Name="UserName"; Expression={ $Processes[[int]$_.OwningProcess].UserName}},
@{Name="ProcessName"; Expression={ $Processes[[int]$_.OwningProcess].ProcessName}},
@{Name="Path"; Expression={ $Processes[[int]$_.OwningProcess].Path}} |
Sort-Object -Property LocalPort, UserName
foreach ($P in $UDPPorts) {
if( $P.LocalAddress -eq "0.0.0.0") {$P.State = "Listen"} }
$Ports += $UDPPorts
$Ports | ft
PS C:\> $Ports | ft
LocalAddress RemoteAddress Proto LocalPort RemotePort State PID UserName ProcessName Path
------------ ------------- ----- --------- ---------- ----- --- -------- ----------- ----
0.0.0.0 0.0.0.0 TCP 135 0 Listen 72 NT AUTHORITY\NETWORK SERVICE svchost C:\WINDOWS\system32\svchost.exe
:: :: TCP 135 0 Listen 72 NT AUTHORITY\NETWORK SERVICE svchost C:\WINDOWS\system32\svchost.exe
172.23.8.171 0.0.0.0 TCP 139 0 Listen 4 System
192.168.142.1 0.0.0.0 TCP 139 0 Listen 4 System
169.254.98.213 0.0.0.0 TCP 139 0 Listen 4 System
192.168.254.1 0.0.0.0 TCP 139 0 Listen 4 System
:: :: TCP 445 0 Listen 4 System
0.0.0.0 0.0.0.0 TCP 902 0 Listen 5456 NT AUTHORITY\SYSTEM vmware-authd C:\Program Files (x86)\VMware\VMware Workstation\vmware-authd.exe
0.0.0.0 0.0.0.0 TCP 912 0 Listen 5456 NT AUTHORITY\SYSTEM vmware-authd C:\Program Files (x86)\VMware\VMware Workstation\vmware-authd.exe
(and so on)
|
So now, if you want just the listening ports, you can get that with a simple grep:
PS C:\> $ports | ? State -eq 'Listen' | ft
LocalAddress RemoteAddress Proto LocalPort RemotePort State PID UserName ProcessName Path
------------ ------------- ----- --------- ---------- ----- --- -------- ----------- ----
0.0.0.0 0.0.0.0 TCP 135 0 Listen 72 NT AUTHORITY\NETWORK SERVICE svchost C:\WINDOWS\system32\svchost.exe
:: :: TCP 135 0 Listen 72 NT AUTHORITY\NETWORK SERVICE svchost C:\WINDOWS\system32\svchost.exe
169.254.98.213 0.0.0.0 TCP 139 0 Listen 4 System
172.20.10.2 0.0.0.0 TCP 139 0 Listen 4 System
10.50.254.132 0.0.0.0 TCP 139 0 Listen 4 System
192.168.254.1 0.0.0.0 TCP 139 0 Listen 4 System
192.168.142.1 0.0.0.0 TCP 139 0 Listen 4 System
:: :: TCP 445 0 Listen 4 System
0.0.0.0 0.0.0.0 TCP 902 0 Listen 5456 NT AUTHORITY\SYSTEM vmware-authd C:\Program Files (x86)\VMware\VMware Workstation\vmware-authd.exe
0.0.0.0 0.0.0.0 TCP 912 0 Listen 5456 NT AUTHORITY\SYSTEM vmware-authd C:\Program Files (x86)\VMware\VMware Workstation\vmware-authd.exe
0.0.0.0 0.0.0.0 TCP 1536 0 Listen 600 wininit
:: :: TCP 1536 0 Listen 600 wininit
:: :: TCP 1537 0 Listen 1268 NT AUTHORITY\SYSTEM svchost C:\WINDOWS\system32\svchost.exe
0.0.0.0 0.0.0.0 TCP 1537 0 Listen 1268 NT AUTHORITY\SYSTEM svchost C:\WINDOWS\system32\svchost.exe
0.0.0.0 0.0.0.0 TCP 1538 0 Listen 1840 NT AUTHORITY\LOCAL SERVICE svchost C:\WINDOWS\System32\svchost.exe
:: :: TCP 1538 0 Listen 1840 NT AUTHORITY\LOCAL SERVICE svchost C:\WINDOWS\System32\svchost.exe
:: :: TCP 1539 0 Listen 3816 NT AUTHORITY\SYSTEM spoolsv C:\WINDOWS\System32\spoolsv.exe
0.0.0.0 0.0.0.0 TCP 1539 0 Listen 3816 NT AUTHORITY\SYSTEM spoolsv C:\WINDOWS\System32\spoolsv.exe
0.0.0.0 0.0.0.0 TCP 1545 0 Listen 684 services
:: :: TCP 1545 0 Listen 684 services
:: :: TCP 1546 0 Listen 740 NT AUTHORITY\SYSTEM lsass C:\WINDOWS\system32\lsass.exe
0.0.0.0 0.0.0.0 TCP 1546 0 Listen 740 NT AUTHORITY\SYSTEM lsass C:\WINDOWS\system32\lsass.exe
::1 :: TCP 1670 0 Listen 10476 NT AUTHORITY\SYSTEM jhi_service C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL\jhi_service.exe
127.0.0.1 0.0.0.0 TCP 4767 0 Listen 4460 NT AUTHORITY\SYSTEM PanGPS C:\Program Files\Palo Alto Networks\GlobalProtect\PanGPS.exe
0.0.0.0 0.0.0.0 TCP 5040 0 Listen 2628 NT AUTHORITY\LOCAL SERVICE svchost C:\WINDOWS\system32\svchost.exe
127.0.0.1 0.0.0.0 TCP 5354 0 Listen 5052 NT AUTHORITY\SYSTEM mDNSResponder C:\Program Files\Bonjour\mDNSResponder.exe
:: :: TCP 5357 0 Listen 4 System
127.0.0.1 0.0.0.0 TCP 5939 0 Listen 5252 NT AUTHORITY\SYSTEM TeamViewer_Service C:\Program Files (x86)\TeamViewer\TeamViewer_Service.exe
0.0.0.0 0.0.0.0 TCP 8099 0 Listen 4796 NT AUTHORITY\SYSTEM SolarWinds TFTP Server C:\Program Files (x86)\SolarWinds\TFTP Server\SolarWinds TFTP Server.exe
127.0.0.1 0.0.0.0 TCP 44430 0 Listen 4384 NT AUTHORITY\SYSTEM FoxitConnectedPDFService C:\PROGRAM FILES (X86)\FOXIT SOFTWARE\FOXIT READER\FoxitConnectedPDFService.exe
127.0.0.1 0.0.0.0 TCP 62522 0 Listen 2304 NT AUTHORITY\SYSTEM vpnagent C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpnagent.exe
0.0.0.0 UDP 69 Listen 4796 NT AUTHORITY\SYSTEM SolarWinds TFTP Server C:\Program Files (x86)\SolarWinds\TFTP Server\SolarWinds TFTP Server.exe
0.0.0.0 UDP 3702 Listen 4640 NT AUTHORITY\LOCAL SERVICE dasHost C:\WINDOWS\system32\dashost.exe
0.0.0.0 UDP 5353 Listen 2276 NT AUTHORITY\NETWORK SERVICE svchost C:\WINDOWS\system32\svchost.exe
0.0.0.0 UDP 5355 Listen 2276 NT AUTHORITY\NETWORK SERVICE svchost C:\WINDOWS\system32\svchost.exe
0.0.0.0 UDP 6096 Listen 6388 NT AUTHORITY\SYSTEM FortiESNAC C:\Program Files (x86)\Fortinet\FortiClient\FortiESNAC.exe
0.0.0.0 UDP 51498 Listen 5252 NT AUTHORITY\SYSTEM TeamViewer_Service C:\Program Files (x86)\TeamViewer\TeamViewer_Service.exe
0.0.0.0 UDP 52326 Listen 8568 NT AUTHORITY\LOCAL SERVICE svchost C:\WINDOWS\system32\svchost.exe
0.0.0.0 UDP 52410 Listen 2304 NT AUTHORITY\SYSTEM vpnagent C:\Program Files (x86)\Cisco\Cisco AnyConnect Secure Mobility Client\vpnagent.exe
0.0.0.0 UDP 58385 Listen 5052 NT AUTHORITY\SYSTEM mDNSResponder C:\Program Files\Bonjour\mDNSResponder.exe
0.0.0.0 UDP 59622 Listen 4 System
0.0.0.0 UDP 59623 Listen 4 System
0.0.0.0 UDP 60966 Listen 1276 DESKTOP-CPHGM1I\rvlab01 mstsc C:\WINDOWS\system32\mstsc.exe
0.0.0.0 UDP 60967 Listen 1276 DESKTOP-CPHGM1I\rvlab01 mstsc C:\WINDOWS\system32\mstsc.exe
0.0.0.0 UDP 62741 Listen 5268 NT AUTHORITY\SYSTEM vmnat C:\WINDOWS\SysWOW64\vmnat.exe
0.0.0.0 UDP 63327 Listen 4640 NT AUTHORITY\LOCAL SERVICE dasHost C:\WINDOWS\system32\dashost.exe
0.0.0.0 UDP 63448 Listen 4 System
0.0.0.0 UDP 63449 Listen 4 System
|
With that done, I got to thinking - what about running this across an entire domain, and then look for "outliers" - listening ports that only 1 or 2 hosts have open?? What would that look like?
GetProcess has a -ComputerName option, so we're good there.
Get-NetTCPConnection doesn't have a -ComputerName option, but it does have a -RemoteAddress option
However .. Get-NetUDPEndpoint has neither - local execution only (insert sad panda face here)
I guess we'll need to do this all remotely then - we'll make the whole script so far into a function, then call it using invoke-command for all stations in a domain - like this:
function PSNetstat {
$Processes = @{}
if ((New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
{
# Elevated - get account info per process
Get-Process -IncludeUserName | ForEach-Object {
$Processes[$_.Id] = $_
}
}
else
{
# Not Elevated - don't collect per-process account info
Get-Process | ForEach-Object {
$Processes[$_.Id] = $_
}
}
# Query Listening TCP Ports and Connections
$Ports = Get-NetTCPConnection |
Select-Object LocalAddress,
RemoteAddress,
@{Name="Proto";Expression={"TCP"}},
LocalPort,RemotePort,State,
@{Name="PID"; Expression={ $_.OwningProcess }},
@{Name="UserName"; Expression={ $Processes[[int]$_.OwningProcess].UserName }},
@{Name="ProcessName"; Expression={ $Processes[[int]$_.OwningProcess].ProcessName }},
@{Name="Path"; Expression={ $Processes[[int]$_.OwningProcess].Path }} |
Sort-Object -Property LocalPort, UserName
# Query Listening UDP Ports (No Connections in UDP)
$UDPPorts = Get-NetUDPEndpoint |
Select-Object LocalAddress,RemoteAddress,
@{Name="Proto";Expression={"UDP"}},
LocalPort,RemotePort,State,
@{Name="PID"; Expression={ $_.OwningProcess}},
@{Name="UserName"; Expression={ $Processes[[int]$_.OwningProcess].UserName}},
@{Name="ProcessName"; Expression={ $Processes[[int]$_.OwningProcess].ProcessName}},
@{Name="Path"; Expression={ $Processes[[int]$_.OwningProcess].Path}} |
Sort-Object -Property LocalPort, UserName
foreach ($P in $UDPPorts) {
if( $P.LocalAddress -eq "0.0.0.0") {$P.State = "Listen"} }
$Ports += $UDPPorts
$Ports
}
$targets =get-adcomputer -filter * -Property DNSHostName
$portlist = @()
$i = 1
$count = $targets.count
foreach ($targethost in $targets) {
write-host $i of $count - $targethost.DNSHostName
if (Test-Connection -ComputerName $targethost.DNSHostName -count 2 -Quiet) {
$portlist += invoke-command -ComputerName $targethost ${function:PSNetStat}
++$i
}
}
$portlist | export-csv all-ports.csv
|
Now you have all TCP and UDP ports, in all states in one giant CSV. If you want, you can pull out the just listening ports using the "grep" method we used earlier, and you can mix-and-match it any way you please in either PowerShell or in Excel (we dumped it all into a CSV at the end).
Use our comment form if you run this and find anything odd in your network, we're always interested in "odd"
===============
Rob VandenBrink
www.coherentsecurity.com
Comments
Anonymous
Jun 21st 2019
5 years ago
Anonymous
Jun 21st 2019
5 years ago
https://sourceforge.net/p/multiline-grep/wiki/Home/
Kurt
Anonymous
Jun 24th 2019
5 years ago