During my exploration of offensive techniques, I’ve always been particularly interested in abuses of built-in Windows mechanisms. One such technique involves Background Intelligent Transfer Service (BITS) Jobs. For a solid overview of its relevance in cybersecurity, see the MITRE ATT&CK page for T1197.
However, I often feel that LOLBINs are a bit overhyped. Focusing detection solely on the use of a single binary—like bitsadmin.exe
—via process creation events leaves gaps. If an adversary skips bitsadmin
and instead uses the BITS COM interface, they can easily bypass many standard detections.
There is a lot of Sigma detection rules that you can bypass if you would avoid usage of bitsadmin:
https://github.com/SigmaHQ/sigma/tree/master/rules/windows/process_creation (ctrl+f bits). Example:
I highly recommend checkin out Pavel Yosifovich take on the topic and his code which you can use to implement this functionality:
We just established an idea that we can download files with the usage of BITS without invoking bitsadmin, the only question that is left is to check what telemetry is being generated when BITS Job is created.
I am testing the functionality with the below piece of code:
1 | #include <windows.h> |
While performing debbuging we can see all the loaded modules (COM Instance not yet created):

After 19th line of code is run we can see that bunch of new DLLs were loaded:

Especially, interesting for us is: BitsProxy.dll.
We should observe the Sysmon Image load events being generated from this activity (given the proper configuration):
https://github.com/olafhartong/sysmon-modular/blob/master/7_image_load/include_bitsproxy.xml
1 | <Sysmon schemaversion="4.40"> |
1 | Image loaded: |
So our first idea would be to detect unknown executables that are loading BitsProxy.dll
. In Sentinel we could do this with (semi-parsed ImageLoad)
1 | Event |

