-
Notifications
You must be signed in to change notification settings - Fork 618
Description
Link to Rule
Rule Tuning Type
False Negatives - Enhancing detection of true threats that were previously missed.
Description
Summary
This rule has two gaps that allowed a DLL sideloading attack to go undetected:
- The
Downloadsfolder is missing from the suspicious paths list - The directory matching logic fails when the malicious DLL is in a subdirectory of the executable's location
Observed Technique
A Discord-distributed info stealer ("FPS_BOOSTER") used DLL sideloading with a legitimate signed Chrome binary. The package contained:
- A renamed but legitimately signed Chrome executable (
fps.exe) - A malicious unsigned
chrome_elf.dllplaced in a version-numbered subdirectory mimicking Chrome's actual directory structure
The full paths:
- Executable:
C:\Users\<user>\Downloads\<hash>\FPS_BOOSTER\fps.exe - Malicious DLL:
C:\Users\<user>\Downloads\<hash>\FPS_BOOSTER\143.0.7499.110\chrome_elf.dll
Gap 1: Missing Downloads Path
The rule's suspicious path list includes several user profile locations:
?:\Users\*\Documents\*.dll?:\Users\*\Pictures\*.dll?:\Users\*\Music\*.dll?:\Users\Public\*.dll
However, ?:\Users\*\Downloads\*.dll is not included. Downloads is a common location for malware execution, especially for socially engineered payloads distributed via Discord, email, or web downloads.
Gap 2: Subdirectory Matching
The rule uses endswith~ to verify the DLL is in the same directory as the executable:
endswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)),
substring(process.executable, 0, length(process.executable) - (length(process.name) + 1)))
However, this approach misses a real evasion technique observed in the wild. In this case:
| Component | Path |
|---|---|
| EXE directory | ...\FPS_BOOSTER\ |
| DLL directory | ...\FPS_BOOSTER\143.0.7499.110\ |
The malware mimics Chrome's legitimate directory structure, where chrome_elf.dll is stored in a version-numbered subdirectory (e.g., 122.0.6261.95\). This is an effective evasion technique because:
- It matches how the abused application (Chrome) actually organizes its files
- The DLL is still within the executable's directory tree, which is abnormal when that tree is rooted in Downloads, Documents, etc.
- Attackers can trivially bypass the current rule by adding one level of subdirectory nesting
Proposed Changes
1. Add Downloads to the suspicious paths:
"?:\\Users\\*\\Downloads\\*.dll",
2. Change endswith~ to startswith~:
startswith~(substring(dll.path, 0, length(dll.path) - (length(dll.name) + 1)),
substring(process.executable, 0, length(process.executable) - (length(process.name) + 1)))
This modification catches DLLs loaded from subdirectories of the executable's location. The existing filters (suspicious base paths, unsigned DLL, trusted process signature, recent file modification) should constrain false positives adequately.
Alternatively, this could be implemented as:
- A separate rule specifically for subdirectory sideloading
- An additional
orcondition alongside the existingendswith~check
Testing
I tested the modified rule (both changes applied) against the malicious event and it correctly identified the sideloading activity without generating additional false positives in my environment.
Additional Indicators from Sample
The malicious DLL had several suspicious characteristics visible in the event data:
| Field | Value |
|---|---|
dll.name |
chrome_elf.dll |
dll.pe.original_file_name |
engine_complete_hyper.dll |
dll.code_signature.exists |
false |
process.code_signature.subject_name |
Google LLC |
dll.Ext.windows.zone_identifier |
3 (downloaded from internet) |
The mismatch between dll.name and dll.pe.original_file_name combined with the lack of code signature could be a separate detection opportunity.
Example Data
Below is the JSON of an event that was missed by the original rule but was returned as a result when the EQL query was modified according to the above.
{
"_index": ".ds-logs-endpoint.events.library-default-2026.01.04-000003",
"_id": "AZvJnJE7X59NdgDSM33A",
"_score": 1,
"_source": {
"@timestamp": "2026-01-17T01:40:54.111Z",
"agent": {
"id": "b5dc5243-0a29-4f1a-a6ed-4aba28187df3",
"type": "endpoint",
"version": "9.2.4"
},
"data_stream": {
"dataset": "endpoint.events.library",
"namespace": "default",
"type": "logs"
},
"dll": {
"Ext": {
"load_index": 1,
"relative_file_creation_time": 1829104.1115048,
"relative_file_name_modify_time": 9.3272753,
"size": 2537984,
"windows": {
"zone_identifier": "3"
}
},
"code_signature": {
"exists": false
},
"hash": {
"sha256": "176396ca9c3ec759716a608104980ea3292c691ba4e30d85b12ebcbff3010a54"
},
"name": "chrome_elf.dll",
"origin_referrer_url": "C:\\Users\\windo\\Downloads\\bcbc71e3e09825109e11e133b94a5cf48b3289f7d868bad21975234472e30997\\FPS_BOOSTER.zip",
"path": "C:\\Users\\windo\\Downloads\\bcbc71e3e09825109e11e133b94a5cf48b3289f7d868bad21975234472e30997\\FPS_BOOSTER\\143.0.7499.110\\chrome_elf.dll",
"pe": {
"file_version": "19.9.56.5137",
"imphash": "66506cf48bfc3b0d79a8e3790223e69e",
"original_file_name": "engine_complete_hyper.dll"
}
},
"ecs": {
"version": "8.10.0"
},
"elastic": {
"agent": {
"id": "b5dc5243-0a29-4f1a-a6ed-4aba28187df3"
}
},
"event": {
"action": [
"load"
],
"agent_id_status": "verified",
"category": [
"library"
],
"created": "2026-01-17T01:40:54.111Z",
"dataset": "endpoint.events.library",
"id": "OKfbe1t8mc4FSGdC++++4bdh",
"ingested": "2026-01-17T01:40:56Z",
"kind": "event",
"module": "endpoint",
"outcome": "success",
"sequence": 27204,
"type": [
"start"
]
},
"host": {
"id": "3ed1eba3-1a30-479e-baf9-44dcf7182128",
"name": "zachs_pc",
"os": {
"type": "windows"
}
},
"message": "Endpoint DLL load event",
"process": {
"Ext": {
"code_signature": {
"exists": true,
"status": "trusted",
"subject_name": "Google LLC",
"trusted": true
}
},
"code_signature": {
"exists": true,
"status": "trusted",
"subject_name": "Google LLC",
"trusted": true
},
"entity_id": "Tezrk+2/tSp/gPup8wY+tg",
"executable": "C:\\Users\\windo\\Downloads\\bcbc71e3e09825109e11e133b94a5cf48b3289f7d868bad21975234472e30997\\FPS_BOOSTER\\fps.exe",
"name": "fps.exe",
"pid": 13788,
"uptime": 1
},
"user": {
"domain": "Zachs_PC",
"id": "S-1-5-21-2273981494-231515429-1712437157-1001",
"name": "windo"
}