Detection rules › Elastic

Ingress DLL Transfer followed by DLL SideLoading

Time window
1m
Sequence by
dll.name, file.name
Source
github.com/elastic/protections-artifacts

Identifies the side load of an untrusted DLL by a persistent trusted binary and that was dropped by commonly abused ingress tool transfer binaries. This behavior may indicate an attempt to sideloading a malicious DLL.

MITRE ATT&CK coverage

Rule body

[rule]
description = """
Identifies the side load of an untrusted DLL by a persistent trusted binary and that was dropped by commonly abused
ingress tool transfer binaries. This behavior may indicate an attempt to sideloading a malicious DLL.
"""
id = "7543f65d-5a1a-4f88-a2d7-ddbc18672217"
license = "Elastic License v2"
name = "Ingress DLL Transfer followed by DLL SideLoading"
os_list = ["windows"]
version = "1.0.5"

query = '''
sequence with maxspan=1m
 [file where event.action != "deletion" and
   file.Ext.header_bytes : "4d5a*" and
   (
    process.name : ("MSHTA.EXE", "CertUtil.exe", "CertReq.exe", "PrintBrm.exe", "curl.exe") or
    process.executable : "?:\\Windows\\sys*\\OpenSSH\\sftp.exe"
   )] by file.name
 [library where
   (dll.Ext.relative_file_creation_time < 5000 or dll.Ext.relative_file_name_modify_time < 5000 ) and dll.name : "*.dll" and
   process.code_signature.status :"trusted" and not dll.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
   dll.hash.sha256 != null and

    /* DLL loaded from the process.executable current directory */
   endswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)), substring(process.executable, 0, length(process.executable) - (length(process.name) + 1))) and

   not process.executable :
             ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe", "?:\\Windows\\Explorer.exe", "?:\\Windows\\assembly\\*",
              "?:\\Windows\\SysWOW64\\*", "?:\\Windows\\System32\\*", "?:\\Windows\\splwow64.exe", "?:\\Windows\\Microsoft.NET\\*",
              "?:\\Windows\\Installer\\*")] by dll.name
'''

min_endpoint_version = "8.6.0"
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1

[[optional_actions]]
action = "rollback"
field = "process.entity_id"
state = 1

[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1574"
name = "Hijack Execution Flow"
reference = "https://attack.mitre.org/techniques/T1574/"
[[threat.technique.subtechnique]]
id = "T1574.001"
name = "DLL"
reference = "https://attack.mitre.org/techniques/T1574/001/"



[threat.tactic]
id = "TA0005"
name = "Defense Evasion"
reference = "https://attack.mitre.org/tactics/TA0005/"
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1105"
name = "Ingress Tool Transfer"
reference = "https://attack.mitre.org/techniques/T1105/"


[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"

[internal]
min_endpoint_version = "8.6.0"

Stages and Predicates

Ordered sequence: each step below must occur in order within 1m, correlated by dll.name, file.name.

Stage 1: file

[file where event.action != "deletion" and
   file.Ext.header_bytes : "4d5a*" and
   (
    process.name : ("MSHTA.EXE", "CertUtil.exe", "CertReq.exe", "PrintBrm.exe", "curl.exe") or
    process.executable : "?:\\Windows\\sys*\\OpenSSH\\sftp.exe"
   )] by file.name

Stage 2: library

[library where
   (dll.Ext.relative_file_creation_time < 5000 or dll.Ext.relative_file_name_modify_time < 5000 ) and dll.name : "*.dll" and
   process.code_signature.status :"trusted" and not dll.code_signature.status : ("trusted", "errorExpired", "errorCode_endpoint*") and
   dll.hash.sha256 != null and
   endswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)), substring(process.executable, 0, length(process.executable) - (length(process.name) + 1))) and
   not process.executable :
             ("?:\\Program Files\\*.exe", "?:\\Program Files (x86)\\*.exe", "?:\\Windows\\Explorer.exe", "?:\\Windows\\assembly\\*",
              "?:\\Windows\\SysWOW64\\*", "?:\\Windows\\System32\\*", "?:\\Windows\\splwow64.exe", "?:\\Windows\\Microsoft.NET\\*",
              "?:\\Windows\\Installer\\*")] by dll.name

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
dll.code_signature.statuswildcardtrusted, errorExpired, errorCode_endpoint*excludes:dll.code_signature.status field:"dll.code_signature.status" value:"trusted" field:"dll.code_signature.status" value:"errorExpired" field:"dll.code_signature.status" value:"errorCode_endpoint*"
process.executablewildcard?:\Program Files\*.exe, ?:\Program Files (x86)\*.exe, ?:\Windows\Explorer.exe, ?:\Windows\assembly\*, ?:\Windows\SysWOW64\*, ?:\Windows\System32\*, ?:\Windows\splwow64.exe, ?:\Windows\Microsoft.NET\*, ?:\Windows\Installer\*excludes:process.executable

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
dll.Ext.relative_file_creation_timelt
  • 5000 transforms: number corpus 6 (elastic 6)
field:"dll.Ext.relative_file_creation_time" kind:lt value:"5000"
dll.Ext.relative_file_name_modify_timelt
  • 5000 transforms: number corpus 6 (elastic 6)
field:"dll.Ext.relative_file_name_modify_time" kind:lt value:"5000"
dll.hash.sha256is_not_null
  • (no value, null check)
field:"Hashes" kind:is_not_null
dll.namewildcard
  • *.dll corpus 2 (elastic 2)
field:"dll.name" kind:wildcard value:"*.dll"
event.actionne
  • deletion corpus 86 (elastic 86)
field:"EventType" kind:ne value:"deletion"
file.Ext.header_byteswildcard
  • 4d5a* corpus 46 (elastic 46)
field:"file.Ext.header_bytes" kind:wildcard value:"4d5a*"
process.code_signature.statuswildcard
  • trusted corpus 6 (elastic 6)
field:"SignatureStatus" kind:wildcard value:"trusted"
process.executablewildcard
  • ?:\Windows\sys*\OpenSSH\sftp.exe corpus 3 (elastic 3)
field:"Image" kind:wildcard value:"?:\Windows\sys*\OpenSSH\sftp.exe"
process.namewildcard
  • CertReq.exe corpus 20 (elastic 20)
  • CertUtil.exe corpus 44 (elastic 38, splunk 6)
  • MSHTA.EXE corpus 84 (elastic 79, splunk 5)
  • PrintBrm.exe corpus 4 (elastic 4)
  • curl.exe corpus 34 (elastic 31, splunk 3)
field:"process_name" kind:wildcard