Lion Cipher Lab
Detect BITS job abuse (T1197) from the BITS-Client event log
- SOC Analyst / Blue Team
- Intermediate
- ~75 min
- Free · no account required
Why it matters
BITS is the quiet download manager built into every copy of Windows. Windows Update uses it, Edge and OneDrive use it, Defender uses it -- so a download through BITS looks like the operating system doing its job. That is exactly why intruders use it: a BITS job can pull a payload over HTTP while blending into the updater noise, survive reboots, and even launch a program of the attacker's choosing when the transfer finishes. MITRE ATT&CK tracks this as T1197, and real groups and malware families use it. A SOC that alerts on 'any BITS job' drowns in Windows Update; a SOC that never looks at…
What you'll learn
- Explaining what the Background Intelligent Transfer Service (BITS) is and why attackers use it to download and persist (MITRE ATT&CK T1197)
- Reading the Microsoft-Windows-Bits-Client/Operational channel: Event ID 3 (job created, processPath) and Event ID 16403 (file added, RemoteName / LocalName)
- Joining two event types into one 'job' record by JobId, and a process-creation event to that job by display name
- Explaining how SetNotifyCmdLine turns a download job into a persistence mechanism, from Microsoft's own API documentation
- Scoring six candidate rules with precision and recall and reading the false positives and false negatives separately
- Choosing a (creator, host) pair allowlist over a domain-only allowlist, and naming the residual blind spots
Steps in this lab
- What BITS is, and why an intruder would bother with it
- Where BITS leaves evidence -- and what Microsoft does not document
- The persistence half: SetNotifyCmdLine, straight from Microsoft's documentation
- Optional: look at the real thing on your own Windows PC (read-only)
- Build the synthetic BITS fixture
- Join the events into jobs and score six rules
- Read the table like an analyst: what each rule got wrong, and why
- A real Python gotcha you just avoided: is_private is not 'RFC 1918'
- Honest limits -- what this rule cannot see
- Where this goes next