某Y院WX小程序挂号,算法还原

查看 111|回复 10
作者:ab19950220   
前情提要:某位大哥说需要XX医院挂号,手动抢不到,让我给分析分析,能不能实现程序抢号,特把分析过程跟大家分享一下,哪里有不对的地方欢迎讨论,所有敏感信息均已脱敏第一步:先用PC打开对应小程序 看能不能省点事(现在模拟器登录微信会封号),反编译小程序,结果如下 很明显的uniapp开发的


image.png (89.48 KB, 下载次数: 4)
下载附件
2025-8-23 14:10 上传



image.png (57.62 KB, 下载次数: 3)
下载附件
2025-8-23 14:12 上传

第二步:抓包查找对应api地址 并找到对应代码(现在版本的小程序包反编译出来,不知道怎么都是html了)


image.png (385.63 KB, 下载次数: 2)
下载附件
2025-8-23 14:15 上传



image.png (121.58 KB, 下载次数: 4)
下载附件
2025-8-23 14:18 上传

如上图所示 能清晰的定位到wechatLogin.js 文件 我们进去看下 登录方法,可以看到很多参数都是写死了的,密码使用md5加密了一下,然后看到iv和encryptedData,熟悉的朋友肯定就知道这是AES加密


image.png (302.08 KB, 下载次数: 4)
下载附件
2025-8-23 14:20 上传

第三步:还原加密算法,根据抓包可以看出 数据参数主要有 {"app":"","charset":"","partner":"","plat":"","ticket":"","bizContent":"","timestamp":"","sign":""} 主要看里面ticket  bizContent  和 sign 先全局搜一下 sign 看能不能找到关键信息


image.png (94.65 KB, 下载次数: 4)
下载附件
2025-8-23 14:29 上传

很明显在getsigndata.js里面,进去看下关键信息


image.png (331.12 KB, 下载次数: 4)
下载附件
2025-8-23 14:32 上传


简单解读一下上面的加密方法
[color=]function
(
[color=]t
,
[color=]e
) {
              
[color=]var

[color=]n

[color=]=

[color=]"-----BEGIN PRIVATE KEY-----
[color=]\n
[color=]"

[color=]+

[color=]e

[color=]+

[color=]"
[color=]\n
[color=]-----END PRIVATE KEY-----"
,
               
[color=]a

[color=]=

[color=]r
.
[color=]KEYUTIL_1
.
[color=]getKey
(
[color=]n
),
               
[color=]p

[color=]=

[color=]new

[color=]r
.
[color=]KJUR_1
.
[color=]crypto
.
[color=]Signature
({
                  
[color=]alg
[color=]:

[color=]"SHA256withRSA"
                });
              
[color=]return

[color=]p
.
[color=]init
(
[color=]a
),
[color=]p
.
[color=]updateString
(
[color=]t
),
[color=]r
.
[color=]hextob64_1
(
[color=]p
.
[color=]sign
());
            }(
[color=]o
,
[color=]n
.
[color=]priK
);该方法主要功能是使用 RSA 私钥对指定字符串进行 SHA256withRSA 算法的签名,并返回 Base64 格式的签名结果
在上面截图可以看出 sign加密的参数主要是由s组成的 这里  bizContent已经存在了,他的实现就是上面的 i 方法,该方法的实现由三个参数组成,从后面传参可以清晰命令的看出 分别是 i=加密参数(分别由"app=" + n.app + "&bizContent=" + i + "&charset=utf-8&partner=" + n.partner + "&plat=" + n.plat + "&ticket=" + n.ticket + "&timestamp=" + p)该字符串组合而成  n.aesKey = AES加密的key  n.iv=AES加密的iv  ,现在只需要找到aesKey和iv 即可复现加密和解密
(
[color=]i

[color=]=

[color=]function
(
[color=]t
,
[color=]e
,
[color=]n
) {
              
[color=]var

[color=]a

[color=]=

[color=]r
.
[color=]CryptoJS
.
[color=]enc
.
[color=]Utf8
.
[color=]parse
(
[color=]e
),
               
[color=]p

[color=]=

[color=]r
.
[color=]CryptoJS
.
[color=]enc
.
[color=]Utf8
.
[color=]parse
(
[color=]n
);
              
[color=]return

[color=]r
.
[color=]CryptoJS
.
[color=]AES
.
[color=]encrypt
(
[color=]t
,
[color=]a
, {
               
[color=]iv
[color=]:

[color=]p
,
               
[color=]mode
[color=]:

[color=]r
.
[color=]CryptoJS
.
[color=]mode
.
[color=]CBC
,
               
[color=]padding
[color=]:

[color=]r
.
[color=]CryptoJS
.
[color=]pad
.
[color=]Pkcs7
              }).
[color=]toString
();
            }(
[color=]i
,
[color=]n
.
[color=]aesKey
,
[color=]n
.
[color=]iv
)),
[color=]o

