Skip to content

Commit

Permalink
[New Hunt] Persistence via PolicyKit (#4406)
Browse files Browse the repository at this point in the history
* [New Hunt] Persistence via PolicyKit

* ++

(cherry picked from commit 1aea556)
  • Loading branch information
Aegrah authored and tradebot-elastic committed Feb 5, 2025
1 parent d10f604 commit e6a01d8
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
1 change: 1 addition & 0 deletions hunting/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Here are the queries currently available:
- [Persistence via Message-of-the-Day](./linux/docs/persistence_via_message_of_the_day.md) (ES|QL)
- [Persistence via Package Manager](./linux/docs/persistence_via_package_manager.md) (ES|QL)
- [Persistence via Pluggable Authentication Modules (PAM)](./linux/docs/persistence_via_pluggable_authentication_module.md) (ES|QL)
- [Persistence via PolicyKit](./linux/docs/persistence_via_policykit.md) (ES|QL)
- [Persistence via SSH Configurations and/or Keys](./linux/docs/persistence_via_ssh_configurations_and_keys.md) (ES|QL)
- [Persistence via System V Init](./linux/docs/persistence_via_sysv_init.md) (ES|QL)
- [Persistence via Systemd (Timers)](./linux/docs/persistence_via_systemd_timers.md) (ES|QL)
Expand Down
5 changes: 5 additions & 0 deletions hunting/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ linux:
path: ./linux/queries/persistence_via_malicious_docker_container.toml
mitre:
- T1610
4e8a17d3-9139-4b45-86d5-79e8d1eba71e:
name: Persistence via PolicyKit
path: ./linux/queries/persistence_via_policykit.toml
mitre:
- T1543
9997c6fb-4e01-477f-9011-fc7fc6b000b6:
name: General Kernel Manipulation
path: ./linux/queries/persistence_general_kernel_manipulation.toml
Expand Down
79 changes: 79 additions & 0 deletions hunting/linux/docs/persistence_via_policykit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Persistence via PolicyKit

---

## Metadata

- **Author:** Elastic
- **Description:** This hunt identifies potential persistence mechanisms leveraging PolicyKit (Polkit) on Linux systems. PolicyKit is a system service used to manage system-wide privileges and is often targeted by attackers to escalate privileges or maintain persistence. By monitoring file creations and modifications in key PolicyKit directories and analyzing metadata for Polkit-related files, this hunt helps detect unauthorized changes or suspicious activities that may indicate malicious use of PolicyKit. It provides detailed insights into potentially compromised PolicyKit configurations, enabling analysts to identify and respond to this persistence technique.

- **UUID:** `4e8a17d3-9139-4b45-86d5-79e8d1eba71e`
- **Integration:** [endpoint](https://docs.elastic.co/integrations/endpoint)
- **Language:** `[ES|QL, SQL]`
- **Source File:** [Persistence via PolicyKit](../queries/persistence_via_policykit.toml)

## Query

```sql
sql
from logs-endpoint.events.file-*
| keep @timestamp, host.os.type, event.type, event.action, file.path, file.extension, process.name, process.executable, agent.id
| where @timestamp > now() - 30 day
| where host.os.type == "linux" and event.type in ("creation", "change") and (
file.path like "/etc/polkit-1/rules.d/*" or
file.path like "/usr/share/polkit-1/rules.d/*" or
file.path like "/usr/share/polkit-1/actions/*" or
file.path like "/etc/polkit-1/localauthority/*" or
file.path like "/var/lib/polkit-1/localauthority/*"
) and not (
file.extension in ("swp", "dpkg-new") or
process.name in ("dnf", "yum", "dpkg")
)
| stats cc = count(), agent_count = count_distinct(agent.id) by file.path, process.executable
| where agent_count <= 3
| sort cc asc
| limit 100
```

```sql
sql
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 = '/etc/polkit-1/rules.d/%'
OR f.path LIKE '/usr/share/polkit-1/rules.d/%'
OR f.path LIKE '/usr/share/polkit-1/actions/%'
OR f.path LIKE '/etc/polkit-1/localauthority/%%'
OR f.path LIKE '/var/lib/polkit-1/localauthority/%%'
)
AND (mtime > strftime('%s', 'now') - (7 * 86400)); -- Modified in the last 7 days
```

## Notes

- Tracks file creations and modifications in PolicyKit-related directories such as `/etc/polkit-1/rules.d/`, `/usr/share/polkit-1/rules.d/`, `/usr/share/polkit-1/actions/`, and others to detect unauthorized additions or tampering.
- Retrieves metadata for PolicyKit configuration files, including ownership, last access times, and modification timestamps, to identify unauthorized or suspicious changes.
- Focuses on recent file modifications within the last 7 days to provide timely detection of potential malicious activities.
- Helps detect rare or anomalous file modifications by correlating process execution with file activities, enabling analysts to identify subtle signs of compromise.

## MITRE ATT&CK Techniques

- [T1543](https://attack.mitre.org/techniques/T1543)

## License

- `Elastic License v2`
64 changes: 64 additions & 0 deletions hunting/linux/queries/persistence_via_policykit.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
[hunt]
author = "Elastic"
description = """
This hunt identifies potential persistence mechanisms leveraging PolicyKit (Polkit) on Linux systems. PolicyKit is a system service used to manage system-wide privileges and is often targeted by attackers to escalate privileges or maintain persistence. By monitoring file creations and modifications in key PolicyKit directories and analyzing metadata for Polkit-related files, this hunt helps detect unauthorized changes or suspicious activities that may indicate malicious use of PolicyKit. It provides detailed insights into potentially compromised PolicyKit configurations, enabling analysts to identify and respond to this persistence technique.
"""
integration = ["endpoint"]
uuid = "4e8a17d3-9139-4b45-86d5-79e8d1eba71e"
name = "Persistence via PolicyKit"
language = ["ES|QL", "SQL"]
license = "Elastic License v2"
notes = [
"Tracks file creations and modifications in PolicyKit-related directories such as `/etc/polkit-1/rules.d/`, `/usr/share/polkit-1/rules.d/`, `/usr/share/polkit-1/actions/`, and others to detect unauthorized additions or tampering.",
"Retrieves metadata for PolicyKit configuration files, including ownership, last access times, and modification timestamps, to identify unauthorized or suspicious changes.",
"Focuses on recent file modifications within the last 7 days to provide timely detection of potential malicious activities.",
"Helps detect rare or anomalous file modifications by correlating process execution with file activities, enabling analysts to identify subtle signs of compromise."
]
mitre = ["T1543"]
query = [
'''sql
from logs-endpoint.events.file-*
| keep @timestamp, host.os.type, event.type, event.action, file.path, file.extension, process.name, process.executable, agent.id
| where @timestamp > now() - 30 day
| where host.os.type == "linux" and event.type in ("creation", "change") and (
file.path like "/etc/polkit-1/rules.d/*" or
file.path like "/usr/share/polkit-1/rules.d/*" or
file.path like "/usr/share/polkit-1/actions/*" or
file.path like "/etc/polkit-1/localauthority/*" or
file.path like "/var/lib/polkit-1/localauthority/*"
) and not (
file.extension in ("swp", "dpkg-new") or
process.name in ("dnf", "yum", "dpkg")
)
| stats cc = count(), agent_count = count_distinct(agent.id) by file.path, process.executable
| where agent_count <= 3
| sort cc asc
| limit 100
''',
'''sql
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 = '/etc/polkit-1/rules.d/%'
OR f.path LIKE '/usr/share/polkit-1/rules.d/%'
OR f.path LIKE '/usr/share/polkit-1/actions/%'
OR f.path LIKE '/etc/polkit-1/localauthority/%%'
OR f.path LIKE '/var/lib/polkit-1/localauthority/%%'
)
AND (mtime > strftime('%s', 'now') - (7 * 86400)); -- Modified in the last 7 days
'''
]

0 comments on commit e6a01d8

Please sign in to comment.