Find a port scan and a password spray in firewall and auth logs
Practise on synthetic logs: read syslog and PAN-OS traffic fields, find a port scan and a password spray (event 4625), then link them by time and source.
Intermediate12 min read
fw traffic log (synthetic) ● time src dport act distinct ports ────────────────────────────────────── per source ▶ 02:14:01 198.51.100.41 443 allow │ 02:14:01 198.51.100.23 21 drop │ 02:14:01 198.51.100.23 22 drop │ .23 ·············· 0 02:14:02 198.51.100.88 53 allow │ 02:14:02 198.51.100.23 23 drop │ 02:14:02 198.51.100.23 445 drop │ .41 ·············· 0 02:14:03 198.51.100.41 443 allow │ 02:14:03 198.51.100.23 3389 drop │ 02:14:03 198.51.100.23 1433 drop │ .88 ·············· 0 02:14:04 198.51.100.23 5900 drop ┃ reading... $ group by src, count distinct dport $ _
On this page
- Step 1: Know the envelope (syslog, RFC 5424)
- Step 2: Learn the fields of a traffic log
- Step 3: Pattern 1, one source and many ports
- Step 4: Pattern 2, many failed logons across many accounts
- Step 5: Correlate the two stories by time and source
- Step 6: Log management, so the logs are there when you need them
- Step 7: Turn a pattern into an alert without drowning
- A pocket checklist
The first time you open a firewall traffic log, it looks like a wall of commas. Then one day it starts to read like a story: someone knocked on seven doors in four seconds, a few minutes later someone tried a dozen names at the front desk, and both were the same visitor. The data hasn't changed. What changed is that you know what each field means and which questions to ask of it.
This post is a small lab. We'll go through the structure of a syslog message, the fields that matter in a firewall traffic log, and two patterns you can practise on: a port scan and a password spray. Then we'll link the firewall and identity logs together and talk about turning a pattern into an alert that doesn't wake you up for nothing.
Every log line in this post is made up. The addresses come from the ranges the IETF reserves for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24, see RFC 5737). The hostnames, usernames and times are invented for practice. They don't come from any real network.
Step 1: Know the envelope (syslog, RFC 5424)
Most firewalls can send their logs to a collector over syslog, so it helps to know the envelope before reading the letter. RFC 5424 (March 2009) defines the modern syslog message: a HEADER, then STRUCTURED-DATA, then an optional free-text MSG. The header fields come in a fixed order:
| Field | What it holds |
|---|---|
| PRI | Priority in angle brackets: facility × 8 + severity |
| VERSION | Syslog protocol version (1) |
| TIMESTAMP | RFC 3339-style time, with an uppercase T and a Z or a numeric UTC offset |
| HOSTNAME | The machine that sent it |
| APP-NAME | The application or device that sent it |
| PROCID | Process ID, or - |
| MSGID | Message type, or - |
The hyphen is the NILVALUE: "no value here". Severity runs from 0 (Emergency) to 7 (Debug), and RFC 5424 works one example through: facility 20 (local use 4) with severity 5 (Notice) gives a PRI of 165.
Here is an invented message in that shape:
<134>1 2026-10-20T02:14:01.204Z fw-lab-01 firewall - TRAFFIC - src=198.51.100.23 dst=192.0.2.10 dport=21 action=drop
Read it left to right: PRI 134 is facility 16 (local0) × 8 + severity 6 (Informational). Then version 1, a UTC timestamp, the sending host, the app, no process ID, a message type, no structured data, and the message itself.
Two practical notes. First, the timestamp format matters later, when we line up logs from different systems. RFC 5424 makes the time zone explicit, so you're never guessing. Second, the transport matters. Plain syslog over UDP (RFC 5426, port 514) has no acknowledgement, so lost messages are simply gone, and it offers no protection against forged or observed messages. RFC 5425 runs syslog over TLS on TCP port 6514 for confidentiality, integrity and authentication. On a Palo Alto Networks firewall, the syslog server profile offers UDP, TCP or SSL, with BSD format by default and IETF as the other choice. The default is UDP on port 514 (Configure Syslog Monitoring).
Step 2: Learn the fields of a traffic log
Every vendor names things a little differently, so I keep one reference open: Palo Alto Networks' Traffic Log Fields for PAN-OS 11.1. Its log is a comma-separated line with well over a hundred positions. You don't need all of them to start. These are the ones I read first:
| Field | Why you care |
|---|---|
| Receive Time / Generated Time | Receive Time is when the management plane received the log. Generated Time is when the dataplane wrote it. Use Generated Time when building a timeline. |
| Type / Subtype | Type is TRAFFIC. The subtype is start, end, drop or deny. A drop happened before the application was identified, with no rule allowing it. A deny happened after it was identified. |
| Source / Destination Address | The original addresses of the session. |
| NAT Source IP | The translated source address, if source NAT was applied. This matters for correlation (see below). |
| Rule Name | Which security rule matched. |
| Source User | The user, if User-ID knows one. |
| Application | What App-ID decided the traffic was. |
| Source / Destination Zone | Where the traffic came from and where it was going. |
| Source / Destination Port, Protocol | The classic five-tuple pieces. |
| Action | allow, deny, drop, drop ICMP, reset both, reset client or reset server. |
| Repeat Count | How many sessions with the same source, destination, application and subtype were seen within 5 seconds. |
| Bytes, Packets, Elapsed Time | How big and how long. A run of near-zero-byte sessions tells its own story. |
| Session End Reason | Why it ended: policy-deny, tcp-rst-from-client, aged-out, tcp-fin, threat and more. |
One field deserves a warning: Repeat Count. Its definition covers source, destination, application and subtype, and the destination port isn't on that list. So before you trust a "distinct ports" count, check how your source collapses similar sessions, and count with the repeat value in mind.
Step 3: Pattern 1, one source and many ports
Here is a trimmed, invented slice of traffic log from an internal firewall between a user zone and a server zone:
generated_time src dst dport app action end_reason
2026-10-20T02:14:01Z 198.51.100.41 192.0.2.10 443 ssl allow tcp-fin
2026-10-20T02:14:01Z 198.51.100.23 192.0.2.10 21 not-applicable drop policy-deny
2026-10-20T02:14:01Z 198.51.100.23 192.0.2.10 22 not-applicable drop policy-deny
2026-10-20T02:14:02Z 198.51.100.88 192.0.2.53 53 dns allow aged-out
2026-10-20T02:14:02Z 198.51.100.23 192.0.2.10 23 not-applicable drop policy-deny
2026-10-20T02:14:02Z 198.51.100.23 192.0.2.10 445 not-applicable drop policy-deny
2026-10-20T02:14:03Z 198.51.100.41 192.0.2.10 443 ssl allow tcp-fin
2026-10-20T02:14:03Z 198.51.100.23 192.0.2.10 3389 not-applicable drop policy-deny
2026-10-20T02:14:03Z 198.51.100.23 192.0.2.10 1433 not-applicable drop policy-deny
2026-10-20T02:14:04Z 198.51.100.23 192.0.2.10 5900 not-applicable drop policy-deny
Exercise: before reading on, group these lines by source and count the distinct destination ports for each one.
fw traffic log (synthetic) ● time src dport act distinct ports ────────────────────────────────────── per source ▶ 02:14:01 198.51.100.41 443 allow │ 02:14:01 198.51.100.23 21 drop │ 02:14:01 198.51.100.23 22 drop │ .23 ·············· 0 02:14:02 198.51.100.88 53 allow │ 02:14:02 198.51.100.23 23 drop │ 02:14:02 198.51.100.23 445 drop │ .41 ·············· 0 02:14:03 198.51.100.41 443 allow │ 02:14:03 198.51.100.23 3389 drop │ 02:14:03 198.51.100.23 1433 drop │ .88 ·············· 0 02:14:04 198.51.100.23 5900 drop ┃ reading... $ group by src, count distinct dport $ _
The answer: .41 touched one port (443, twice), .88 touched one (53), and .23 touched seven different ports on the same server in about four seconds, every one of them dropped. Look at the ports, too. In the IANA port registry they belong to FTP, SSH, Telnet, Microsoft-DS (SMB), MS WBT Server (RDP), Microsoft SQL Server and Remote Framebuffer (the protocol VNC uses). Those aren't random numbers. They're common remote services.
MITRE ATT&CK calls this Network Service Discovery (T1046): adversaries try to find services running on remote hosts, including ones that may be open to remote exploitation, often with port or vulnerability scans. One of ATT&CK's analytics for it looks for exactly this shape: rapid connections from one place to many services or hosts.
There are two shapes to learn:
- Vertical: one source, one destination, many ports (what we just saw).
- Horizontal (a sweep): one source, one port, many destinations. Someone looking for every host with port 445 open.
A pattern isn't a verdict. Your vulnerability scanner makes exactly the same shape on purpose. The question to ask next is: is this source expected to do this?
Step 4: Pattern 2, many failed logons across many accounts
Now switch to identity logs. On Windows, a failed logon is event 4625, "An account failed to log on". Microsoft documents that it's logged for any logon failure, on the computer where the attempt was made. The fields that matter most for us:
- Account For Which Logon Failed → Account Name: the name that was tried.
- Logon Type: for example 2 (Interactive), 3 (Network) and 10 (RemoteInteractive, for Remote Desktop).
- Failure Information → Status / Sub Status: why it failed.
- Network Information → Source Network Address and Workstation Name: where the attempt came from.
The status codes are where the story is. The first four below come from the page's monitoring table. The last one is the Status value the page says this event typically carries, with the failure reason "Account locked out":
| Code | Meaning (per Microsoft) |
|---|---|
0xC000006D |
Bad username or authentication information |
0xC000006A |
Misspelled or bad password |
0xC0000064 |
Misspelled or bad user account (several in a row can be a sign of user enumeration) |
0xC0000072 |
Account disabled by an administrator |
0xC0000234 |
Account locked out |
Here is an invented slice from a domain controller's Security log:
time_utc event target_user status sub_status logon_type source_ip
2026-10-20T02:17:10Z 4625 alice 0xC000006D 0xC000006A 3 198.51.100.23
2026-10-20T02:17:16Z 4625 bob 0xC000006D 0xC000006A 3 198.51.100.23
2026-10-20T02:17:23Z 4625 carol 0xC000006D 0xC000006A 3 198.51.100.23
2026-10-20T02:17:29Z 4625 dave 0xC000006D 0xC000006A 3 198.51.100.23
2026-10-20T02:17:36Z 4625 erin 0xC000006D 0xC0000064 3 198.51.100.23
... (seven more accounts, one failure each in this stretch)
2026-10-20T02:18:44Z 4625 dave 0xC000006D 0xC000006A 3 198.51.100.23
2026-10-20T02:18:52Z 4625 ivan 0xC000006D 0xC000006A 3 198.51.100.23
Exercise: count the failures per account, then count the distinct accounts per source.
event 4625 (failed logon), synthetic PER-USER VIEW alice · · bob · · carol · · max fails/account ···············│0/5 dave · · erin · · frank · · lockout limit grace · · heidi · · ivan · · PER-SOURCE VIEW judy · · ken · · lena · · accounts failed ······│······ 0 alert line counting... src ◆ 198.51.100.23 $ group by src, count distinct user $ _
Per account, nobody has more than two failures, so a lockout threshold set any higher than that never fires. Per source, one address failed against twelve accounts in under two minutes. That's the signature of Password Spraying (T1110.003): one common password (or a short list) tried against many accounts, instead of many passwords against one account, precisely to avoid lockouts. ATT&CK also notes two things that make it harder to see. Adversaries may slow down to stay under detection thresholds. And spraying over LDAP or Kerberos may produce fewer of the failed-logon events that SMB attempts commonly cause, so 4625 alone may not show the whole picture.
The one 0xC0000064 line is a small bonus clue. Someone tried a username that doesn't exist, which fits a list taken from somewhere other than your directory.
Step 5: Correlate the two stories by time and source
Put the two slices side by side and the story writes itself:
- 02:14:01–02:14:04
198.51.100.23probes seven service ports on192.0.2.10, including SMB (445). - 02:17:10–02:18:52 the same address fails to log on to twelve accounts over the network (logon type 3).
NIST calls this event correlation: finding relationships between two or more log entries, most commonly with rules that match on timestamps, IP addresses and event types (SP 800-92, section 3.2).
correlate by source and time, synthetic logs 7 ports src = 198.51.100.23 fw xx·───────·────·───────·──··─···─────··──·───────── dc 4625 ───··──────··──────────────·────xxxxxxxx─xxxx──x─x─ 12 accounts ┬─────────┬─────────┬─────────┬─────────┬─────────┬ 02:14 02:15 02:16 02:17 02:18 02:19 $ join fw, dc on src within 10m $ _ clocks: NTP ●
Three things can quietly break the link, so check them before you trust a correlation:
- Clocks. SP 800-92 warns that if a host's clock is wrong, its timestamps are wrong, and gives the example of logs that suggest event A happened 45 seconds before event B when it actually happened two minutes after. Its fix is to synchronise every log source to a common time source, such as NTP.
- Time zones. One system writes local time and another writes UTC. Normalise everything to one zone (RFC 5424 timestamps carry the offset, which helps).
- NAT. If the firewall translated the source, the identity log may see the NAT Source IP, not the original. That's why that field is worth keeping in your index.
And a general caution: an IP address is a clue, not a person. Addresses get reassigned, so add user, hostname and time context before you name anyone.
Don't skip the follow-up search either. The 4625 page itself names event 4624, "An account was successfully logged on," as a related event (its example is matching the Logon ID field). After a spray, the line I most want to find is a success for the same account names from the same source. One caveat from the 4624 page: the IP address and workstation fields depend on the protocol, and network logons with Kerberos are likely to have no workstation information, while NTLM logons have no TCP/IP details.
Step 6: Log management, so the logs are there when you need them
All of this assumes the logs exist, arrived and were kept. NIST's SP 800-92, Guide to Computer Security Log Management (September 2006) is still the classic reference. NIST published a draft revision, SP 800-92 Rev. 1, Cybersecurity Log Management Planning Guide, as an initial public draft on 11 October 2023. The points I find most useful from the 2006 guide:
- The core problem is balancing limited resources against a constant flow of log data, made harder by many sources, inconsistent formats and timestamps, and growing volume.
- Decide what to log, on purpose. Its example policy items include which events each component logs and which details to record, for example username and source IP address for authentication attempts. That's exactly what Step 4 needed.
- Normalise fields, especially dates and times, so different formats can be compared.
- Aggregate. NIST's own example: a thousand entries that each record part of a scan can become one entry saying how many hosts were scanned.
- Retention vs preservation. Retention is archiving logs routinely. Preservation is keeping logs that would normally be discarded because they record activity of interest, for example during an incident.
- Integrity. Store message digests of archived logs securely so you can tell if they were changed.
On how long to keep logs, SP 800-92 doesn't give one number. It says retention should come from your requirements (laws, regulations, organisational policy) and that its example settings are a starting point, not values to adopt as-is. It also reminds you that forensic work may need data weeks or months after an event. My own rule of thumb: decide retention before the incident, because you can't go back and collect what you didn't keep.
Step 7: Turn a pattern into an alert without drowning
Spotting a pattern by eye is the lab. Doing it every minute, automatically, is the job. A few habits that keep alerts useful:
- Count distinct things, per source, per window. Distinct destination ports, distinct destination hosts, distinct failed accounts. Raw event counts punish busy-but-normal hosts. Distinct counts find the shape.
- Start with a known baseline. Firewalls ship with their own thresholds. In PAN-OS reconnaissance protection, for example, a TCP port scan triggers at 100 events within 2 seconds by default, and host sweeps use a 10-second interval (Reconnaissance Protection settings). Notice what that means: our seven-port scan would never trigger it. A slow, careful scanner can stay under any fixed threshold, so add a longer window (say, distinct ports per hour) in your SIEM as a second net.
- Exclude the scanners you own, and only those. Palo Alto's guidance on scan exclusions is to exclude only addresses of trusted internal groups that do vulnerability testing. Keep that list short and reviewed.
- Chain signals for severity. A scan alone is low. Failed logons across many accounts alone is medium. Scan, then spray, then a 4624 success from the same source is the one that should page someone.
- Use the codes. Microsoft notes that several
0xC0000064(bad user account) codes in a row can be a sign of user enumeration. Microsoft also recommends watching every 4625 for local and service accounts, because those accounts typically shouldn't be locked out. - Fix the cause, not just the alert. ATT&CK's mitigations for spraying are MFA, account use policies (including conditional access) and sensible password policies. For network service discovery they are closing unneeded services, network intrusion prevention and network segmentation. A tuned alert is good. A smaller attack surface is better.
- Test with synthetic data. Write lines like the ones in this post, feed them to your pipeline, and check that the alert fires and that the normal lines don't trigger it.
A pocket checklist
- Which field is the time, and which clock wrote it?
- Is the source original or translated (NAT)?
- Group by source: how many distinct ports, hosts or accounts?
- Does the action and end reason say blocked or allowed?
- What happened next from the same source (look for a success)?
- Is this source expected to do this (scanner, admin, monitoring)?
Once these questions are habit, the wall of commas turns into a timeline, and a timeline is something you can reason about.
Sources
- RFC 5424: The Syslog Protocol (IETF)
- RFC 5426: Transmission of Syslog Messages over UDP (IETF)
- RFC 5425: Transport Layer Security (TLS) Transport Mapping for Syslog (IETF)
- RFC 5737: IPv4 Address Blocks Reserved for Documentation (IETF)
- Palo Alto Networks: Configure Syslog Monitoring (PAN-OS 11.1)
- Palo Alto Networks: Syslog Field Descriptions (PAN-OS 11.1)
- Palo Alto Networks: Traffic Log Fields (PAN-OS 11.1)
- Palo Alto Networks: Reconnaissance Protection settings (PAN-OS 11.1)
- MITRE ATT&CK T1046: Network Service Discovery
- MITRE ATT&CK T1110.003: Brute Force: Password Spraying
- Microsoft Learn: 4625(F) An account failed to log on
- Microsoft Learn: 4624(S) An account was successfully logged on
- IANA: Service Name and Transport Protocol Port Number Registry
- NIST SP 800-92: Guide to Computer Security Log Management (publication page)
- NIST SP 800-92 (PDF)
- NIST SP 800-92 Rev. 1 (Initial Public Draft): Cybersecurity Log Management Planning Guide
Keep reading
Related posts
Network security
How to read MITRE ATT&CK without treating it as a checklist
What MITRE ATT&CK is, how tactics, techniques and procedures fit, how to read a technique page, and how to use Navigator layers without chasing 100%.
Beginner9 min read
- MITRE ATT&CK
- D3FEND
- Detection engineering
- Threat intelligence
- SOC
Network security
How a phishing email gets past SPF, DKIM and DMARC
One fictional phishing email, checked by SPF, DKIM and DMARC: what each verifies, why p=none and look-alike domains let it through, and what to do if you click.
Beginner8 min read
- Phishing
- Email security
- SPF
- DKIM
- DMARC
- MITRE ATT&CK
Network security
Five network segmentation myths, checked against CISA and NIST
VLANs alone are not segmentation. Five common myths checked against CISA, NIST and MITRE guidance, plus a default-deny rollout and ways to test it.
Beginner10 min read
- network segmentation
- microsegmentation
- zero trust
- lateral movement
- MITRE ATT&CK
- CISA
- NIST
- firewalls