[color=]=

[color=]"app="

[color=]+

[color=]n
.
[color=]app

[color=]+

[color=]"&bizContent="

[color=]+

[color=]i

[color=]+

[color=]"&charset=utf-8&partner="

[color=]+

[color=]n
.
[color=]partner

[color=]+

[color=]"&plat="

[color=]+

[color=]n
.
[color=]plat

[color=]+

[color=]"&ticket="

[color=]+

[color=]n
.
[color=]ticket

[color=]+

[color=]"&timestamp="

[color=]+

[color=]p
,
[color=]s

[color=]=
{
              
[color=]app
[color=]:

[color=]n
.
[color=]app
,
              
[color=]charset
[color=]:

[color=]"utf-8"
,
              
[color=]partner
[color=]:

[color=]n
.
[color=]partner
,
              
[color=]plat
[color=]:

[color=]n
.
[color=]plat
,
              
[color=]ticket
[color=]:

[color=]n
.
[color=]ticket
,
              
[color=]bizContent
[color=]:

[color=]i
,
              
[color=]timestamp
[color=]:

[color=]p
,
              
[color=]sign
[color=]:

[color=]""
            }
老规矩 先找关键字 或者 关键方法


image.png (489.3 KB, 下载次数: 3)
下载附件
2025-8-23 14:49 上传

从这个初始化方法来看 e 是由外部传进来的  只需要找到初始化该方法时 传参即可


image.png (287.83 KB, 下载次数: 4)
下载附件
2025-8-23 14:50 上传

从这里代码就可以判断出来很多东西了,key 和 iv 都是由e 这个值获取而来 ,简单看下代码就知道这俩值是如何获取的


image.png (131.6 KB, 下载次数: 4)
下载附件
2025-8-23 14:54 上传



image.png (217.92 KB, 下载次数: 3)
下载附件
2025-8-23 14:55 上传

现在测试一下 看看对不对


image.png (134.09 KB, 下载次数: 4)
下载附件
2025-8-23 14:58 上传

完美,到现在为止参数加密解密已完成,再附上挂号的记录


image.png (460.97 KB, 下载次数: 4)
下载附件
2025-8-23 15:01 上传



9af1ca61fc3cfd3ba59c35d6e0a9ccc.jpg (125.34 KB, 下载次数: 4)
下载附件
2025-8-23 15:04 上传

下载次数, 下载附件

ab19950220
OP
  


kuaibeyond 发表于 2025-8-25 06:10
请教如何反编译小程序

论坛有教程 其他地方也有很多,确实有需要 我看后面出一期新版本的小程序反编译教程
cick   

每次挂号难 抢票难都是难点,这个教程对我们这种没含量的人来说,有点难,但是知道的事可以另辟新径,也能实现一票难求的局面,这个放号前一直跑脚本实现的么?有的挂号是定时放票的,请问下up这个也可以支持么? 节假日抢票挂号也很难
kuaibeyond   

请教如何反编译小程序
cuimen   

怎么反编译的呢?
lance1077   

看的一脸懵逼,对于我这样刚学习JS逆向的小学生还是太难了。。。。
skyshiyi   

这样都可以哦,厉害厉害
202sjx   

感谢分享
dzdzdzd   


ab19950220 发表于 2025-8-25 08:56
论坛有教程 其他地方也有很多,确实有需要 我看后面出一期新版本的小程序反编译教程

出吧,支持一下
yaoyi   

写的很详细了,正准备学习逆向小程序。
您需要登录后才可以回帖 登录 | 立即注册

返回顶部