解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
请求重放总是401?原来逆向sign后还能绕过WAF爆破用户名
一. 前言
本文涉及的相关漏洞均已修复、本文中技术和方法仅用于教育目的;
文中讨论的所有案例和技术均旨在帮助读者更好地理解相关安全问题,并采取适当的防护措施来保护自身系统免受攻击,请不要复现!
二. 大概流程
1. 问题发现
测试时请求无法重放,提示 401 错误(token 无效),发现请求包含 token、sign、timestamp 三个关键参数。
2. JS 逆向
通过全局搜索和断点调试,定位 sign 生成逻辑,发现其由固定格式字符串token + timestamp + 固定salt
经 SHA1 加密(函数 p()) 得到。
3. 自动化实现
使用 Python 模拟 sign 生成算法,结合 mitmproxy 配置代理流程
(Burp → mitmproxy → 服务端),自动更新 timestamp、生成 sign 并替换请求参数,实现请求正常重放。
4. WAF 绕过与注入测试
输入单引号发现 SQL 注入迹象,遇 WAF 拦截后,通过 URL 编码的 || 判断为 Oracle 数据库。
利用 “被除数不为 0” 特性 + SUBSTRB 函数逐字符爆破出数据库用户名。
三. 正文
JS 逆向
正常测试时发现:
请求 无法重放
返回 401 token 错误
查看请求包,可以看到三个参数:
token
sign
timestamp
很好理解:
一个 Token,一个签名,一个时间戳。

开始逆向 sign
通过全局搜索关键字 sign,逐处下断点,发现某处停住,即为目标位置。
可以看到变量 c 就是 sign 未加密前的原始字符串:
token = t(固定) 时间戳 = timestamp(动态) i = 固定 salt
只需要找到 p() 算法即可。
继续往下,看到 sign 已被加密得到最终值。
p() 就是加密函数,于是在控制台打印此函数,定位到具体源码位置。
调用验证一下 → 确认算法正确。

自动化
目前有两种方式模拟加密:
方式 1:Python 模拟 sign 算法(推荐)
用于实现完全自动化 → burp 自动替换 sign → 自动更新 timestamp。
方式 2:JS 原封不动放进 burp 扩展
也可以,但整合性不如 Python。

自动化流程(推荐方案)
Python 模拟 sign 生成
mitmproxy 作为 burp 的 上游代理
自动拦截请求
替换 timestamp & sign
发往真实服务器,实现 热加载更新 sign
需要注意:
timestamp 也必须同步更新!
Burp → 上游代理:mitmproxy
mitmproxy 再走一个出口代理(可选)
启动 mitmproxy 示例:
mitmproxy --mode upstream:http://127.0.0.1:8080
重新重放请求 → 成功
mitmproxy 中也能看到流量正常经过。
WAF 绕过
输入一个单引号 ' → 报错
输入两个 ' ' 正常 → 确认 SQL 注入
继续测试,发现存在:
WAF 拦截
后端过滤
开始慢慢 fuzz。

确定数据库类型
通过 URL 编码的 || 可以绕过 WAF%7C%7C → Oracle 字符串拼接
确认:数据库为 Oracle
此处为 拼接 而非运算符,因此必须 URL 编码,否则直接 400。
利用 “被除数不能为 0” 特性判断
构造 payload:
条件成立 → 正常
条件不成立 → 除以 0 报错
通过报错与否判断字符。
前 3 位正常
第 4 位报错
继续爆破……
用户名爆破(SUBSTR / SUBSTRB)
Oracle 可用:
SUBSTR()SUBSTRB() # 可绕过某些过滤
逐字符爆破最终获得:
OP**