forked from elastic/detection-rules
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpersistence_via_systemd_timers.toml
More file actions
188 lines (180 loc) · 6.76 KB
/
Copy pathpersistence_via_systemd_timers.toml
File metadata and controls
188 lines (180 loc) · 6.76 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
[hunt]
author = "Elastic"
description = """
This hunt identifies potential persistence mechanisms via systemd (timers) on Linux systems. It monitors for file creation or modification events related to systemd service and timer configurations, as well as generators, which can indicate attempts to establish persistence through scheduled tasks.
"""
integration = ["endpoint"]
uuid = "d2d24ad6-a315-4e05-a3f9-e205eb805df4"
name = "Persistence via Systemd (Timers)"
language = ["ES|QL", "SQL"]
license = "Elastic License v2"
notes = [
"This hunt includes multiple ES|QL and OSQuery queries to identify potential persistence mechanisms via systemd timers on Linux systems.",
"Detects file creation or modification events in directories and files associated with systemd services, timers, and generators, such as /run/systemd/system, /etc/systemd/system, /etc/systemd/user, and various /usr/lib/systemd directories.",
"Excludes common legitimate processes and file types to minimize false positives.",
"Uses EVAL to tag potential persistence events and counts occurrences to identify unusual activity.",
"OSQuery queries are provided to complement the detection by retrieving detailed file information and entries related to systemd services, timers, and generators."
]
mitre = ["T1053.005", "T1546.002"]
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/user-specific services/timers (root permissions required)
file.path like "/run/systemd/system/*" or
file.path like "/etc/systemd/system/*" or
file.path like "/etc/systemd/user/*" or
file.path like "/usr/local/lib/systemd/system/*" or
file.path like "/lib/systemd/system/*" or
file.path like "/usr/lib/systemd/system/*" or
file.path like "/usr/lib/systemd/user/*" or
// user-specific services/timers (user permissions required)
file.path like "/home/*/.config/systemd/user/*" or
file.path like "/home/*/.local/share/systemd/user/*" or
// System-wide generators (root permissions required)
file.path like "/etc/systemd/system-generators/*" or
file.path like "/usr/local/lib/systemd/system-generators/*" or
file.path like "/lib/systemd/system-generators/*" or
file.path like "/etc/systemd/user-generators/*" or
file.path like "/usr/local/lib/systemd/user-generators/*" or
file.path like "/usr/lib/systemd/user-generators/*"
) and not (
process.name in (
"dpkg", "dockerd", "yum", "dnf", "snapd", "pacman", "pamac-daemon",
"netplan", "systemd", "generate"
) 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/user-specific services/timers (root permissions required)
file.path like "/run/systemd/system/*" or
file.path like "/etc/systemd/system/*" or
file.path like "/etc/systemd/user/*" or
file.path like "/usr/local/lib/systemd/system/*" or
file.path like "/lib/systemd/system/*" or
file.path like "/usr/lib/systemd/system/*" or
file.path like "/usr/lib/systemd/user/*" or
// user-specific services/timers (user permissions required)
file.path like "/home/*/.config/systemd/user/*" or
file.path like "/home/*/.local/share/systemd/user/*" or
// System-wide generators (root permissions required)
file.path like "/etc/systemd/system-generators/*" or
file.path like "/usr/local/lib/systemd/system-generators/*" or
file.path like "/lib/systemd/system-generators/*" or
file.path like "/etc/systemd/user-generators/*" or
file.path like "/usr/local/lib/systemd/user-generators/*" or
file.path like "/usr/lib/systemd/user-generators/*",
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
''',
'''
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 LIKE "/run/systemd/system/%"
OR f.path LIKE "/etc/systemd/system/%"
OR f.path LIKE "/etc/systemd/user/%"
OR f.path LIKE "/usr/local/lib/systemd/system/%"
OR f.path LIKE "/lib/systemd/system/%"
OR f.path LIKE "/usr/lib/systemd/system/%"
OR f.path LIKE "/usr/lib/systemd/user/%"
OR f.path LIKE "/home/%/.config/systemd/user/%"
OR f.path LIKE "/home/%/.local/share/systemd/user/%")
AND f.filename LIKE "%.service"
''',
'''
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,
h.md5
FROM
file f
LEFT JOIN
users u ON f.uid = u.uid
LEFT JOIN
groups g ON f.gid = g.gid
LEFT JOIN
hash h ON f.path = h.path
WHERE
f.directory IN (
'/run/systemd/system',
'/etc/systemd/system',
'/etc/systemd/user',
'/usr/local/lib/systemd/system',
'/lib/systemd/system',
'/usr/lib/systemd/system',
'/usr/lib/systemd/user',
'/home/.config/systemd/user',
'/home/.local/share/systemd/user'
)
AND f.filename LIKE "%.timer"
ORDER BY
f.mtime DESC;
''',
'''
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,
h.md5
FROM
file f
LEFT JOIN
users u ON f.uid = u.uid
LEFT JOIN
groups g ON f.gid = g.gid
LEFT JOIN
hash h ON f.path = h.path
WHERE
f.directory IN (
'/etc/systemd/system-generators/',
'/usr/local/lib/systemd/system-generators/',
'/lib/systemd/system-generators/',
'/etc/systemd/user-generators/',
'/usr/local/lib/systemd/user-generators/',
'/usr/lib/systemd/user-generators/'
)
ORDER BY
f.mtime DESC;
''',
'''
SELECT name, path, source, status, type FROM startup_items
WHERE type == "systemd unit" AND status == "active" AND
name LIKE "%.service" OR name LIKE "%.timer"
'''
]