Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4de4fdf
detection(experimental): Lateral Movement via BitLocker COM Hijacking…
AAtashGar Nov 23, 2025
1439e50
Rule status changed from experimental to Production.
AAtashGar Nov 25, 2025
2605c64
Merge branch 'develop' into rule/bitlocker
patel-bhavin Dec 16, 2025
95bbfa4
Update lateral_movement_via_bitlocker_com_hijacking.yml and fix status
AAtashGar Dec 27, 2025
3fdda4e
2 drilldown_searches added
AAtashGar Jan 3, 2026
8553887
Merge branch 'develop' into rule/bitlocker
patel-bhavin Jan 9, 2026
a2b6ad4
Merge branch 'develop' into rule/bitlocker
patel-bhavin Jan 12, 2026
c75c510
Delete macro filter file
AAtashGar Jan 26, 2026
f6ffe69
Modify author and type in lateral movement detection
AAtashGar Jan 26, 2026
522c9f1
Enhance BitLocker COM Hijacking detection story
AAtashGar Jan 26, 2026
d53026d
Refactor lateral movement detection for BitLocker COM hijacking
AAtashGar Feb 2, 2026
6e8d570
Delete stories/bitlocker_com_hijacking_lateral_movement.yml
AAtashGar Feb 2, 2026
229a6cb
Merge branch 'develop' into rule/bitlocker
patel-bhavin Feb 10, 2026
9bd7ce6
YAML parsing error fixed
AAtashGar Feb 10, 2026
63c4d7a
fix: Validation Issues
AAtashGar Feb 21, 2026
0a133b7
fix tests section
AAtashGar Feb 21, 2026
fd52328
Merge branch 'develop' into rule/bitlocker
patel-bhavin Feb 23, 2026
a77da35
Merge branch 'develop' into rule/bitlocker
nasbench Mar 2, 2026
5a55867
Merge branch 'develop' into rule/bitlocker
patel-bhavin Mar 3, 2026
16b2f3b
Merge branch 'develop' into rule/bitlocker
patel-bhavin Mar 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions detections/endpoint/lateral_movement_via_bitlocker_com_hijacking.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
name: Lateral Movement via BitLocker COM Hijacking
id: 990d5907-c022-4358-9ada-f6e5e69514e8
version: 1
date: '2025-09-28'
author: AAtashGar
status: production
description: |-
This detection identifies potential lateral movement activities
using BitLocker COM hijacking techniques. It monitors for changes
to the Remote Registry service, new registry values in CLSID paths,
handle operations on CLSIDs, and executions of specific processes like
baaupdate.exe and BdeUISrv.exe. These events are correlated by host to
detect sequences indicative of this attack vector.
type: Correlation
references:
- https://medium.com/@seripallychetan/bitlocker-com-hijack-a-new-frontier-in-lateral-movement-tactics-ac5039b18dc6
- https://ipurple.team/2025/08/04/lateral-movement-bitlocker/
search: |
(`wineventlog_security`) OR (`wineventlog_system`) \
EventCode IN (7040, 4657, 4663, 4688)
[ search `wineventlog_system` EventCode=7040 service="Remote Registry"
| fields ComputerName
| dedup ComputerName
]
| where
(EventCode=7040 AND service="Remote Registry") OR
(EventCode=4657 AND Operation_Type="New registry value created"
AND Object_Name LIKE "%CLSID%") OR
(EventCode=4663 AND Object_Name LIKE "%CLSID%") OR
(EventCode=4688 AND (
(process_name="baaupdate.exe" AND parent_process_name="explorer.exe") OR
(process_name="BdeUISrv.exe" AND parent_process_name="svchost.exe")
))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be optimized by moving the filter early as well as adding conditions to the subsearch to look only for changes to the status of the service to Enabled from Disabled.

Also the field you are using are not the XML fields but the General view field. Which we do not recommend using.

Now for the condition, you are filtering for any CLSID which is not the case of the attack. But instead it targets specific CLSID. You should filter on those.

Also keep in mind that EID 4663/4657 requires a dedicated SACL in the key/value to trigger.

You need better filtering to avoid non-related matches.

| eval srvchngstsTime=if(EventCode=7040, _time, null)
| eval regvlsetTime=if(EventCode=4657, _time, null)
| eval reghandleTime=if(EventCode=4663, _time, null)
| eval procexecTime=if(EventCode=4688, _time, null)
| eval ServiceMessage=if(EventCode=7040, Message, null)
| eval ProcessName_4663=if(EventCode=4663, process, null)
| eval CLSID_Path=if(EventCode IN (4657, 4663), Object_Name, null)
| stats
values(srvchngstsTime) AS srvchngstsTime
values(regvlsetTime) AS regvlsetTime
values(reghandleTime) AS reghandleTime
values(procexecTime) AS procexecTime
values(ServiceMessage) AS ServiceMessage
values(CLSID_Path) AS CLSID_Path
values(New_Value_Type) AS New_Value_Type
values(New_Value) AS New_Value
values(Access_Mask) AS AccessMask
values(ProcessName_4663) AS ProcessName_4663
values(parent_process_id) AS parent_process_id
values(parent_process_name) AS parent_process_name
values(process_id) AS process_id
values(process_name) AS process_name
values(TimeDiff1) AS TimeDiff_Service_to_Registry
values(TimeDiff2) AS TimeDiff_Registry_to_Handle
values(TimeDiff3) AS TimeDiff_Handle_to_Process
count(eval(EventCode=7040)) AS SrvEvts
count(eval(EventCode=4657)) AS RegEvts
count(eval(EventCode=4663)) AS HdlEvts
count(eval(EventCode=4688)) AS ProcEvts
by ComputerName
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The grouping needs to also take into account a timespan to be more efficient since these events could occur unrelated. Add a time span of 10 minutes or so to be more efficient.

