微信小程序逆向之牛仔城游戏厅签到接口

查看 122|回复 11
作者:iBaiYu   
智谱清言说:
大家好,今天我将为大家带来一篇关于微信小程序逆向之牛仔城签到接口逆向的技术分享。在这篇文章中,我们将一起探讨如何逆向牛仔城微信小程序的签到接口,并分析其背后的原理。
由于已经逆向成功了,现在只是重新复现。
参考贴:
技术分享|微信小程序绕过sign签名思路
使用工具:
反编译小程序工具
解密小程序源码工具

小程序包解密.rar
(9.65 KB, 下载次数: 146)
2024-4-19 12:17 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB

这边推荐再下一个everything,方便你找到.wxapkg结尾的文件,除非你能准确知道小程序的存放路径就可以不用。打开我们的微信PC,然后登录藍搜索【疯狂牛仔城】微信小程序


然后点开小程序,这时候进入小程序后,多点击几个功能,比如什么登录啊,我的,主页,活动和二维码都点击一下,方便让小程序把需要的文件都下载完成。

打开everything,开始我们的搜索!直接搜.wxapkg,选择修改时间-倒序,然后打开_APP_.wxapkg所在的文件夹



当然,到这一步,你可能想问,你都没和我说怎么抓签到接口啊!😅
我想说,不好意思我忘了😋
这边你再下载一个抓包工具,叫HTTP Debugger Pro,或者你有可以抓到微信小程序的抓包工具都可以用
然后,打开HTTP Debugger Pro,这是他的页面。

开始抓包,点击一下签到,然后抓到该请求。


我们可以发现,通过抓包,发现有个doGrow,经过翻译,可以大致推断他就是签到接口

通过接口response返回,可以看到request发送了如下json
{
   "member_no" : 9999,
   "sign" : "2675c58926fe37d01a39874b6e210486",
   "store_no" : 12,
   "time" : "20240418200528",
   "type" : 12
}
通过询问GPT,可以得知:
member_no:表示会员编号,这里的值为44246,可能是指一个特定会员的唯一识别码。
sign:通常表示一个签名或者校验码,用于验证数据的完整性和真实性。这里的值“2675c58926fe37d01a39874b6e210486”可能是一个通过特定算法生成的签名。
store_no:表示商店编号,这里的值为12,可能指的是特定商店的编号。
time:表示时间,这里的值“20240418200528”看起来是一个时间戳,格式可能是YYYYMMDDHHMMSS,即2024年4月18日20点05分28秒。
type:表示类型,这里的值为12,具体指什么类型需要根据上下文来判断,比如可能是指交易类型、消息类型等。

并且可以看到,返回了如下json:
{
   "data" : null,
   "errorCode" : 0,
   "errorMessage" : "领取成功",
   "filename" : null,
   "success" : true,
   "url" : null
}
尝试重发请求,修改time值为20240419200528 原time值为:20240418200528


使用APIFOX发送请求可以发现,只修改time会出现416错误返回:
{
    "Message": "出现错误。"
}

由此可以判断,只修改time是没法进行签到的,需要一同把sign修改了,可是我们该如何得到sign值呢?
通过长度判断,可以发现sign是md5的32位长度,猜测是md5加盐了

接下来开始解密__APP__.wxapkg
打开UnpackMiniApp.exe


1.png (55.42 KB, 下载次数: 1)
下载附件
2024-4-28 16:06 上传

打开之前找到的_APP_.wxapkg的所在的文件路径


然后打开\wxpack\目录
找到如下文件wx28881238baa06aeb.wxapkg


然后打开wxapkgconvertor.exe,把wx28881238baa06aeb.wxapkg拖进去

反编译成功,生成了wx28881238baa06aeb目录

vscode打开该目录,注意!由于性能问题和混淆问题,建议将目录中的app-service.js复制内容,然后找个JS格式化网站格式化一下
这里可以用Javascript格式化在线工具:https://coding.tools/cn/javascript-beautifier
格式化打开后如下:

尝试搜索关键词doGrow,现有个函数定义了doGrow


通过分析,可以发现,上面的a变量,对照了下图中的a.default.doGrow,可以发现,query对象和我们抓接口出来请求时的对象一致

猜想一下,既然可能是MD5加盐加密,很有可能方法名就叫MD5,或者尝试搜索sign看看能不能搜出结果。
下图可以发现,第一条包含有sign,还包含有hexMD5,看样子是MD5加密函数,并且下面第三条也有定义hexMD5方法


{864D6C43-19AA-4543-A5CF-F268326943A0}.png (52.3 KB, 下载次数: 0)
下载附件
2024-4-19 12:56 上传

点击第一条搜索结果,可以看到有一段[JavaScript] 纯文本查看 复制代码var f = "911e529a9bcf081551797284f095f061acun"
可以粗略判断它是加盐的密钥,把这部分代码贴到GPT,问问它


{441DE93B-182B-46d5-AC7B-709DA9126E96}.png (186.81 KB, 下载次数: 1)
下载附件
2024-4-19 12:59 上传



PixPin_2024-04-19_13-01-29.png (196.28 KB, 下载次数: 1)
下载附件
2024-4-19 13:01 上传

GPT已经帮我们分析好了,它说f可能是一个签名或密钥,那就先扣下这段代码,新建一个test.js文件,然后粘贴


