Detection rules › Splunk

Windows Known Abused DLL Loaded Suspiciously

Status
production
Severity
medium
Group by
command_line, dest, image_loaded, process_guid, process_hash, process_id, process_name, service_dll_signature_exists, service_dll_signature_verified, signature, signature_id, user_id, vendor_product
Author
Steven Dick
Source
github.com/splunk/security_content

The following analytic detects when DLLs with known abuse history are loaded from an unusual location. This activity may represent an attacker performing a DLL search order or sideload hijacking technique. These techniques are used to gain persistence as well as elevate privileges on the target system. This detection relies on Sysmon EID7 and is compatible with all Officla Sysmon TA versions.

Known false positives

  • DLLs being loaded by user mode programs for legitimate reasons.

MITRE ATT&CK coverage

Telemetry coverage

ProviderRecord / event type
SysmonEvent ID 7: Image loaded

Rule body

name: Windows Known Abused DLL Loaded Suspiciously
id: dd6d1f16-adc0-4e87-9c34-06189516b803
version: 12
creation_date: '2024-04-06'
modification_date: '2026-05-13'
author: Steven Dick
status: production
type: TTP
description: The following analytic detects when DLLs with known abuse history are loaded from an unusual location. This activity may represent an attacker performing a DLL search order or sideload hijacking technique. These techniques are used to gain persistence as well as elevate privileges on the target system. This detection relies on Sysmon EID7 and is compatible with all Officla Sysmon TA versions.
data_source:
    - Sysmon EventID 7
search: '`sysmon` ImageLoaded EventCode=7 NOT ImageLoaded IN ("*\\Program Files*","*\\system32\\*", "*\\syswow64\\*","*\\winsxs\\*","*\\wbem\\*") | stats count min(_time) as firstTime max(_time) as lastTime by Image ImageLoaded dest process_exec process_guid process_hash process_id process_path service_dll_signature_exists service_dll_signature_verified signature signature_id user_id vendor_product loaded_file | rename Image as process | eval process_name = case(isnotnull(process),replace(process,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)","")), loaded_file_path = case(isnotnull(loaded_file), replace(loaded_file, "(:[\w\. ]+)", "")), loaded_file = case(isnotnull(loaded_file),replace(loaded_file,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)","")), user = case(NOT user IN ("-"), replace(user, "(.*)\\\(.+)$","\2")) | lookup hijacklibs_loaded library AS loaded_file OUTPUT islibrary comment as desc | lookup hijacklibs_loaded library AS loaded_file excludes as loaded_file_path OUTPUT islibrary as excluded | search islibrary = TRUE AND excluded = false | stats count min(_time) as firstTime max(_time) as lastTime by dest loaded_file loaded_file_path process process_exec process_guid process_hash process_id process_name process_path service_dll_signature_exists service_dll_signature_verified signature signature_id user_id vendor_product | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `windows_known_abused_dll_loaded_suspiciously_filter`'
how_to_implement: The following analytic requires Sysmon operational logs to be imported, with EID7 being mapped to the process_name field. Modify the sysmon macro as needed to match the sourcetype or add index.
known_false_positives: DLLs being loaded by user mode programs for legitimate reasons.
references:
    - https://attack.mitre.org/techniques/T1574/002/
    - https://hijacklibs.net/api/
    - https://wietze.github.io/blog/hijacking-dlls-in-windows
    - https://github.com/olafhartong/sysmon-modular/pull/195/files
finding:
    title: The module [$loaded_file$] was loaded from an unusual location.
    entity:
        field: dest
        type: system
        score: 50
analytic_story:
    - SolarWinds WHD RCE Post Exploitation
    - Windows Defense Evasion Tactics
    - Living Off The Land
asset_type: Endpoint
mitre_attack_id:
    - T1574.001
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: endpoint
security_domain: endpoint

Stages and Predicates

Stage 1: search

`sysmon` ImageLoaded EventCode=7 NOT ImageLoaded IN ("*\\Program Files*","*\\system32\\*", "*\\syswow64\\*","*\\winsxs\\*","*\\wbem\\*")

Stage 2: stats

| stats count min(_time) as firstTime max(_time) as lastTime by Image ImageLoaded dest process_exec process_guid process_hash process_id process_path service_dll_signature_exists service_dll_signature_verified signature signature_id user_id vendor_product loaded_file

Stage 3: rename

| rename Image as process

Stage 4: eval

| eval process_name = case(isnotnull(process),replace(process,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)","")), loaded_file_path = case(isnotnull(loaded_file), replace(loaded_file, "(:[\w\. ]+)", "")), loaded_file = case(isnotnull(loaded_file),replace(loaded_file,"(.*\\\)(?=.*(\.\w*)$|(\w+)$)","")), user = case(NOT user IN ("-"), replace(user, "(.*)\\\(.+)$","\2"))
loaded_file =
elsereplace(loaded_file, "(.*\\\)(?=.*(\.\w*)$|(\w+)$)", "")
loaded_file_path =
elsereplace(loaded_file, "(:[\w\. ]+)", "")
process_name =
elsereplace(process, "(.*\\\)(?=.*(\.\w*)$|(\w+)$)", "")
user =
elsereplace(user, "(.*)\\\(.+)$", "\2")

Stage 5: lookup

| lookup hijacklibs_loaded library AS loaded_file OUTPUT islibrary comment as desc
Lookup table
hijacklibs_loaded
Key field
library as loaded_file
Output columns
['islibrary', 'islibrary'], ['comment', 'desc']

Stage 6: lookup

| lookup hijacklibs_loaded library AS loaded_file excludes as loaded_file_path OUTPUT islibrary as excluded
Lookup table
hijacklibs_loaded
Key field
library as loaded_file
Output columns
['islibrary', 'excluded']

Stage 7: search

| search islibrary = TRUE AND excluded = false

Stage 8: stats

| stats count min(_time) as firstTime max(_time) as lastTime by dest loaded_file loaded_file_path process process_exec process_guid process_hash process_id process_name process_path service_dll_signature_exists service_dll_signature_verified signature signature_id user_id vendor_product

Stage 9: search

| `security_content_ctime(firstTime)`

Stage 10: search

| `security_content_ctime(lastTime)`

Stage 11: search

| `windows_known_abused_dll_loaded_suspiciously_filter`

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
ImageLoadedin"*\\Program Files*", "*\\system32\\*", "*\\syswow64\\*", "*\\wbem\\*", "*\\winsxs\\*"excludes:ImageLoaded

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
EventCodeeq
  • 7 corpus 41 (splunk 39, elastic 1, kusto 1)
field:"EventID" kind:eq value:"7"
excludedeq
  • false
field:"excluded" kind:eq value:"false"
islibraryeq
  • TRUE corpus 3 (splunk 3)
field:"islibrary" kind:eq value:"TRUE"

Search terms

These SPL tokens match against raw event text.

StageTerm
1ImageLoaded