Skip to content

Commit 273e426

Browse files
committed
[New Hunt] Persistence via Dynamic Linker Hijacking
1 parent 2ff2965 commit 273e426

File tree

4 files changed

+201
-0
lines changed

4 files changed

+201
-0
lines changed

hunting/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Here are the queries currently available:
4040
- [OSQuery SUID Hunting](./linux/docs/privilege_escalation_via_suid_binaries.md) (ES|QL)
4141
- [Persistence Through Reverse/Bind Shells](./linux/docs/persistence_reverse_bind_shells.md) (ES|QL)
4242
- [Persistence via Cron](./linux/docs/persistence_via_cron.md) (ES|QL)
43+
- [Persistence via Dynamic Linker Hijacking](./linux/docs/persistence_via_dynamic_linker_hijacking.md) (ES|QL)
4344
- [Persistence via Message-of-the-Day](./linux/docs/persistence_via_message_of_the_day.md) (ES|QL)
4445
- [Persistence via Package Manager](./linux/docs/persistence_via_package_manager.md) (ES|QL)
4546
- [Persistence via SSH Configurations and/or Keys](./linux/docs/persistence_via_ssh_configurations_and_keys.md) (ES|QL)

hunting/index.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ linux:
220220
mitre:
221221
- T1037.004
222222
- T1546.003
223+
664d65ec-029e-4746-bf97-7bf3a0113e6a:
224+
name: Persistence via Dynamic Linker Hijacking
225+
path: ./linux/queries/persistence_via_dynamic_linker_hijacking.toml
226+
mitre:
227+
- T1574.006
223228
okta:
224229
0b936024-71d9-11ef-a9be-f661ea17fbcc:
225230
name: Failed OAuth Access Token Retrieval via Public Client App
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Persistence via Dynamic Linker Hijacking
2+
3+
---
4+
5+
## Metadata
6+
7+
- **Author:** Elastic
8+
- **Description:** This hunt identifies potential persistence mechanisms via dynamic linker hijacking on Linux systems. Attackers can manipulate environment variables like LD_PRELOAD and LD_LIBRARY_PATH to execute malicious shared libraries, hijacking the dynamic linker process for persistence or privilege escalation. This hunt monitors for suspicious usage of these environment variables, the creation of shared library files (.so), and access to critical dynamic linker configuration files.
9+
10+
- **UUID:** `664d65ec-029e-4746-bf97-7bf3a0113e6a`
11+
- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint)
12+
- **Language:** `[ES|QL, SQL]`
13+
- **Source File:** [Persistence via Dynamic Linker Hijacking](../queries/persistence_via_dynamic_linker_hijacking.toml)
14+
15+
## Query
16+
17+
```sql
18+
from logs-endpoint.events.process-*
19+
| keep @timestamp, host.os.type, event.type, event.action, process.env_vars, agent.id
20+
| where @timestamp > now() - 30 days
21+
| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
22+
process.env_vars like "LD_PRELOAD=*.so" or
23+
process.env_vars like "LD_LIBRARY_PATH=*"
24+
| stats env_count = count(process.env_vars) by agent.id, process.env_vars
25+
```
26+
27+
```sql
28+
from logs-endpoint.events.file-*
29+
| keep @timestamp, host.os.type, event.type, event.action, file.extension, file.path, process.executable, agent.id
30+
| where @timestamp > now() - 30 days
31+
| where host.os.type == "linux" and event.type == "creation" and file.extension == "so" and not (
32+
// Add your exclusions here
33+
file.path like "/run/initramfs/*" or
34+
file.path like "/var/tmp/mkinitramfs*"
35+
)
36+
| stats cc = count(), agent_count = count_distinct(agent.id) by file.path, process.executable
37+
| where agent_count <= 3
38+
| sort cc asc
39+
| limit 100
40+
```
41+
42+
```sql
43+
SELECT * FROM process_envs
44+
WHERE key = "LD_PRELOAD"
45+
OR key = "LD_LIBRARY_PATH";
46+
```
47+
48+
```sql
49+
SELECT
50+
f.filename,
51+
f.path,
52+
u.username AS file_owner,
53+
g.groupname AS group_owner,
54+
datetime(f.atime, 'unixepoch') AS file_last_access_time,
55+
datetime(f.mtime, 'unixepoch') AS file_last_modified_time,
56+
datetime(f.ctime, 'unixepoch') AS file_last_status_change_time
57+
datetime(f.btime, 'unixepoch') AS file_created_time,
58+
f.size AS size_bytes
59+
FROM
60+
file f
61+
LEFT JOIN
62+
users u ON f.uid = u.uid
63+
LEFT JOIN
64+
groups g ON f.gid = g.gid
65+
WHERE
66+
f.path = "/etc/ld.so.preload"
67+
OR f.path = "/etc/ld.so.conf"
68+
OR f.path = "/etc/ld.so.cache"
69+
OR f.path LIKE "/etc/ld.so.conf.d/%";
70+
```
71+
72+
```sql
73+
SELECT
74+
p.pid,
75+
p.name AS process_name,
76+
p.path AS process_path,
77+
p.cmdline AS command_line,
78+
pe.key AS env_key,
79+
pe.value AS env_value,
80+
(strftime('%s', 'now') - p.start_time) AS runtime_seconds
81+
FROM
82+
processes p
83+
JOIN
84+
process_envs pe ON p.pid = pe.pid
85+
WHERE
86+
pe.key IN ('LD_PRELOAD', 'LD_LIBRARY_PATH')
87+
AND (strftime('%s', 'now') - p.start_time) > 3600;
88+
```
89+
90+
## Notes
91+
92+
- Identifies processes with suspicious environment variables, specifically LD_PRELOAD and LD_LIBRARY_PATH, which are often used in dynamic linker hijacking attacks.
93+
- Monitors the creation of shared object (.so) files in non-standard or uncommon directories to detect potential malicious libraries.
94+
- Tracks modifications to critical dynamic linker files like /etc/ld.so.preload, /etc/ld.so.conf, and related directories, which are common targets for attackers.
95+
- Uses process environment variables and metadata to detect running processes that rely on suspicious linker configurations, focusing on processes that persist longer than typical short-lived tasks.
96+
- Provides complementary OSQuery queries for detailed file metadata, including file ownership and timestamps, to support forensic investigations.
97+
- This hunt leverages the process.env_vars field, which is a field that must be manually enabled within the Elastic Defend policy advanced settings tab.
98+
99+
## MITRE ATT&CK Techniques
100+
101+
- [T1574.006](https://attack.mitre.org/techniques/T1574/006)
102+
103+
## License
104+
105+
- `Elastic License v2`
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
[hunt]
2+
author = "Elastic"
3+
description = """
4+
This hunt identifies potential persistence mechanisms via dynamic linker hijacking on Linux systems. Attackers can manipulate environment variables like LD_PRELOAD and LD_LIBRARY_PATH to execute malicious shared libraries, hijacking the dynamic linker process for persistence or privilege escalation. This hunt monitors for suspicious usage of these environment variables, the creation of shared library files (.so), and access to critical dynamic linker configuration files.
5+
"""
6+
integration = ["endpoint"]
7+
uuid = "664d65ec-029e-4746-bf97-7bf3a0113e6a"
8+
name = "Persistence via Dynamic Linker Hijacking"
9+
language = ["ES|QL", "SQL"]
10+
license = "Elastic License v2"
11+
notes = [
12+
"Identifies processes with suspicious environment variables, specifically LD_PRELOAD and LD_LIBRARY_PATH, which are often used in dynamic linker hijacking attacks.",
13+
"Monitors the creation of shared object (.so) files in non-standard or uncommon directories to detect potential malicious libraries.",
14+
"Tracks modifications to critical dynamic linker files like /etc/ld.so.preload, /etc/ld.so.conf, and related directories, which are common targets for attackers.",
15+
"Uses process environment variables and metadata to detect running processes that rely on suspicious linker configurations, focusing on processes that persist longer than typical short-lived tasks.",
16+
"Provides complementary OSQuery queries for detailed file metadata, including file ownership and timestamps, to support forensic investigations.",
17+
"This hunt leverages the process.env_vars field, which is a field that must be manually enabled within the Elastic Defend policy advanced settings tab."
18+
]
19+
mitre = ["T1574.006"]
20+
21+
query = [
22+
'''
23+
from logs-endpoint.events.process-*
24+
| keep @timestamp, host.os.type, event.type, event.action, process.env_vars, agent.id
25+
| where @timestamp > now() - 30 days
26+
| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and
27+
process.env_vars like "LD_PRELOAD=*.so" or
28+
process.env_vars like "LD_LIBRARY_PATH=*"
29+
| stats env_count = count(process.env_vars) by agent.id, process.env_vars
30+
''',
31+
'''
32+
from logs-endpoint.events.file-*
33+
| keep @timestamp, host.os.type, event.type, event.action, file.extension, file.path, process.executable, agent.id
34+
| where @timestamp > now() - 30 days
35+
| where host.os.type == "linux" and event.type == "creation" and file.extension == "so" and not (
36+
// Add your exclusions here
37+
file.path like "/run/initramfs/*" or
38+
file.path like "/var/tmp/mkinitramfs*"
39+
)
40+
| stats cc = count(), agent_count = count_distinct(agent.id) by file.path, process.executable
41+
| where agent_count <= 3
42+
| sort cc asc
43+
| limit 100
44+
''',
45+
'''
46+
SELECT * FROM process_envs
47+
WHERE key = "LD_PRELOAD"
48+
OR key = "LD_LIBRARY_PATH";
49+
''',
50+
'''
51+
SELECT
52+
f.filename,
53+
f.path,
54+
u.username AS file_owner,
55+
g.groupname AS group_owner,
56+
datetime(f.atime, 'unixepoch') AS file_last_access_time,
57+
datetime(f.mtime, 'unixepoch') AS file_last_modified_time,
58+
datetime(f.ctime, 'unixepoch') AS file_last_status_change_time
59+
datetime(f.btime, 'unixepoch') AS file_created_time,
60+
f.size AS size_bytes
61+
FROM
62+
file f
63+
LEFT JOIN
64+
users u ON f.uid = u.uid
65+
LEFT JOIN
66+
groups g ON f.gid = g.gid
67+
WHERE
68+
f.path = "/etc/ld.so.preload"
69+
OR f.path = "/etc/ld.so.conf"
70+
OR f.path = "/etc/ld.so.cache"
71+
OR f.path LIKE "/etc/ld.so.conf.d/%";
72+
''',
73+
'''
74+
SELECT
75+
p.pid,
76+
p.name AS process_name,
77+
p.path AS process_path,
78+
p.cmdline AS command_line,
79+
pe.key AS env_key,
80+
pe.value AS env_value,
81+
(strftime('%s', 'now') - p.start_time) AS runtime_seconds
82+
FROM
83+
processes p
84+
JOIN
85+
process_envs pe ON p.pid = pe.pid
86+
WHERE
87+
pe.key IN ('LD_PRELOAD', 'LD_LIBRARY_PATH')
88+
AND (strftime('%s', 'now') - p.start_time) > 3600;
89+
'''
90+
]

0 commit comments

Comments
 (0)