PixPin_2024-04-19_13-02-49.png (107.85 KB, 下载次数: 0)
下载附件
2024-4-19 13:02 上传



PixPin_2024-04-19_13-04-55.png (16.67 KB, 下载次数: 1)
下载附件
2024-4-19 13:04 上传

继续分析代码
发现有段代码进行了解构,i.default.hexMD5(c + l + f)中的c和l都是通过解构了arguments获得的
var r, n, s, c, l, h, d, p, g, m = arguments;
暂时没法判断出用途,那就换个思路,直接搜hexMD5,可以发现有两个地方调用了hexMD5,第一个是咱们刚刚看过的位置。
第二个咱没看过,点进去一看,发现,诶这不是我想要的getSign吗?


{C1726DC8-511C-4454-896B-7F6066F07C8E}.png (171.91 KB, 下载次数: 0)
下载附件
2024-4-19 13:10 上传

同样的,在这里也发现了e,t,r,n解构了arguments变量
先别管他干嘛的,扣下来扣下来。这时候是没法运行的,因为会报错,hexMD5未被定义。点击搜索的第三个,把hexMD5也扣下来


PixPin_2024-04-19_13-12-26.png (90.19 KB, 下载次数: 1)
下载附件
2024-4-19 13:12 上传

咱可以发现,hexMD5调用了c,u,l这三个方法,刚好这三个方法肯定就在这附近,所以上面的代码可以判断,上面的方法就是被调用的c,u,l。
也要一并扣下来,这时候还没法运行,因为u方法会报错,会提示o未被定义


{62068629-F6AC-48c5-9096-554EEFC0E346}.png (39.7 KB, 下载次数: 0)
下载附件
2024-4-19 13:16 上传

通过hexMD5方法的上下文,可以看到有o,r,n,i,a,s方法被定义,一起扣下来


1713503942352.jpg (135.18 KB, 下载次数: 1)
下载附件
2024-4-19 13:19 上传

这是最终扣下来的代码:


微信截图_20240419131957.png (66.95 KB, 下载次数: 1)
下载附件
2024-4-19 13:19 上传

尝试运行看看,可以发现成功了,并且md5和现成的库加密出来的也是一样的:


1713504134020.jpg (124.19 KB, 下载次数: 1)
下载附件
2024-4-19 13:22 上传

回到getSign方法,将i.default.hexMD5改成hexMD5。


微信截图_20240419134329.png (53.68 KB, 下载次数: 1)
下载附件
2024-4-19 13:43 上传

尝试运行看看,你会发现加密出来的sign并不一致。


dc541dad4863fca81981d4ba10e9041f.png (111.77 KB, 下载次数: 1)
下载附件
2024-4-19 13:45 上传

关键点就在于getSIgn的arguments,当你看不懂的时候,可以问问AI,咱问问它到底是什么意思:


微信截图_20240419134609.png (95.58 KB, 下载次数: 1)
下载附件
2024-4-19 13:46 上传

这下知道getSign接受什么参数了,参数一: object, 参数二: time值,也就是20240418200528
并且通过 r = e.query || {}可以知道,e是参数1的query值,也就是我们发送请求时的object对象,这时候的query可不存在time和sign字段,可不要搞混了:
{
   "member_no" : 44246,
   "store_no" : 12,
   "type" : 12
}
所以咱可以知道,e本质上是传一个query,然后通过time值还有密钥key进行混淆,尝试一下:


1713504785426.jpg (124.56 KB, 下载次数: 0)
下载附件
2024-4-19 13:33 上传

成功!!让AI重写一下getSign方便阅读:


PixPin_2024-04-19_13-34-41.png (115.06 KB, 下载次数: 0)
下载附件
2024-4-19 13:34 上传

尝试运行一下,会发现结果一致。


1713504932369.jpg (96.47 KB, 下载次数: 0)
下载附件
2024-4-19 13:35 上传

回到apifox,尝试发送新的请求:


1713505207542.jpg (93.32 KB, 下载次数: 1)
下载附件
2024-4-19 13:42 上传

成功!逆向完成。

下载次数, 下载附件

wfghim   

微信PC版本:3.9.8.25
抓包程序用Proxifier转发报文给Fiddler.exe
调试程序用WeChatOpenDevTools-Python-main
直接断点调试找sign,可能更方便一些
iBaiYu
OP
  

开始有些图盗链无法显示,一起编辑上传本地吧。
iBaiYu
OP
  


Monkey0 发表于 2024-4-20 12:33
跟着操作了一下,成功获取到个人信息,签到接口也成功了,遇到个问题,请教一下,使用html引用ajax访问接口 ...

使用node.js配合axios就没这种现象了,用浏览器就会有跨域问题
博士   


Glico 发表于 2024-4-21 00:43
大佬牛的 这是啥ai的

chatglm 智谱清言的
Eqwer   

AI都这么强大了啊
tomjin   

竟然不校对签到时间和服务器时间匹不匹配,学到了
zhy1992   

牛批,感谢分享。再问下这是什么ai啊
le2yun   

正常来说  生成签名 是不是需要 密钥呢 用户之类的内容啊?
zhonghuaz0464   

谁懂啊!!我已经连续手动签了几个月了
您需要登录后才可以回帖 登录 | 立即注册