forked from elastic/detection-rules
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpersistence_via_shell_modification_persistence.toml
More file actions
105 lines (99 loc) · 4.16 KB
/
Copy pathpersistence_via_shell_modification_persistence.toml
File metadata and controls
105 lines (99 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
[hunt]
author = "Elastic"
description = """
This hunt identifies potential persistence mechanisms via modifications to shell profile files on Linux systems. It monitors file creation or modification events in system-wide and user-specific profile files, which can indicate attempts to establish persistence through shell modifications. It also monitors processes started by SSH daemons to detect suspicious activity related to SSH logins.
"""
integration = ["endpoint"]
uuid = "20a02fad-2a09-44c0-a8ce-ce4502859c8a"
name = "Shell Modification Persistence"
language = ["ES|QL", "SQL"]
license = "Elastic License v2"
notes = [
"Monitors for file creation or modification events in system-wide and user-specific profile files, such as /etc/profile, /etc/bash.bashrc, /home/*/.bashrc, and others.",
"Excludes modifications made by expected update processes such as package managers to reduce false positives.",
"Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.",
"Monitors processes started by SSH daemons (sshd) to detect suspicious activity related to SSH logins.",
"OSQuery query is provided to retrieve detailed file information related to profile files."
]
mitre = ["T1546.004", "T1053.005"]
query = [
'''
from logs-endpoint.events.file-*
| where @timestamp > now() - 30 day
| where host.os.type == "linux" and event.type in ("creation", "change") and (
// System-wide profile files
file.path in ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") or
file.path like "/etc/profile.d/*" or
// root-specific profile files
file.path in ("/root/.profile", "/root/.bash_profile", "/root/.bash_login", "/root/.bash_logout", "/root/.bashrc") or
// User-specific profile files
file.path like "/home/*/.profile" or
file.path like "/home/*/.bash_profile" or
file.path like "/home/*/.bash_login" or
file.path like "/home/*/.bash_logout" or
file.path like "/home/*/.bashrc"
) and not (
process.name in (
"dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon", "microdnf", "podman", "apk"
) or
process.executable == "/proc/self/exe" or
process.executable like "/dev/fd/*" or
file.extension in ("dpkg-remove", "swx", "swp")
)
| eval persistence = case(
// System-wide profile files
file.path in ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout") or
file.path like "/etc/profile.d/*" or
// root-specific profile files
file.path in ("/root/.profile", "/root/.bash_profile", "/root/.bash_login", "/root/.bash_logout", "/root/.bashrc") or
// User-specific profile files
file.path like "/home/*/.profile" or
file.path like "/home/*/.bash_profile" or
file.path like "/home/*/.bash_login" or
file.path like "/home/*/.bash_logout" or
file.path like "/home/*/.bashrc",
process.name,
null
)
| stats pers_count = count(persistence) by process.executable, file.path
| where pers_count > 0 and pers_count <= 20
| sort pers_count asc
| limit 100
''',
'''
from logs-endpoint.events.process-*
| where @timestamp > now() - 30 day
| where host.os.type == "linux" and event.type == "start" and event.action == "exec" and process.parent.name == "sshd"
| stats cc = count(*) by process.command_line
| where cc <= 20
| sort cc asc
| limit 100
''',
'''
SELECT
f.filename,
f.path,
u.username AS file_owner,
g.groupname AS group_owner,
datetime(f.atime, 'unixepoch') AS file_last_access_time,
datetime(f.mtime, 'unixepoch') AS file_last_modified_time,
datetime(f.ctime, 'unixepoch') AS file_last_status_change_time,
datetime(f.btime, 'unixepoch') AS file_created_time,
f.size AS size_bytes
FROM
file f
LEFT JOIN
users u ON f.uid = u.uid
LEFT JOIN
groups g ON f.gid = g.gid
WHERE
f.path IN ("/etc/profile", "/etc/bash.bashrc", "/etc/bash.bash_logout")
OR f.path IN ("/root/.profile", "/root/.bash_profile", "/root/.bash_login", "/root/.bash_logout", "/root/.bashrc")
OR f.path LIKE "/etc/profile.d/%"
OR f.path LIKE "/home/%/.profile"
OR f.path LIKE "/home/%/.bash_profile"
OR f.path LIKE "/home/%/.bash_login"
OR f.path LIKE "/home/%/.bash_logout"
OR f.path LIKE "/home/%/.bashrc"
'''
]