TIP: Identifying a process on a listening port

This is a great example on how I combine scripts and BigFix to get data across a large number of systems quickly.

We needed to know the process listening on common web ports. We knew which ports we wanted to check, we did not know which apps to check.

I started with a 25 line Batch Script.

Basically we set an session variable for each port we want to check.
We then loop through those and call a sub routine that uses netstat to see if the port is listening
We then use the netstat results to get the process ID (PID) on the listening port
We then use the PID to get the name of the process
We then dump this into a registry key using the port as the value name and the process name in the value data.

@echo off
SETLOCAL enabledelayedexpansion
CLS
SET __PortTocheck1=80
SET __PortTocheck2=443
SET __PortTocheck3=8080
SET __PortTocheck4=8443
FOR /F "tokens=2* delims==" %%A IN ('SET __PortTocheck') do call :DDCheckPort %%A
:DDCheckPort
set _calledport=%1
netstat -aon | find /i "listening" | find ":!_calledport!" >NUL 2>NUL
if %errorlevel% EQU 0 (
SET _cmdnets="netstat -aon | find /i "listening" | find ":!_calledport!""
for /f "tokens=5 delims= " %%a in ('!_cmdnets!') do SET _strPID= %%a
SET _cmdPID="tasklist /fi "pid eq !_strPID!""
for /f "tokens=1 delims= " %%b in ('!_cmdPID!') do SET _rProcess= %%b
CALL :regoutput !_rProcess! !_calledport!
)
if %errorlevel% NEQ 0 GOTO :EOF
GOTO :EOF
:regoutput
Set FoundProcess= %1
Set FoundPort= %2
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\MYREGKEY\WEBProcesses" /v !FoundPort! /d "!FoundProcess!" /t REG_SZ /f /reg:64 >NUL 2>NUL
GOTO :EOF

Run that in a task to execute against all machines, or at least those you want to check

Create an analysis to see if the WEBProcesses key exists (Used to make relevant)
Pull the data for the ports you know you checked for in the script.

This is what the reg keys will look like. (From our root server if you could not tell)

image

This is the relevance of ONE of the properties. You will need a property for every port you checked.

if exists key “HKEY_LOCAL_MACHINE\SOFTWARE\MYREGKEY\WEBProcesses” whose (exists value “80” of it as string) of x64 registries then (value “80” of key “HKEY_LOCAL_MACHINE\SOFTWARE\MYREGKEY\WEBProcesses” of x64 registries as string) else “Not Applicable”

The results look like this…

image

I am sure there are other ways to get this data and probably without using the batch script, but this worked for us and it only took about an hour to put in place and gather the data.

6 Likes

Curious is you ran netstat -abn wouldn’t that give you the application info you need and save you a step?

Maybe, but then I would not have my fancy code! LOL

I know just enough about system admin and utilities to be dangerous. :smile: Just enough to get the job done.

I was in a hurry to get this out, had upper management requesting data “yesterday”. So I wrote it as quickly as I could.

This is awesome work, and thanks for the tip!

This method demonstrates a repeating pattern that comes up fairly often - where an Action has to be run, to produce an output, and the output is read as part of an Analysis. There are many areas where we don’t have prebuilt Inspectors to query some system state directly.

That said, this particular example does have a pure-relevance solution so I’d like to point that out too -

q: unique values of (it as string) of (pid of process of it as string | "Unknown", name of process of it | "unknown", local port of it) of sockets whose (tcp of it and local port of it  is contained by set of ( 80;443;8080;8083;3389;52311)) of network
A: 0, unknown, 52311
A: 1180, svchost.exe, 3389
A: 3748, BESWebReportsServer.exe, 8080
A: 3748, BESWebReportsServer.exe, 8083
A: 3884, BESRootServer.exe, 52311
T: 0.490 ms

edit: In the Fixlet Debugger, this has to be evaluated in “Local Client Evaluation Mode” to show the Process properties; in “Fixlet Debuggger Evaluation Mode” those will show “unknown” although the matching Port numbers will be displayed.

3 Likes

Just noticed the result for process ‘0’ with process name “unknown”. That’s because the socket is still available but probably in a CLOSE_WAIT state. This query is refined a bit to only show the tcp ports that are in LISTENING state, and also shows the IP address(s) on which the socket is listening (as it’s sometimes useful to be able to filter to specific network addresses or filter out loopback-only listeners)

q: (pid of process of it as string | "Unknown", name of process of it | "unknown", local address of it, local port of it) of sockets whose (tcp of it and listening of tcp state of it and local port of it is contained by set of ( 80;443;8080;8083;3389;52311)) of network

A: 1180, svchost.exe, 0.0.0.0, 3389
A: 3748, BESWebReportsServer.exe, 0.0.0.0, 8080
A: 3748, BESWebReportsServer.exe, 0.0.0.0, 8083
A: 3884, BESRootServer.exe, 0.0.0.0, 52311
A: 1180, svchost.exe, 0:0:0:0:0:0:0:0, 3389
A: 3748, BESWebReportsServer.exe, 0:0:0:0:0:0:0:0, 8080
A: 3748, BESWebReportsServer.exe, 0:0:0:0:0:0:0:0, 8083
A: 3884, BESRootServer.exe, 0:0:0:0:0:0:0:0, 52311
3 Likes

I’m going to link this idea for this usecase every time I can.

https://bigfix-ideas.hcltechsw.com/ideas/BFP-I-252

1 Like