Detecting Port Scanning Activity

Using endpoint logs to track down compromised hosts

When attackers gain an initial foothold within an environment they’ll inevitably start looking to perform some sort of lateral movement techniques to achieve their objectives. Attackers will likely start this process through a series of ping sweeps and port scans.

This post assumes you’re lucky enough to be collecting endpoint TCP connection logs from tools like Sysmon, or popular EDR solutions. These logs can be very noisy but can be very helpful when tracking down lateral movement from adversaries. Below is an example of Sysmon EventID 3.

The important fields from this log are; Image (process) the DestinationPort and DestinationIp. We’re going to attempt to correlate hosts that have communicated with multiple destination systems across multiple destination ports. The idea behind this detection is if a single host is communicating with multiple hosts using the same destination ports it may be performing scanning. False positives might include software deployment servers like WSUS, SCCM, or domain controllers.

Once you have your logging solution deployed and centrally logged the following search (Splunk SPL) can be used:

| tstats summariesonly=t values(vendor_product) as vendor_product values(file_path) as file_path values(src_ip) as src_ip earliest(_time) as etime dc(dest_port) as dc_dest_port values(dest_port) as dest_port
where index=*_sec sourcetype=sysmon (dest_port >= 1 AND dest_port <= 1024) OR dest_port = 8080 OR dest_port = 5900 OR dest_port = 3306 OR dest_port=3389 by dest_ip,dest,index,sourcetype,acq_time,process_name,process_id,user

In the above SPL you can see I’m accelerating the Sysmon data — this is really up to your organization but I highly recommend it if you can. At least accelerate the EventIDs you’re going to be performing correlations like this. From the above search — we’re focused on ports between 1 & 1024 as well as 8080, 5900, 3306, & 3389. These are the common ports most port scanners will attempt to enumerate.

| where dc_dest_port >= 5
| stats values(*) as * dc(dest_ip) as dc_dest_ip dc(dest_port) as dc_dest_port by index,sourcetype,dest,user,acq_time,process_id,process_name
| where dc_dest_ip >= 100

The above SPL is now filtering only those source hosts who are communicating with destination ip addresses over 5 or more ports. The 2nd part of the above SPL is correlating all that together to then filter on source hosts that are communicating with 100 or more distinct destination ip addresses.

Combining this together we’re left with hosts that have communicated with 100 or more hosts and have at least attempted to connect to 5 or more common ports used during port scans.

The above output provides us a host of interest as it has attempted to communicate over 7 unique ports to 256 unique hosts (a subnet range).

Hopefully this has been helpful — stay tuned for future stories to help you detect the bag guys.

Cyber Security enthusiast, detection developer and engineer, researcher, consultant.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store