What’s also interesting is the fact that svchost.exe will be spawned and it will also load BitsProxy.dll
. The same svchost.exe is then responsible for downloading the content.
We will observe also this svchost.exe creating our file, however, it will only be visible by creating this temporary BITS file:
1 | File created: RuleName: - UtcTime: 2025-05-24 12:59:08.244 ProcessGuid: {F4A83506-C297-6831-F20A-000000001100} ProcessId: 13524 Image: C:\WINDOWS\System32\svchost.exe TargetFilename: C:\Windows\Tasks\BITE39A.tmp CreationUtcTime: 2025-05-24 12:59:07.873 User: NT AUTHORITY\SYSTEM |
1 | Dns query: RuleName: - UtcTime: 2025-05-24 12:59:07.944 ProcessGuid: {F4A83506-C297-6831-F20A-000000001100} ProcessId: 13524 QueryName: raw.githubusercontent.com QueryStatus: 0 QueryResults: ::ffff:185.199.108.133;::ffff:185.199.111.133;::ffff:185.199.109.133;::ffff:185.199.110.133; Image: C:\Windows\System32\svchost.exe User: NT AUTHORITY\SYSTEM |
NOTE: Sysmon Event ID 3 would also generate, it was lacking in my Sysmon Modular configuration, I would guess due to significant number of potential noise events. Still, if Event ID 22 (DNS Query) is there then Event ID 3 should also generate.
Looking for svchost.exe would seem to lead to many false positives, only interesting if you want to know if there was ANY BITS Job created, or perhaps you would want to track creation of BITS Temp files in some weird directories - like C:\Windows\Tasks\
etc.
This is very cool from the offensive point of view, as you are successfully “detaching” the download activity from your potentially malicious process.
That’s all cool and rainbows when you create your own binary, can we do it simpler? Surprisingly, the answer is yes, lol.
Yuu an simply utilize PowerShell
one liner:
1 | Start-BitsTransfer -DisplayName "BITSJOBFROMPOWERSHELL" -Source "https://raw.githubusercontent.com/olafhartong/sysmon-modular/master/7_image_load/exclude_cscript_scrobj.xml" -Destination "C:\Windows\Tasks\exclude_cscript_scrobj.xml" |
1 | <DataItem type="System.XmlData" time="2025-05-24T06:26:04.7586679-07:00" sourceHealthServiceId="A18FEB8F-23F9-A8C4-0E93-245BABEE7B44"><EventData xmlns="http://schemas.microsoft.com/win/2004/08/events/event"><Data Name="RuleName">technique_id=T1197,technique_name=BITS</Data><Data Name="UtcTime">2025-05-24 13:26:04.749</Data><Data Name="ProcessGuid">{f4a83506-c8dd-6831-6a0b-000000001100}</Data><Data Name="ProcessId">14356</Data><Data Name="Image">C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Data><Data Name="ImageLoaded">C:\Windows\System32\BitsProxy.dll</Data><Data Name="FileVersion">7.8.26100.1882 (WinBuild.160101.0800)</Data><Data Name="Description">Background Intelligent Transfer Service Proxy</Data><Data Name="Product">Microsoft® Windows® Operating System</Data><Data Name="Company">Microsoft Corporation</Data><Data Name="OriginalFileName">qmgrprxy.dll</Data><Data Name="Hashes">SHA1=DDE59105E322DD0742FD582DE685B98C731B21C0,MD5=FDC8DFDBCFDC7637CEA74CECF9D580AB,SHA256=39B245CD0BF0F27241AAAFBB317AEC0D7D01DBF7750851EEF37BB319255C214D,IMPHASH=E68B2C7E33E04DC8081D5A96FEB7F59A</Data><Data Name="Signed">true</Data><Data Name="Signature">Microsoft Windows</Data><Data Name="SignatureStatus">Valid</Data><Data Name="User">unicorn\unicorn</Data></EventData></DataItem> |
Again svchost is also spawned:
1 | <DataItem type="System.XmlData" time="2025-05-24T06:26:04.7583783-07:00" sourceHealthServiceId="A18FEB8F-23F9-A8C4-0E93-245BABEE7B44"><EventData xmlns="http://schemas.microsoft.com/win/2004/08/events/event"><Data Name="RuleName">technique_id=T1197,technique_name=BITS</Data><Data Name="UtcTime">2025-05-24 13:26:04.747</Data><Data Name="ProcessGuid">{f4a83506-c8e8-6831-700b-000000001100}</Data><Data Name="ProcessId">14680</Data><Data Name="Image">C:\Windows\System32\svchost.exe</Data><Data Name="ImageLoaded">C:\Windows\System32\BitsProxy.dll</Data><Data Name="FileVersion">7.8.26100.1882 (WinBuild.160101.0800)</Data><Data Name="Description">Background Intelligent Transfer Service Proxy</Data><Data Name="Product">Microsoft® Windows® Operating System</Data><Data Name="Company">Microsoft Corporation</Data><Data Name="OriginalFileName">qmgrprxy.dll</Data><Data Name="Hashes">SHA1=DDE59105E322DD0742FD582DE685B98C731B21C0,MD5=FDC8DFDBCFDC7637CEA74CECF9D580AB,SHA256=39B245CD0BF0F27241AAAFBB317AEC0D7D01DBF7750851EEF37BB319255C214D,IMPHASH=E68B2C7E33E04DC8081D5A96FEB7F59A</Data><Data Name="Signed">true</Data><Data Name="Signature">Microsoft Windows</Data><Data Name="SignatureStatus">Valid</Data><Data Name="User">NT AUTHORITY\SYSTEM</Data></EventData></DataItem> |
The same svchost.exe creates temporary BITS file:
1 | <DataItem type="System.XmlData" time="2025-05-24T06:26:05.1491514-07:00" sourceHealthServiceId="A18FEB8F-23F9-A8C4-0E93-245BABEE7B44"><EventData xmlns="http://schemas.microsoft.com/win/2004/08/events/event"><Data Name="RuleName">-</Data><Data Name="UtcTime">2025-05-24 13:26:05.148</Data><Data Name="ProcessGuid">{f4a83506-c8e8-6831-700b-000000001100}</Data><Data Name="ProcessId">14680</Data><Data Name="Image">C:\WINDOWS\System32\svchost.exe</Data><Data Name="TargetFilename">C:\Windows\Tasks\BIT8F95.tmp</Data><Data Name="CreationUtcTime">2025-05-24 13:26:04.772</Data><Data Name="User">NT AUTHORITY\SYSTEM</Data></EventData></DataItem> |
Of course, in the situation of BITS Jobs there is Event Log Microsoft-Windows-Bits-Client/Operational
, which is superior in providing us with actual details on what has happened:
Event ID 3
1 | <DataItem type="System.XmlData" time="2025-05-24T05:59:07.8700635-07:00" sourceHealthServiceId="A18FEB8F-23F9-A8C4-0E93-245BABEE7B44"><EventData xmlns="http://schemas.microsoft.com/win/2004/08/events/event"><Data Name="jobTitle">EVIL UNICORN JOB</Data><Data Name="jobId">{7f68cced-f925-4864-9525-37b40b3496d7}</Data><Data Name="jobOwner">unicorn\unicorn</Data><Data Name="processPath">C:\Users\unicorn\source\repos\BITSD\x64\Debug\BITSD.exe</Data><Data Name="processId">12796</Data><Data Name="ClientProcessStartKey">4785074604083945</Data></EventData></DataItem> |
Event ID 16403
1 | <DataItem type="System.XmlData" time="2025-05-24T05:59:07.8893135-07:00" sourceHealthServiceId="A18FEB8F-23F9-A8C4-0E93-245BABEE7B44"><EventData xmlns="http://schemas.microsoft.com/win/2004/08/events/event"><Data Name="User">unicorn\unicorn</Data><Data Name="jobTitle">EVIL UNICORN JOB</Data><Data Name="jobId">{7f68cced-f925-4864-9525-37b40b3496d7}</Data><Data Name="jobOwner">unicorn\unicorn</Data><Data Name="fileCount">1</Data><Data Name="RemoteName">https://raw.githubusercontent.com/olafhartong/sysmon-modular/refs/heads/master/7_image_load/include_bitsproxy.xml</Data><Data Name="LocalName">C:\Windows\Tasks\evil.txt</Data><Data Name="processId">12796</Data><Data Name="ClientProcessStartKey">4785074604083945</Data></EventData></DataItem> |
To sum up:
Microsoft-Windows-Bits-Client/Operational
provides you with the best visibility- Don’t rely on process creation events for
bitsadmin
as it is quite easy to bypass. - There are quite few artifacts that are generated.
- Can do it from PowerShell too, you could also look for
4104s
. - Looking for processes that load
BitsProxy.dll
could be an interesting hunting expedition and potentially a proper detection after testing and baselining.