-
-
[原创]某商超小程序加密算法解析
-
发表于: 2021-7-12 23:00 13634
-
下载地址:https://www.charlesproxy.com/
(前提:手机和电脑均安装好charles证书)
证书安装及支持抓包https设置指引请参考: https://blog.csdn.net/victory0943/article/details/106332095/
下载地址:https://www.postman.com/
支持导入cURL,便捷高效,导入操作如下图
下载地址: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捕捉到相关接口请求
选中相关请求右键复制其cURL格式数据 ,导入到postman进行调试分析
观察发现是个post请求, 请求体是URL编码后的,不易阅读,我们进行url解码
(注意这里获取的cURL接口数据和图例所示的不是同一个请求,图例所示的抓包接口被笔者不小心清除了,于是重新抓了一次请求~)
如下为url解码后的cURL接口数据,这下好看多了~
观察可知有data、h5、paramsMD5三个参数,整理如下:
手机重复操作,经多次调用抓包该接口后对比发现:
h5
这个值是固定的yx_touch
paramsMD5
通过字面意思判断为加密参数,但其数据格式不像MD5,猜测是用了MD5后又进行了其他的编码加密
观察可知获取门店要传入的经纬度入参也是加密的,正常来说经纬度均是数字{"longitude":"MTIwLjE1NDc3NQ==","latitude":"MzAuMzA1ODIy"}
前述提到的RE文件管理器app
如今微信小程序单包体积不能超过4M(小程序基础依赖包除外),如果项目内容过大,开发者会使用分包模式
拿下图举例来说(下图所示小程序包是其他应用的,非本文要分析的case)
其中:
_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
用于阅读代码,代码跳转追踪
是骡子是马拉出来溜溜,不是有个加密叫paramsMD5吗,全局搜索试试看:
好嘛,定位到2处代码,直觉告诉我选request.js中的,直接定位到一个函数getHmacSha256(n)。
再看看这个data结构,含data、h5、paramMD5,和之前接口分析的结论一致,通用格式没的说~
变量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验证一下
混淆代码阅读性差,且代码量也繁杂,实现加密翻译或许有点吃力;那么我们转换思路,由“破译”转为“利用”
重新梳理一下上述加密流程,将涉及加密的代码整理出来,拷贝到一个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¶msMD5=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¶msMD5=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¶msMD5=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¶msMD5=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关键字后没有任何匹配项)。
赞赏
- [原创]某大厂生鲜超市加密协议分析 14374
- [原创]手机自动化操作--苹果手机篇 3684
- [原创]手机自动化操作--安卓手机篇 4730
- [原创]抓包神器之Charles配置和使用手册 18028
- [原创]某生鲜电商sign签名算法分析 14539