| where SrvEvts>0 AND RegEvts>0 AND HdlEvts>0 AND ProcEvts>0
| where isnotnull(CLSID_Path)
| eval srvchngstsTime=strftime(srvchngstsTime, "%Y-%m-%d %H:%M:%S")
| eval regvlsetTime=strftime(regvlsetTime, "%Y-%m-%d %H:%M:%S")
| eval reghandleTime=strftime(reghandleTime, "%Y-%m-%d %H:%M:%S")
| eval procexecTime=strftime(procexecTime, "%Y-%m-%d %H:%M:%S")
| table
ComputerName
srvchngstsTime
ServiceMessage
regvlsetTime
CLSID_Path
New_Value_Type
New_Value
reghandleTime
ProcessName_4663
AccessMask
procexecTime
parent_process_id
parent_process_name
process_id
process_name
| rename
ComputerName AS "Host"
CLSID_Path AS "CLSID Path"
srvchngstsTime AS "Service Change Time"
ServiceMessage AS "Service Message"
regvlsetTime AS "Registry Change Time"
New_Value_Type AS "Registry Value Type"
New_Value AS "Registry Value"
reghandleTime AS "Handle Creation Time"
AccessMask AS "Access Mask"
ProcessName_4663 AS "Process Accessing Registry"
procexecTime AS "Process Execution Time"
parent_process_name AS "Parent Process"
process_name AS "Process Name"
parent_process_id AS "Parent Process ID"
process_id AS "Process ID"
| sort - "Service Change Time"
| `lateral_movement_via_bitlocker_com_hijacking_filter`
how_to_implement: |-
Ensure Windows Event Logs are being ingested into Splunk,
particularly from the Security channel (wineventlog).
This detection requires fields like EventCode, ComputerName,
service, Operation_Type, Object_Name, process_name, parent_process_name,
Message, process, New_Value_Type, New_Value, Access_Mask, parent_process_id,
and process_id. Use Sysmon or Endpoint data models for enhanced coverage.
known_false_positives: |-
Legitimate administrative activities may trigger this detection,
such as software installations or system configurations involving
Remote Registry and BitLocker components. Tune based on environment.
drilldown_searches:
- name: View the detection results for - "$Host$"
search: '%original_detection_search% | search Host = "$Host$"'
earliest_offset: $info_min_time$
latest_offset: $info_max_time$
- name: View risk events for the last 7 days for - "$Host$"
search: '| from datamodel Risk.All_Risk | search normalized_risk_object="$Host$"
starthoursago=168 | stats count min(_time) as firstTime max(_time)
as lastTime values(search_name) as "Search Name" values(risk_message) as "Risk
Message" values(analyticstories) as "Analytic Stories" values(annotations._all)
as "Annotations" values(annotations.mitre_attack.mitre_tactic) as "ATT&CK Tactics"
by normalized_risk_object | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`'
earliest_offset: $info_min_time$
latest_offset: $info_max_time$
tags:
analytic_story:
- BitLocker COM Hijacking Lateral Movement
asset_type: Endpoint
mitre_attack_id:
- T1546.015
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
security_domain: endpoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: lateral_movement_via_bitlocker_com_hijacking_filter
definition: search *
description: Filter macro for Lateral Movement via BitLocker COM Hijacking detection
32 changes: 32 additions & 0 deletions stories/bitlocker_com_hijacking_lateral_movement.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
# Analytic Story: BitLocker COM Hijacking Lateral Movement
name: BitLocker COM Hijacking Lateral Movement
id: 9d1f4a2b-6e3c-4f7d-8a9b-1c5e7f8d3e4f
version: 1
date: '2025-11-23'
author: Ali Atashgar (AAtashGar)
status: production
description: |
Detection content for the 2025 BitLocker COM hijacking lateral
movement technique using HKCU registry manipulation
of Network Unlock COM object.
narrative: |
In August 2025, a novel lateral movement technique was published that abuses
the BitLocker Network Unlock COM object
(CLSID {A7A63E5C-3877-4840-8727-C1EA9D7A4D50}).
Attackers enable RemoteRegistry,write a malicious DLL path to InprocServer32
under HKCU\Software\Classes\CLSID for logged-on users, and trigger execution
via baaupdate.exe (from explorer.exe) or BdeUISrv.exe (from svchost.exe).
This analytic story provides detection for this advanced persistence and
lateral movement technique.
references:
- https://ipurple.team/2025/08/04/lateral-movement-bitlocker/
- https://github.com/rtecCyberSec/BitlockMove
tags:
category:
- Adversary Tactics
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
usecase: Advanced Threat Detection
Loading