Skip to content

detection Lateral Movement via BitLocker COM Hijacking#3801

Draft
AAtashGar wants to merge 20 commits intosplunk:developfrom
AAtashGar:rule/bitlocker
Draft

detection Lateral Movement via BitLocker COM Hijacking#3801
AAtashGar wants to merge 20 commits intosplunk:developfrom
AAtashGar:rule/bitlocker

Conversation

@AAtashGar
Copy link

Add detection for BitLocker COM Hijacking Lateral Movement (T1546.015)

What does this PR do?

Adds a new experimental ESCU detection + analytic story for the novel BitLocker Network Unlock COM Object Hijacking technique published in August 2025.

This living-off-the-land lateral movement method:

  • Enables RemoteRegistry service
  • Writes a malicious DLL path to HKCU\Software\Classes\CLSID\{A7A63E5C-3877-4840-8727-C1EA9D7A4D50}\InprocServer32
  • Triggers code execution via baaupdate.exe (from explorer.exe) or BdeUISrv.exe (from svchost.exe)

This is the first public detection covering this advanced technique.

Files added:

  • detections/endpoint/lateral_movement_bitlocker_com_hijacking.yml
  • macros/lateral_movement_bitlocker_com_hijacking_filter.yml
  • stories/bitlocker_com_hijacking_lateral_movement.yml

Screenshots

Screenshot 2025-11-23 at 20-40-39 Search Splunk 10 0 1

