The Background Intelligent Transfer Service is the same Windows component that downloads updates, which is exactly why a malicious download or callback hidden in a BITS job blends in. MITRE ATT&CK T1197 BITS Jobs covers abuse of BITS to download, execute and clean up code, and to keep a foothold through long-lived jobs. In ATT&CK v20 it maps to three tactics, Stealth, Persistence and Execution, on Windows. ATT&CK notes that BITS jobs live in the BITS job database "without new files or registry modifications" and are often permitted by host firewalls, so file and registry monitoring alone will miss them. This guide explains how BITS jobs work, what the abuse looks like in logs, how to inventory and constrain jobs, and how to remove a malicious one. It is for detection engineers, threat hunters and Windows endpoint owners. For other Windows persistence routes, see the Persistence Techniques Guide.
Key takeaways
- BITS is a scheduler as well as a downloader. A job can name a program that BITS runs when the transfer completes or fails, and BITS retries that program if it does not exit cleanly, which gives an intruder persistence without a scheduled task or service.
- The Bits-Client operational log is the best native source. Microsoft documents Event ID 3 as a new job with its owner and Event ID 59 as the start of a file transfer; on current Windows builds JPCERT/CC's testing shows Event ID 3 also carrying the creating process path and Event ID 59 the URL, so every job leaves a trail even when nothing touches the file system.
- Look at what BITS starts. ATT&CK's detection strategy looks for a notify command launched from the BITS service host (
svchost.exe -k netsvcs -s BITS); a script host or shell as the child is a strong signal. - Do not disable BITS. Windows itself uses BITS for updates. Constrain it instead: shorter job lifetimes through Group Policy, egress filtering and application control.
- Inventory needs administrator rights. Only an elevated session can list other users' jobs (
Get-BitsTransfer -AllUsers), so hunts must run with admin context or through your EDR.
How BITS works and how it is abused
Microsoft describes BITS as a service that transfers files between a client and HTTP web servers or SMB file shares in the background, using idle bandwidth and resuming automatically after network interruptions and reboots. It is exposed through a COM interface, PowerShell cmdlets and the BITSAdmin command-line tool. Each transfer is a job holding one or more files.
| Abuse pattern | BITS feature used | Related ATT&CK technique | What defenders see |
|---|---|---|---|
| Download a tool or payload | Download job from an HTTP(S) URL or SMB share | T1105 Ingress Tool Transfer | Bits-Client Event IDs 3, 59, 60, 4; network connection from the BITS service; a new file in an unusual folder |
| Execute on completion | Notify command line set on the job | T1197 (execution) | A process started by the BITS service host |
| Persist | Long-lived jobs; notify program re-run after a non-zero exit; jobs survive reboots | T1197 (persistence) | Jobs that never complete, or that keep erroring and retrying |
| Exfiltrate | Upload or upload-reply job | T1048 Exfiltration Over Alternative Protocol | Outbound transfer from the BITS service to an unfamiliar host |
| Clean up | The notify program deletes artefacts after running | T1070 Indicator Removal | Short-lived files; delete events after a BITS-launched process |
The notify command line
The persistence and execution value of BITS comes from one API method, IBackgroundCopyJob2::SetNotifyCmdLine. Microsoft's reference documents the behaviour defenders need to know:
- When it runs: when the job enters the transferred or error state. BITS runs it even if the method was called after that event.
- Retries: the program should return exit code 0. If it does not, and has not completed or cancelled the job, BITS runs it again after the job's minimum retry delay. A program that deliberately never succeeds therefore runs repeatedly.
- Account: BITS starts the program with
CreateProcessAsUserin the context of the user who set it. Jobs owned by service accounts (NetworkService, LocalSystem, LocalService) do not run command-line callbacks at all. - Paths: BITS does not use the search path or expand environment variables, so legitimate notify commands use full paths. Script callbacks typically name a script host as the program.
Because the callback runs as the job owner, a job created by an administrator runs its callback with administrator rights. Job lifetimes matter too: ATT&CK notes the default maximum lifetime is 90 days and can be extended, and Microsoft's Group Policy reference sets both the inactivity timeout and the maximum download time to 90 days by default.
Detection
| Source | Event or field | What it shows | Use |
|---|---|---|---|
| Microsoft-Windows-Bits-Client/Operational | Event ID 3 | Job created with its owner (Microsoft); creating process path also shown in JPCERT/CC's testing | Alert when the creating process is a shell, script host or Office application |
| Microsoft-Windows-Bits-Client/Operational | Event ID 59 and 60 | Transfer started and stopped, with the file and, for 60, the status code (Microsoft); URL shown in JPCERT/CC's testing | Compare URLs with known update and software distribution hosts |
| Microsoft-Windows-Bits-Client/Operational | Event ID 4 | Transfer completed, owner and file count (per JPCERT/CC testing) | Close the loop on job lifetime |
| Security 4688 or Sysmon Event ID 1 | Process creation | bitsadmin.exe with job-creation or notify arguments; children of the BITS service host | Highest value rule: unexpected child of svchost.exe -k netsvcs -s BITS |
| PowerShell logging | Event IDs 4103 and 4104 | BITS cmdlets such as Start-BitsTransfer in module and script block logs | Catches jobs created without BITSAdmin; see the PowerShell Security Guide |
| Sysmon Event IDs 3 and 22 | Network connection and DNS query | Destinations contacted by the BITS service | Domain age and reputation checks |
| System log | Event ID 7036 | Service state changes | Context for BITS starting on demand |
Microsoft's event reference covers Event IDs 3, 59 and 60; the JPCERT/CC tool analysis sheet for BITS (a national CERT, used here as a secondary source) shows the Event ID 3, 59, 60 and 4 sequence for a job created from PowerShell, and notes the job state files under C:\ProgramData\Microsoft\Network\Downloader\, which forensic tools parse to recover past jobs.
Rules worth building first:
- Unexpected child of the BITS service: any process other than known updater binaries whose parent is the BITS service host. In most estates this is close to zero, so it can alert directly.
- Job creation by interactive tools: Event ID 3 where the process is
bitsadmin.exe,powershell.exe,cmd.exe, a script host or an Office process. - Unfamiliar URLs: Event ID 59 URLs outside an allow list of update, CDN and internal distribution hosts, raw IP addresses, or newly registered domains.
- Long-lived or failing jobs: jobs present in successive inventories for days, or jobs repeatedly in an error state.
- Uploads: any upload job from a workstation, which is rare in normal use.
Many legitimate products use BITS, so baseline first: run an estate-wide inventory, record which processes create jobs and which hosts they contact, then alert on anything new. The Living off the Land Guide covers the general approach to built-in tool abuse.
Hunting and inventory
- List all jobs: from an elevated session or through your EDR, run
Get-BitsTransfer -AllUserson each host. Microsoft documents that the parameter returns jobs for all users and requires administrative credentials. - Record the useful fields: owner, display name, job state, creation time, file URLs and local paths, and any notify command.
- Flag: jobs with a notify command that is not a known updater, jobs with remote URLs outside the allow list, local destinations in user profile or temporary folders, and jobs older than your intended lifetime.
- Look back: search retained Bits-Client logs for Event ID 3 by unusual creating processes over the last 90 days, the default job lifetime.
Prevention and hardening
| Control | ATT&CK mitigation | How | Trade-off |
|---|---|---|---|
| Shorten job lifetime | M1028 Operating System Configuration | Group Policy for BITS: lower JobInactivityTimeout and MaxDownloadTime (both default 90 days, stored under HKLM\Software\Policies\Microsoft\Windows\BITS) | Very large legitimate downloads on slow links may need longer; test with your update tooling |
| Limit job counts | M1028 | MaxJobsPerUser (default 60) and MaxJobsPerMachine (default 300); Microsoft notes these do not apply to administrators or service accounts | Limited effect against admin-level intruders |
| Egress filtering | M1037 Filter Network Traffic | Route BITS traffic through a proxy and allow only known update and distribution hosts from servers | Needs an allow list maintained with software teams |
| Restrict BITS access | M1018 User Account Management | Remove standing local admin so jobs and callbacks run in limited user context | Wider admin-rights programme |
| Application control | Not a T1197 mitigation in ATT&CK, but limits what a callback can run | Block script hosts and binaries in user-writable paths; see the App Control for Business (WDAC) guide | Audit mode and tuning first |
Our recommendation: do not stop or disable the BITS service on Windows clients, because Windows Update and many management tools depend on it. On servers that receive updates from an internal source, a short job lifetime plus a strict egress allow list removes most of the abuse value.
Choosing where to start
- Small organisation: turn on the Bits-Client operational log collection in your EDR or log agent, and run a monthly
-AllUsersinventory with a review of notify commands. - SOC with a SIEM: deploy the "unexpected child of the BITS service" rule first, then Event ID 59 URL allow-listing.
- Servers and high-value hosts: enforce egress allow lists; BITS from a domain controller or database server to the internet should not happen.
- Mature hunting teams: correlate Event ID 3 creating process, Event ID 59 URL and any resulting child process into one detection chain, as ATT&CK's detection strategy describes.
Implementation: a phased rollout
- Collect (week 1): forward Microsoft-Windows-Bits-Client/Operational, process creation and PowerShell logs from all Windows endpoints. See the Windows Event Forwarding Guide.
- Baseline (weeks 2 to 3): inventory jobs across the estate and build allow lists of creating processes, URLs and notify programs.
- Detect in alert-only mode (weeks 3 to 4): run the rules above, record false positives from updaters and software agents, and tune by signed path.
- Harden (week 5 onwards): apply the BITS Group Policy values to a pilot ring, confirm Windows Update and software distribution still complete, then roll out. Rollback is setting the policy back to Not configured.
- Exercise: create a benign test job with a notify command on a test host and measure detection time.
Removing a malicious job
- Preserve: export the job details with
Get-BitsTransfer -AllUsersoutput and copy the BITS state files and Bits-Client log before changes. - Cancel the job: remove it with
Remove-BitsTransferfrom an elevated session, then confirm it is gone from the inventory. - Remove what it delivered: delete downloaded files and investigate any process the notify command started, including other persistence it may have created.
- Find the owner: the job owner account was used by the intruder; reset its credentials and review its other activity.
- Sweep the estate: search for the same URL, file name or notify command on other hosts.
Where identity fits
A BITS job runs its callback as the account that created it, and administrator-owned jobs can be listed and changed only by administrators. That makes the job owner the key identity fact in every investigation: a job owned by a deployment service account or a shared local administrator points to a credential that may be in use elsewhere. Unique local administrator passwords and removing standing admin rights limit both the reach and the privilege of BITS callbacks. See the Local Administrator Password Solution (LAPS) Guide.
Measuring it
- Log coverage: percentage of Windows endpoints forwarding the Bits-Client operational log.
- Unknown jobs: jobs per inventory cycle with a creating process, URL or notify command outside the allow list (target zero unexplained).
- Job age: number of jobs older than your intended lifetime.
- Egress exceptions: BITS connections from servers to destinations outside the allow list.
- Time to detect: from test job creation to alert in exercises.
Common failure patterns
- Not collecting the Bits-Client log: it is an operational channel that many log pipelines skip, which removes the best native evidence.
- Hunting without elevation: a non-admin inventory shows only the current user's jobs and gives false reassurance.
- Allow-listing svchost: broad exclusions for
svchost.exenetwork activity hide every BITS transfer. - Disabling BITS outright: breaks updates and management tools, so it is quietly re-enabled and nobody tunes the real controls.
- Removing the file but not the job: a job with a notify command and a failing program keeps re-running it.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| MITRE ATT&CK v20 | T1197 BITS Jobs; mitigations M1028, M1037, M1018 | Technique definition and mitigations |
| NIST SP 800-53 Rev. 5 | CM-7 Least Functionality; SC-7 Boundary Protection; SI-4 System Monitoring; AU-2 Event Logging; AC-6 Least Privilege | Constrain the service, filter egress, log and monitor jobs |
| NIST CSF 2.0 | DE.CM-09 monitoring computing hardware and software; DE.AE-02 analysing adverse events | Detection and analysis |
Practitioner checklist
- Forward Microsoft-Windows-Bits-Client/Operational from every Windows endpoint.
- Alert on unexpected child processes of the BITS service host.
- Alert on BITS jobs created by shells, script hosts or Office processes.
- Allow-list BITS URLs and investigate everything else, especially raw IPs and uploads.
- Run elevated
Get-BitsTransfer -AllUsersinventories and review notify commands. - Shorten
JobInactivityTimeoutandMaxDownloadTimeafter testing with update tooling. - Enforce egress allow lists for BITS on servers.
- When evicting, cancel the job as well as deleting its files, and reset the owner's credentials.
Standards and references
- MITRE ATT&CK: BITS Jobs (T1197)
- Microsoft: Background Intelligent Transfer Service
- Microsoft: IBackgroundCopyJob2::SetNotifyCmdLine method
- Microsoft: BITS Group Policies
- Microsoft: Get-BitsTransfer
- Microsoft: bitsadmin
- Microsoft: BITS Event ID 3 (job creation)
- Microsoft: BITS Event ID 59 (start transfer)
- Microsoft: BITS Event ID 60 (stop transfer)
- JPCERT/CC: Tool Analysis Result Sheet, BITS (secondary)
- NIST: SP 800-53 Rev. 5 Security and Privacy Controls
Related NHI Mgmt Group resources: Persistence Techniques Guide · T1105 Ingress Tool Transfer Defensive Guide · Living off the Land Guide · T1053 Scheduled Task/Job Defensive Guide · MITRE ATT&CK T1112 Modify Registry