From Storm Signatures to Attack Signatures
- 15 hours ago
- 5 min read
I spent years reading atmospheric data for the anomaly that didn't belong. This week I finished TryHackMe's Intro to Log Analysis room and found the same instinct waiting for me in an Apache access log — just a different kind of storm.
Log analysis is pattern recognition under time pressure. You have a wall of noise, and somewhere in it is the one line that matters. That framing is why this room felt less like learning something new and more like translating something I already knew into a new vocabulary.
Here's what the room actually taught me, the parts that surprised me, and the through-line back to the work I've been doing all along.
01 The command line is a real analysis tool
Before any SIEM, before any dashboard, the terminal is often the fastest way to interrogate a log. The room walked through a small toolkit that does a surprising amount of work: cat to read, cut to slice fields, grep to filter, awk for conditional logic, and the sort | uniq -c | sort -nr chain for frequency counting.
Working through an Apache log, four questions mapped to four one-liners. Pulling every requested URL is just field extraction:

Counting HTTP 200 responses is a conditional match on the status field:

And finding the noisiest source IP is the frequency chain — the same move you'd make to spot the host hammering an endpoint during triage:

None of this is glamorous. That's the point. When you don't have Splunk up and running, plain Linux commands still get you to an answer.
02 Regex (Regular Expression) character classes for bounded ranges
The room posed a deceptively simple question: given a pattern that matches blog post IDs 10 through 19, how would you match 20 through 29? It confused me for a minute — until I saw that the answer was a single character change.

The logic: [0-9] is a character class meaning "any one digit." You pin the tens place with a literal digit and leave the ones place open. Clean way to carve a numeric range out of noisy data — the same shape you'd use to bound a subnet octet, like 10\.0\.5[0-9]\. to catch .50 through .59.
One to remember
This trick only works cleanly inside a single tens-block. A range that straddles blocks — say 15 to 24 — needs alternation instead: 1[5-9]|2[0-4]. Worth filing away before it bites you.
03 What the attacks actually look like in a log
This was the section that landed hardest. I've read about SQL injection and cross-site scripting plenty of times. Seeing their fingerprints sitting in raw log lines is different — it makes the abstract concrete.
SQL injection
SQLi tries to smuggle database commands through input fields. In logs, it leaves telltale characters behind: single quotes, comment markers (--, #), and union statements. A query parameter carrying ' UNION SELECT is an attacker escaping the intended query and reaching for the users table. Time-based variants lean on SLEEP() or WAITFOR DELAY. And it's often URL-encoded, so decoding is part of the job.
Cross-site scripting (XSS)
XSS injects scripts that run in a victim's browser. The signature to scan for is unexpected markup in input: <script> tags and event handlers like onerror, onclick, onmouseover. A classic test payload — <script>alert(1)</script> dropped into a search parameter — is a common probe for the vulnerability.
Path traversal
Traversal attacks try to climb out of the web directory to reach files they shouldn't. The pattern is repeated ../ sequences and targets sensitive files like /etc/passwd. Because attackers URL-encode to slip past filters, it pays to know that %2E is . and %2F is /.
The common thread across all three: you're looking for input that doesn't belong. That's anomaly detection. It's the same question I asked reading a pressure field — what's here that shouldn't be, and what does it tell me is coming?
04 CyberChef, and a debugging lesson I earned the hard way

CyberChef is a browser-based "Swiss Army knife" for data — you stack operations into a recipe, and it transforms your input step by step. For SOC work, the useful ones are the extractors (IP addresses, URLs, MAC addresses) and the decoders (Base64, URL, Hex) for cracking obfuscated payloads.
One challenge hid a flag behind Base64. Straightforward: paste the string, add From Base64, read the output. Another buried a MAC address under a Base64 layer and a pile of decoy hex groups — so the recipe needed two operations stacked in order: From Base64, then Extract MAC addresses to filter the one real six-pair address out of the noise.
Then I got stuck. My output kept coming back looking exactly like my input — the same Base64 blob I started with. I nearly closed the browser and started over. The culprit turned out to be a stray To Base64 operation sitting at the bottom of my recipe, quietly re-encoding my answer right back into gibberish.
The lesson that stuck
In CyberChef, order matters and every operation runs live. When your output looks suspiciously like your input, check whether a trailing step is undoing everything upstream — same instinct as a piped shell command where the last | clobbers the rest.
05 Logs, timelines, and the bigger picture
The room also zoomed out to the landscape around raw analysis. A few pieces worth holding onto:
Log types are perspectives, not just files. Application, audit, security, server, system, network, database, web server — each one shows a different slice of the same environment. Correlating across them is where investigations actually get solved. On Linux, knowing where they live matters too: /var/log/auth.log for authentication, /var/log/apache2/access.log for web requests, /var/log/syslog for general system events.
Timelines are the backbone of incident response. A timeline is just events in chronological order — but a super timeline consolidates many sources into one view so you can trace an attacker's steps from initial compromise forward. Tools like Plaso automate building these, which is a mercy given how much manual timestamp-wrangling it would otherwise take.
Threat intel gives you something to look for. It's hard to find an anomaly if you don't know what one looks like. Feeds of known-bad IPs, file hashes, and domains turn a blind scroll into a targeted hunt — you're searching your logs for indicators someone else has already flagged.
◇ automated vs manual ◇
The comparison that stuck with me most was automated versus manual analysis — because it's exactly where a data background earns its keep.
Automated
Saves time on the heavy lifting
ML is strong at surfacing patterns and trends
But tooling is often expensive and commercial
Only as good as the model — false positives, and it can miss novel events it was never trained on
Manual
Cheap — simple Linux commands do the trick
Thorough, and reduces overfitting false positives
Contextual: the analyst understands the org
But slow, and things get missed in high volume
You need both. Automation catches the obvious at scale; the human catches what the model was never trained to see, and brings the context no tool has. That contextual, hands-on judgment is precisely the muscle a decade of data analysis builds — and it's the argument I keep making for why this transition isn't a reset; it's a redirect.
◇ takeaways ◇
The terminal is a first-class analysis tool — cut, grep, awk, and the sort | uniq -c chain go a long way before any SIEM.
Regex character classes bound ranges cleanly: pin a digit, leave [0-9] open — and reach for alternation when the range straddles blocks.
SQLi, XSS, and path traversal all reduce to the same hunt: input that doesn't belong.
In a CyberChef recipe, order is live and cumulative. Output mirroring input means a later step is undoing an earlier one.
Automated and manual analysis are partners, not rivals — and contextual judgment is where a data background becomes a security asset.
I closed the room out with the Logging Legend badge, which felt like a fair name for a week spent learning to read the story a log is telling. Same instinct I've always had for finding the anomaly in the noise. Different domain.



Comments