首页
社区
课程
招聘
[原创]某商超小程序加密算法解析
发表于: 2021-7-12 23:00 13634

[原创]某商超小程序加密算法解析

2021-7-12 23:00
13634

image-20210706151936444

下载地址:https://www.charlesproxy.com/

(前提:手机和电脑均安装好charles证书)

证书安装及支持抓包https设置指引请参考: https://blog.csdn.net/victory0943/article/details/106332095/

image-20210712171621034

下载地址:https://www.postman.com/

支持导入cURL,便捷高效,导入操作如下图

image-20210712171745333

image-20210712174731685

下载地址:https://m-k73-com.sm-tc.cn/c/m.k73.com/mipw/574951.html

华为p9 android 6.0

(android7.0以上版本抓包工具默认抓不到https请求,因为7.0以上只信任系统级别证书,而charles证书是安装到用户级目录的。

解决方式:可将charles证书升级为系统证书,即安装证书到系统证书目录下。

具体操作可参考连接:https://www.pianshen.com/article/97291182754/ )

手机上操作该小程序,找到可以进行重新定位的地方点击来触发请求以获取附近的门店,随后charles捕捉到相关接口请求

image-20210712223517703

选中相关请求右键复制其cURL格式数据 ,导入到postman进行调试分析

image-20210712173322417

观察发现是个post请求, 请求体是URL编码后的,不易阅读,我们进行url解码

(注意这里获取的cURL接口数据和图例所示的不是同一个请求,图例所示的抓包接口被笔者不小心清除了,于是重新抓了一次请求~)

如下为url解码后的cURL接口数据,这下好看多了~

观察可知有data、h5、paramsMD5三个参数,整理如下:

手机重复操作,经多次调用抓包该接口后对比发现:

h5 这个值是固定的yx_touch

paramsMD5 通过字面意思判断为加密参数,但其数据格式不像MD5,猜测是用了MD5后又进行了其他的编码加密

观察可知获取门店要传入的经纬度入参也是加密的,正常来说经纬度均是数字
{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}

前述提到的RE文件管理器app

如今微信小程序单包体积不能超过4M(小程序基础依赖包除外),如果项目内容过大,开发者会使用分包模式

拿下图举例来说(下图所示小程序包是其他应用的,非本文要分析的case)

image-20210712164945927

其中:

_2124598774_821.wxapkg 3.3M 主包

_-588782754_76.wxapkg 1.5M 子包

_152740959_13.wxapkg 89k 子包

_1123949441_552.wxapkg 14M 基础依赖包

打开小程序一顿操作后,会在小程序包存放目录下自动下载生成对应的包

通过re文件管理器直捣微信小程序包路径:
/data/data/com.tencent.mm/MicroMsg/"$用户MD5"/appbrand/pkg/_*_xxx.wxapkg
通过re文件管理器打成zip包发送到个人钉钉或者QQ、微信等,电脑完成文件接收

提示:若在之前打开过多个小程序,可以先进入目录全部删除,这样好区分小程序包的归属

####

下载地址:https://gitee.com/guo492273770/wxappUnpacker
运行前提需要安装node环境
该工具运行需要一些node依赖库,安装指引在链接中README.md文档中有

等我弄明白了~, 有基础的同学可以参考这个 https://mp.weixin.qq.com/s/4BerA1Ij3BfMeg2LA0cm5g

笔者太菜,看的不太懂~

下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html

用于阅读代码,代码跳转追踪

image-20210712165335021

是骡子是马拉出来溜溜,不是有个加密叫paramsMD5吗,全局搜索试试看:

好嘛,定位到2处代码,直觉告诉我选request.js中的,直接定位到一个函数getHmacSha256(n)。
再看看这个data结构,含data、h5、paramMD5,和之前接口分析的结论一致,通用格式没的说~

image-20210712165507451

变量t:
三目运算表达式,为true时貌似表示是BETA版本运行,那么正常使用的版本应该是false,所以猜测t="@653yx#*^&HrTy99",是一个固定盐值。

将前述接口分析中的参数data进行复制,粘贴进来改一下代码再加一个打印语句执行调试看看结果:

针对这个错误,百度了一番找到个解决方案:
https://blog.csdn.net/sinat_33184880/article/details/85533095

小程序使用async出现regeneratorRuntime is not defined错误说是少个依赖库,下载之

修改common.js代码引入该包:

解决思路
我看到小程序代码中有这样的片段:

看起来就是引入库的方式,于是我学了下写了这样一段:

再次运行:

继续分析它的生成逻辑,追到相关代码,添加打印语句:

上述r是个base64对象,且用到了它的words和sigBytes两个属性:

继续分析r的生成逻辑, 添加几行打印语句:

加了几句打印语句执行看看:

很明显了,是用“@653yx#*^&HrTy99”作为key种子初始化加密对象,然后将拼接的字符串n传入进行加密
百科了一下,该方法背后调用了著名的加密Hmac-Sha256

看来关于密码学笔者也需要系统地学一学~

前端能加密,后端一定有对应的解密。梳理一下上述分析的加密逻辑后,用java或者python写个测试demo验证一下

image-20210712190729823

混淆代码阅读性差,且代码量也繁杂,实现加密翻译或许有点吃力;那么我们转换思路,由“破译”转为“利用”
重新梳理一下上述加密流程,将涉及加密的代码整理出来,拷贝到一个js文件作为一个工具库来拿到最后的加密结果:
具体过程:

crypto-js 为前端一个加密库 介绍参见:https://blog.csdn.net/caoyan0829/article/details/88886635

function getSignStr (str) {
var hash = CryptoJS.HmacSHA256(str, key);
// let hashInHex= CryptoJS.enc.Hex.stringify(hash); //base64_str
return stringify(hash);
}

public class ExecuteScript {

}

那就这样吧,也不失为一种解决策略;倘若不是为了爬虫,完全复刻出java版的加密逻辑工作量太大没必要

{\"longitude\":\"MTIwLjE1NDc3NQ==\",\"latitude\":\"MzAuMzA1ODIy\"}

经纬度的加密相比paramsMD5来说简单太多,这个不难就不展开了,大体说一下思路:

直接用java写段demo反向验证,用base64加密尝试下

结论:就是单纯的base64加密

心得:

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
curl -H 'Host: yx.feiniu.com' -H 'content-type: application/x-www-form-urlencoded' -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.7(0x18000731) NetType/WIFI Language/zh_CN' -H 'Referer: https://servicewechat.com/wx08cc6bd15fabfa53/83/page-frame.html' --data-binary "data=%7B%22apiVersion%22%3A%22t141%22%2C%22appVersion%22%3A%221.5.1%22%2C%22areaCode%22%3A%22CS000016%22%2C%22channel%22%3A%22online%22%2C%22clientid%22%3A%22a7ea53059fc868e2e3e2dd7c04027035%22%2C%22device_id%22%3A%22tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE%22%2C%22time%22%3A1626080760465%2C%22reRule%22%3A%224%22%2C%22token%22%3A%227ae362df162da5ffbfc408ed8e3d4ff3%22%2C%22viewSize%22%3A%22720x1184%22%2C%22networkType%22%3A%22wifi%22%2C%22isSimulator%22%3Afalse%2C%22osType%22%3A%224%22%2C%22scopeType%22%3A1%2C%22businessType%22%3A2%2C%22businessId%22%3A%2217210001%22%2C%22deliveryCircleType%22%3A%221%22%2C%22body%22%3A%7B%22longitude%22%3A%22MTIwLjE1NDc3NQ%3D%3D%22%2C%22latitude%22%3A%22MzAuMzA1ODIy%22%7D%7D&h5=yx_touch&paramsMD5=iOWz8O%2BxL9r9GX4k5Te%2F2U5HGTRk1GQ6YqLnMErWrAI%3D" --compressed 'https://yx.feiniu.com/member-yxapp/location/homeStoreList/t141'
curl -H 'Host: yx.feiniu.com' -H 'content-type: application/x-www-form-urlencoded' -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.7(0x18000731) NetType/WIFI Language/zh_CN' -H 'Referer: https://servicewechat.com/wx08cc6bd15fabfa53/83/page-frame.html' --data-binary "data=%7B%22apiVersion%22%3A%22t141%22%2C%22appVersion%22%3A%221.5.1%22%2C%22areaCode%22%3A%22CS000016%22%2C%22channel%22%3A%22online%22%2C%22clientid%22%3A%22a7ea53059fc868e2e3e2dd7c04027035%22%2C%22device_id%22%3A%22tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE%22%2C%22time%22%3A1626080760465%2C%22reRule%22%3A%224%22%2C%22token%22%3A%227ae362df162da5ffbfc408ed8e3d4ff3%22%2C%22viewSize%22%3A%22720x1184%22%2C%22networkType%22%3A%22wifi%22%2C%22isSimulator%22%3Afalse%2C%22osType%22%3A%224%22%2C%22scopeType%22%3A1%2C%22businessType%22%3A2%2C%22businessId%22%3A%2217210001%22%2C%22deliveryCircleType%22%3A%221%22%2C%22body%22%3A%7B%22longitude%22%3A%22MTIwLjE1NDc3NQ%3D%3D%22%2C%22latitude%22%3A%22MzAuMzA1ODIy%22%7D%7D&h5=yx_touch&paramsMD5=iOWz8O%2BxL9r9GX4k5Te%2F2U5HGTRk1GQ6YqLnMErWrAI%3D" --compressed 'https://yx.feiniu.com/member-yxapp/location/homeStoreList/t141'
curl -H 'Host: yx.feiniu.com' -H 'content-type: application/x-www-form-urlencoded' -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.7(0x18000731) NetType/WIFI Language/zh_CN' -H 'Referer: https://servicewechat.com/wx08cc6bd15fabfa53/83/page-frame.html' --data-binary "data={"apiVersion":"t141","appVersion":"1.5.1","areaCode":"CS000016","channel":"online","clientid":"a7ea53059fc868e2e3e2dd7c04027035","device_id":"tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE","time":1626080760465,"reRule":"4","token":"7ae362df162da5ffbfc408ed8e3d4ff3","viewSize":"720x1184","networkType":"wifi","isSimulator":false,"osType":"4","scopeType":1,"businessType":2,"businessId":"17210001","deliveryCircleType":"1","body":{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}}&h5=yx_touch&paramsMD5=iOWz8O+xL9r9GX4k5Te/2U5HGTRk1GQ6YqLnMErWrAI=" --compressed 'https://yx.feiniu.com/member-yxapp/location/homeStoreList/t141'
curl -H 'Host: yx.feiniu.com' -H 'content-type: application/x-www-form-urlencoded' -H 'User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 13_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.7(0x18000731) NetType/WIFI Language/zh_CN' -H 'Referer: https://servicewechat.com/wx08cc6bd15fabfa53/83/page-frame.html' --data-binary "data={"apiVersion":"t141","appVersion":"1.5.1","areaCode":"CS000016","channel":"online","clientid":"a7ea53059fc868e2e3e2dd7c04027035","device_id":"tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE","time":1626080760465,"reRule":"4","token":"7ae362df162da5ffbfc408ed8e3d4ff3","viewSize":"720x1184","networkType":"wifi","isSimulator":false,"osType":"4","scopeType":1,"businessType":2,"businessId":"17210001","deliveryCircleType":"1","body":{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}}&h5=yx_touch&paramsMD5=iOWz8O+xL9r9GX4k5Te/2U5HGTRk1GQ6YqLnMErWrAI=" --compressed 'https://yx.feiniu.com/member-yxapp/location/homeStoreList/t141'
data: {"apiVersion":"t141","appVersion":"1.5.1","areaCode":"CS000016","channel":"online","clientid":"a7ea53059fc868e2e3e2dd7c04027035","device_id":"tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE","time":1626080760465,"reRule":"4","token":"7ae362df162da5ffbfc408ed8e3d4ff3","viewSize":"720x1184","networkType":"wifi","isSimulator":false,"osType":"4","scopeType":1,"businessType":2,"businessId":"17210001","deliveryCircleType":"1","body":{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}}
h5: yx_touch
paramsMD5: iOWz8O+xL9r9GX4k5Te/2U5HGTRk1GQ6YqLnMErWrAI=
data: {"apiVersion":"t141","appVersion":"1.5.1","areaCode":"CS000016","channel":"online","clientid":"a7ea53059fc868e2e3e2dd7c04027035","device_id":"tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE","time":1626080760465,"reRule":"4","token":"7ae362df162da5ffbfc408ed8e3d4ff3","viewSize":"720x1184","networkType":"wifi","isSimulator":false,"osType":"4","scopeType":1,"businessType":2,"businessId":"17210001","deliveryCircleType":"1","body":{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}}
h5: yx_touch
paramsMD5: iOWz8O+xL9r9GX4k5Te/2U5HGTRk1GQ6YqLnMErWrAI=
 
 
 
 
 
 
 
 
 
 
 
 
 
 
# 主包反编译
node wxWxapkg.js ../../wxapkg/xxxx/_-2094256841_77.wxapkg
# 子包反编译
node wxWxapkg.js  -s=/Users/toretto/crack/wxapkg/xxxx/_-2094256841_77  ../../wxapkg/xxxx/_571009734_77.wxapkg
....
#部分子包反编译可能会报错,但没关系,不影响后续的加密分析过程
# 主包反编译
node wxWxapkg.js ../../wxapkg/xxxx/_-2094256841_77.wxapkg
# 子包反编译
node wxWxapkg.js  -s=/Users/toretto/crack/wxapkg/xxxx/_-2094256841_77  ../../wxapkg/xxxx/_571009734_77.wxapkg
....
#部分子包反编译可能会报错,但没关系,不影响后续的加密分析过程
 
 
function getHmacsha256(e) {
 var n = JSON.stringify(e) + e.isSimulator + e.viewSize + e.networkType + e.time, t = _common2.default.environment === _config.ENVIRONMENTS.BETA ? "@yx789*&^DKJ##CC" : "@653yx#*^&HrTy99";
 console.log("request.js@32 n: " + n);
 return _encBase2.default.stringify((0, _hmacSha2.default)(n, t));
}
function getHmacsha256(e) {
 var n = JSON.stringify(e) + e.isSimulator + e.viewSize + e.networkType + e.time, t = _common2.default.environment === _config.ENVIRONMENTS.BETA ? "@yx789*&^DKJ##CC" : "@653yx#*^&HrTy99";
 console.log("request.js@32 n: " + n);
 return _encBase2.default.stringify((0, _hmacSha2.default)(n, t));
}
 
var a = {"apiVersion":"t141","appVersion":"1.5.1","areaCode":"CS000016","channel":"online","clientid":"a7ea53059fc868e2e3e2dd7c04027035","device_id":"tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE","time":1626080760465,"reRule":"4","token":"7ae362df162da5ffbfc408ed8e3d4ff3","viewSize":"720x1184","networkType":"wifi","isSimulator":false,"osType":"4","scopeType":1,"businessType":2,"businessId":"17210001","deliveryCircleType":"1","body":{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}};
 
 
function getHmacsha256(e) {
    // var n = JSON.stringify(e) + e.isSimulator + e.viewSize + e.networkType + e.time, t = _common2.default.environment === _config.ENVIRONMENTS.BETA ? "@yx789*&^DKJ##CC" : "@653yx#*^&HrTy99";
    var n = JSON.stringify(e) + e.isSimulator + e.viewSize + e.networkType + e.time, t = "@653yx#*^&HrTy99";
    console.log("request.js@32 n: " + n);
    return _encBase2.default.stringify((0, _hmacSha2.default)(n, t));
}
 
console.log(getHmacsha256(a));
var a = {"apiVersion":"t141","appVersion":"1.5.1","areaCode":"CS000016","channel":"online","clientid":"a7ea53059fc868e2e3e2dd7c04027035","device_id":"tv179yrhs3kv9RXjJv6uJNmdkN6kTbmaUHQE","time":1626080760465,"reRule":"4","token":"7ae362df162da5ffbfc408ed8e3d4ff3","viewSize":"720x1184","networkType":"wifi","isSimulator":false,"osType":"4","scopeType":1,"businessType":2,"businessId":"17210001","deliveryCircleType":"1","body":{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}};
 
 
function getHmacsha256(e) {
    // var n = JSON.stringify(e) + e.isSimulator + e.viewSize + e.networkType + e.time, t = _common2.default.environment === _config.ENVIRONMENTS.BETA ? "@yx789*&^DKJ##CC" : "@653yx#*^&HrTy99";
    var n = JSON.stringify(e) + e.isSimulator + e.viewSize + e.networkType + e.time, t = "@653yx#*^&HrTy99";
    console.log("request.js@32 n: " + n);
    return _encBase2.default.stringify((0, _hmacSha2.default)(n, t));
}
 
console.log(getHmacsha256(a));
#运行
node request.js
# 运行结果报错:
regeneratorRuntime is not defined     在 comment.js中
#运行
node request.js
# 运行结果报错:
regeneratorRuntime is not defined     在 comment.js中
 
#生成package.json
npm init
#下载缺少的包
npm install regenerator@0.13.1
# 将所缺文缺runtime.js移动到项目中
cd node_modules/regenerator-runtime/
#与common.js同目录
cp runtime.js /Users/toretto/crack/wxapkg/darunfa/_-2094256841_77/service/
#生成package.json
npm init
#下载缺少的包
npm install regenerator@0.13.1
# 将所缺文缺runtime.js移动到项目中
cd node_modules/regenerator-runtime/
#与common.js同目录
cp runtime.js /Users/toretto/crack/wxapkg/darunfa/_-2094256841_77/service/
// 最上方添加
import regeneratorRuntime from './runtime.js'
// 最上方添加
import regeneratorRuntime from './runtime.js'
#再次运行
node request.js
#还报错:
can not import modules from outside
#不能从外部导入文件,没有js基础的我盲猜可能是微信小程序无此语法(因为代码全局搜索import关键字后没有任何匹配项)。

[注意]APP应用上架合规检测服务,协助应用顺利上架!

收藏
免费 4
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
// // 统计代码