Checklist

  • Validate name matches <platform>_<mitre att&ck technique>_<short description> nomenclature
  • [CI/CD](https://github.com/splunk/security_content/actions) jobs passed (local contentctl validate --path . → No issues)
  • Validated SPL logic (tested on simulated events)
  • Validated tags, description, how_to_implement, known_false_positives
  • Verified references match analytic
  • No lookup updates — N/A
  • All lines < 80 characters, yamllint clean

Testing Performed

→ Validation Completed - No issues detected!

→ All files valid

@nasbench
Copy link
Contributor

Hey @AAtashGar before reviewing this. Just wanted to ask any particular reason you want this as experimental instead of production. From your screenshot it looks like you have the data already.

Simply export it as raw and then upload it to https://github.com/splunk/attack_data as LFS with a corresponding yaml definition. (See old PRs for reference).

Or if you want you could upload the raw logs here and we will take care of it, if we deem the rule ineteresting.

@nasbench nasbench added the WIP DO NOT MERGE Work in Progress label Nov 25, 2025
@AAtashGar
Copy link
Author

Dear @nasbench
Regarding experimental vs production: I marked it experimental because it's a novel technique (first public detection) and I used simulated data from BitlockMove repo for testing. But you're right — I have the raw logs ready. I'll export them and create a PR to splunk/attack_data with YAML definition.

Should I change status to production after adding the data? Happy to upload raw logs here if needed.

Let me know if there's anything else!

@nasbench
Copy link
Contributor

@AAtashGar in this repo context. Production means tested rules aka with logs and experimental means untested. So yes once you upload the data to attack data and Link it you can switch the status and I can start reviewing it.

Cheers

@AAtashGar
Copy link
Author

@nasbench Perfect, thanks for clarifying! Got it
I'll export the raw logs and create a PR to splunk/attack_data, After that, I'll update the status to production and push the change. Looking forward to your review
Thank you

@AAtashGar
Copy link
Author

@nasbench Done! attack_data PR created with LFS logs and YAML definition:
splunk/attack_data#1098

Status changed to production in detection file and pushed.

Ready for review — thanks!

@AAtashGar AAtashGar changed the title detection(experimental): Lateral Movement via BitLocker COM Hijacking detection Lateral Movement via BitLocker COM Hijacking Nov 25, 2025
@nasbench nasbench self-assigned this Dec 12, 2025
@github-actions github-actions bot removed the Macros label Jan 26, 2026
Expanded the analytic story to provide detailed detection strategies for BitLocker COM hijacking lateral movement, including MITRE ATT&CK mappings and recommendations for monitoring and prevention.
@AAtashGar
Copy link
Author

Thanks for your help, I changed the things you said, I hope I understood the change regarding the author correctly
I appreciate you taking the time to help me merge this request.
@patel-bhavin

Comment on lines +19 to +33
(`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
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.

Comment on lines +41 to +63
| 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
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.

@github-actions github-actions bot removed the Stories label Feb 2, 2026
@AAtashGar
Copy link
Author

Thanks for your advice, I checked and corrected everything.
@nasbench

patel-bhavin and others added 2 commits February 10, 2026 10:35
YAML parsing error fixed (indent in search block), added ---, changed to LF line endings. CI should pass now. Ready for re-review!
@nasbench nasbench added this to the v5.23.0 milestone Feb 17, 2026
@patel-bhavin patel-bhavin removed this from the v5.23.0 milestone Mar 3, 2026
@nasbench nasbench marked this pull request as draft March 3, 2026 14:07
Copy link
Contributor

@nasbench nasbench left a comment

Choose a reason for hiding this comment

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

Will be moving this to draft, until you fix these issues

Comment on lines +21 to +22
Message="The start type of the Remote Registry service was changed*") \
OR (EventCode=4657 AND OperationType="New registry value created" AND \
Copy link
Contributor

Choose a reason for hiding this comment

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

You are using both Message / OperationType as strings which they do not exist in this form while ingesting XML.

The message is not a field in the XML and the OperationType is usually encoded in the form %%XXX.

You cheated the logs in attack data, while you were asked to change it to XML.

You have to upload new logs that reflect the actual XML export splunk/attack_data#1098

You also have to adapt the search to use those values.

Comment on lines +157 to +169
tests:
- name: True Positive Test security log
attack_data:
- data:
https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546.015/bitlocker_com_hijacking/windows-security.log
source: XmlWinEventLog:security
sourcetype: XmlWinEventLog
- name: True Positive Test system log
attack_data:
- data:
https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546.015/bitlocker_com_hijacking/windows-system.log
source: XmlWinEventLog:system
sourcetype: XmlWinEventLog
Copy link
Contributor

Choose a reason for hiding this comment

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

Also since you are looking at the logs at once. They have to be in the same file. Do not split them.

@patel-bhavin
Copy link
Contributor

Hello @AAtashGar - the yaml is still missing some keys and hence its failing on CI : I have attempted to fix the yaml formatting such that it atleast passes build and yaml validation CI jobs. However, this detection is not passing unit-testing : looks like the attack_data link does not have the required data for the base search either.

@patel-bhavin
Copy link
Contributor

fixed yaml : please check this updated yaml and share relevant dataset!

name: Lateral Movement via BitLocker COM Hijacking
id: 990d5907-c022-4358-9ada-f6e5e69514e8
version: 1
date: '2025-09-28'
author: Ali Atashgar (AAtashGar), Github Community
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: TTP
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=7040 AND Service_Name="Remote Registry" AND
    Message="The start type of the Remote Registry service was changed*")
    OR (EventCode=4657 AND OperationType="New registry value created" AND
    ObjectName="*A7A63E5C-3877-4840-8727-C1EA9D7A4D50*")
    OR (EventCode=4663 AND ObjectName="*A7A63E5C-3877-4840-8727-C1EA9D7A4D50*")
    OR (EventCode=4688 AND ((NewProcessName="baaupdate.exe" AND
    ParentProcessName="explorer.exe") OR (NewProcessName="BdeUISrv.exe" AND
    ParentProcessName="svchost.exe"))))

    | eval Service_Change_Time=if(EventCode=7040, _time, null)
    | eval Registry_Change_Time=if(EventCode=4657, _time, null)
    | eval Handle_Creation_Time=if(EventCode=4663, _time, null)
    | eval Process_Execution_Time=if(EventCode=4688, _time, null)
    | eval Service_Message=if(EventCode=7040, Message, null)
    | eval Process_Accessing_Registry=if(EventCode=4663, ProcessName, null)
    | bin _time span=10m
    | stats
        values(Service_Change_Time) AS Service_Change_Time
        values(Service_Message) AS Service_Message
        values(Registry_Change_Time) AS Registry_Change_Time
        values(ObjectName) AS CLSID_PATH
        values(NewValue) AS Registry_value
        values(NewValueType) AS Registry_Value_Type
        values(Handle_Creation_Time) AS Handle_Creation_Time
        values(Process_Accessing_Registry) AS Process_Accessing_Registry
        values(Process_Execution_Time) AS Process_Execution_Time
        values(ProcessId) AS ParentProcessId
        values(ParentProcessName) AS ParentProcessName
        values(NewProcessId) AS NewProcessId
        values(NewProcessName) AS NewProcessName
        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 Computer
    | where SrvEvts>0 AND RegEvts>0 AND HdlEvts>0 AND ProcEvts>0
    | eval Service_Change_Time=strftime(Service_Change_Time, "%Y-%m-%d %H:%M:%S")
    | eval Registry_Change_Time
    =strftime(Registry_Change_Time, "%Y-%m-%d %H:%M:%S")
    | eval Handle_Creation_Time
    =strftime(Handle_Creation_Time, "%Y-%m-%d %H:%M:%S")
    | eval Process_Execution_Time
    =strftime(Process_Execution_Time, "%Y-%m-%d %H:%M:%S")
    | 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),and System channel (for EventCode 7040).
    This detection requires fields like EventCode, ComputerName, Service_Name,
    OperationType, ObjectName, NewProcessName, ParentProcessName, Message,
    ProcessName, NewValue, NewValueType, ProcessId,ParentProcessId,
    and count values from stats.
    Use Sysmon or Endpoint data models for enhanced coverage.
    For Event IDs 4657 and 4663 (registry modifications and access attempts),
    auditing must be enabled as these events are not logged by default.
    Follow these steps to configure auditing
    1. **Enable Object Access Auditing in Group Policy or Local Security Policy:**
     - Open Local Security Policy (secpol.msc) or Group Policy Editor (gpedit.msc)
     - Navigate to Computer Configuration > Windows Settings > Security Settings >
       Advanced Audit Policy Configuration > Audit Policies > Object Access.
     - Enable "Audit Registry" for Success and Failure
     (or specifically "Audit Handle Manipulation" and "Audit Kernel Object"
     if needed for finer control).
    2. **Set System Access Control List (SACL) on the specific registry key:**
     - Open Registry Editor (regedit.exe) as Administrator.
     - Navigate to the target key:
     HKCU\Software\Classes\CLSID\{A7A63E5C-3877-4840-8727-C1EA9D7A4D50}
       (or the relevant subkeys where changes are expected).
     - Right-click the key > Permissions > Advanced > Auditing tab.
     - Click "Add" > Select Principal
     (e.g., "Everyone" or a specific user/group for broader monitoring).
     - Set Type to "Success" and "Failure".
     - Check permissions to audit, such as "Set Value", "Create Subkey", "Delete",
     "Query Value", "Enumerate Subkeys",and "Write DAC"
     (adjust based on the attack vector; at minimum, include "Set Value" for 4657
     and access operations for 4663).
     - Apply the changes. This SACL must be set on the exact keys/values
     to generate events 4657 (for value modifications)
     and 4663 (for handle access).
    **Important Note on HKCU:**
      Since this registry path is located under **HKEY_CURRENT_USER (HKCU)**,
      the SACL is user-specific and applies only to the currently
      logged-on user profile.
      To ensure comprehensive coverage on multi-user systems
     (e.g., Terminal Servers, Remote Desktop Session Hosts,or shared workstations)
     this SACL configuration must be applied **for each user profile**
     that needs to be monitored.
     - One common approach is to log in as each relevant user
       (or use a script/tool like PowerShell
       with scheduled tasks or logon scripts)
       to set the SACL in their HKCU hive.
     - For domain environments, consider using Group Policy Preferences
       (Registry) or logon scripts to automate applying these
       auditing settings per user.
     - If monitoring all users is impractical, prioritize high-risk or
     privileged accounts.
    Note SACLs are object-specific and do not propagate
    unless inheritance is enabled.For domain-wide deployment,
    use Group Policy to apply these settings where possible.
    Test the configuration by simulating registry changes
    (as the target user) to verify events are generated in the Security log.
    For EventCode 7040 (service changes), ensure "Audit System Events"
    is enabled under Audit Policies > System Audit Policies > System.
    Without these auditing configurations,
    the detection will not trigger for registry-related events.
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.
references:
    - https://attack.mitre.org/techniques/T1546/015/
drilldown_searches:
    - name: View the detection results for - "$Computer$"
      search: '%original_detection_search% | search  Computer = "$Computer$"'
      earliest_offset: $info_min_time$
      latest_offset: $info_max_time$
    - name: View risk events for the last 7 days for - "$Computer$"
      search: |
        | from datamodel Risk.All_Risk | search normalized_risk_object="$Computer$"
        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$
rba:
    message: Lateral movement via BitLocker COM hijacking detected on host - [$Computer$]
    risk_objects:
        - field: Computer
          type: system
          score: 49
    threat_objects: []
tags:
    analytic_story:
        - Windows Persistence Techniques
    asset_type: Endpoint
    mitre_attack_id:
        - T1546.015
    product:
        - Splunk Enterprise
        - Splunk Enterprise Security
        - Splunk Cloud
    security_domain: endpoint
tests:
    - name: True Positive Test security log
      attack_data:
        - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546.015/bitlocker_com_hijacking/windows-security.log
          source: XmlWinEventLog:security
          sourcetype: XmlWinEventLog
    - name: True Positive Test system log
      attack_data:
        - data: https://media.githubusercontent.com/media/splunk/attack_data/refs/heads/master/datasets/attack_techniques/T1546.015/bitlocker_com_hijacking/windows-system.log
          source: XmlWinEventLog:system
          sourcetype: XmlWinEventLog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Detections WIP DO NOT MERGE Work in Progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants