Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ sqlmap -r login.txt -p username --second-url "http://10.10.10.10/details.php"
sqlmap -r login.txt -p username --second-req details.txt
```

## Finding and confirming the delayed sink

Do not stop testing when the request that stores a value succeeds. Create a record containing an unmatched delimiter such as `'`, then visit every view, export, moderation, or details endpoint that later consumes that record. If the value remains stored but one of those consumers returns an SQL error, truncates its HTML where the record should be rendered, or otherwise fails, the vulnerable query is probably in that second processing step.<sup>[[3]](#references)</sup>

For a reflected `UNION` sink, increment the number of selected markers until the delayed page renders again, then replace markers individually with functions such as `version()` or `user()` to locate reflected columns. This confirmation must be repeated through the full **store → retrieve → execute** flow for every payload attempt.<sup>[[3]](#references)</sup>

```sql
' UNION SELECT 1,2,3-- -
' UNION SELECT 1,2,3,4,5-- -
' UNION SELECT version(),user(),3,4,5-- -
```

## When the storage response redirects to the sink

Sometimes the storage `POST` returns a redirect whose `Location` is the newly created record, and that destination immediately evaluates the stored value. In that specific flow, sqlmap can observe the second-order result by following the per-attempt redirect, so a fixed `--second-url` or `--second-req` is not required. Save a benign authenticated storage request and target the stored parameter; if the `UNION` technique is already known, restricting the test reduces noise.<sup>[[3]](#references)</sup>

```bash
sqlmap -r create.req -p stored_parameter --technique U
```

When prompted, **follow the redirect**, but answer **no** to resending the original POST body if the destination is a GET-only details page. This makes sqlmap request the generated `Location` as the consumer request instead of replaying the creation body against it. A negative basic heuristic is not decisive here because the first response only stores the payload; let the selected technique test the redirected response.<sup>[[3]](#references)</sup>

If the redirect does not reach the actual consumer, the record requires another action, or the trigger URL is not returned dynamically, fall back to `--second-url`, `--second-req`, or a helper script for the extra state transitions.<sup>[[1]](#references)[[3]](#references)</sup>

In several cases **this won't be enough** because you will need to **perform other actions** apart from sending the payload and accessing a different page.

When this is needed, you can use a **sqlmap tamper script**. For example, the following script registers a new user **using the sqlmap payload as the email address** and then logs out.
Expand Down Expand Up @@ -140,5 +164,6 @@ This pattern is especially useful when the payload is stored in places such as:<

- [1] [sqlmap official usage wiki](https://github.com/sqlmapproject/sqlmap/wiki/Usage)
- [2] [Second Order SQLi: Automating with sqlmap](https://jlajara.gitlab.io/Second_order_sqli)
- [3] [HTB: Cobblestone](https://0xdf.gitlab.io/2026/08/15/htb-cobblestone.html)

{{#include ../../../banners/hacktricks-training.md}}