某付宝APP之某加油小程序对称加解密算法解析
本帖最后由 闷骚小贱男 于 2021-7-31 09:22 编辑# 前言
---
前几天发了一个某付宝小程序的sign参数md5加密拿到明文参数的帖子..
又发现一个别的小程序,好像是用的对称加密,耐不住好奇心,就试了试...结果成功实现了加解密的操作。遂发帖记录一下。
# 工具
- fiddler【抓包工具】
- Drony【转发工具,因为fiddler抓不到小程序的包,所以用Drony转发用fiddler能抓到包】
- MT(或NP)管理器【文件管理】
- Nodepad++【JS格式化+分析】
# 开始操作
---
## Drony的配置和开启
---
之前就已经讲过了,就不再讲解了。想了解的可以跳转看一下:(https://www.52pojie.cn/thread-1358606-1-1.html#36585369_fiddler+drony抓包)
## 拿到源码
---
用MT管理器在`/data/user/0/com.eg.android.AlipayGphone/files/nebulaInstallApps/`目录中直接搜索小程序的名字,找到小程序的目录
## 操作+抓包
---
小程序端操作:输入手机号,点击获取验证码,FD搜到smsitfs/sendSms的抓包信息
密文为aNrKSihAtEQuPZr8qdxkxspWvzMjXwvunyoWxdKdqj8HPdxkxsxjtwrdtwYMnic8nwv4vzx1nwMuty7NnwqWOZndOsqjxHJ=
## 请求密文JS加密分析
---
### sendSms接口分析
JS中搜索`smsitfs/sendSms`,找到变量sendSms
~~~JavaScript
sendSms: i.default.BASE_QUANGUO_URL + "smsitfs/sendSms",
~~~
全词匹配搜索sendSms,发现有4处调用位置,且均为getCode的函数名,看名字就知道我们是找对了,取出其中一个并小小的分析一下
~~~JavaScript
getCode: function () {
this.countDown();
var e = {
phoneNumber: this.data.phoneNumber
};
e.sign = f.default.sortAndStringfy(e, !0);//e的值{"phoneNumber": "183xxxx548", sign: "MD5操作之后的值"}
(0, l.default)(c.default.sendSms, {
isStr: !0,
data: f.default.transpositionEncryptNew((0, r.default)({}, e), !1)
}).then(function (e) {
var t = f.default.transpositionDecryptNew(e);
if (t) {
var a = JSON.parse(t);
console.log(a),
1 === a.retCode ? (0, o.default)("获取成功!", "success") : (0, o.default)(a.msg)
}
})
},
~~~
可得出流程:
### 先分析获取e.sign的sortAndStringfy函数
搜索sortAndStringfy:到
~~~JavaScript
t.default = {
transpositionEncryptNew: ae,
transpositionDecryptNew: ie,
sortAndStringfy: re
},
e.exports = t.default
~~~
加密函数transpositionEncryptNew=ae
解密函数transpositionDecryptNew=ie
也就是re函数就是sortAndStringfy函数,如下。
~~~JavaScript
function re(e, t) {//根据传参可得e={'phoneNumber':'手机号'} , t = !0;
var a = new Array,
n = Object.keys(e);
n.sort();
for (var i = 0, r = n.length; i < r; i++) {
var o = e],
s = ] + "=" + o;
a.push(s)
}
return t ? y.default.hexMD5(C.Base64.encode("&" + a.join("&"))) : a.join("&") + "&key=" + L
}
~~~
果然是MD5加密,枚举变量e,a = ,re函数的返回值为md5(base64编码("&" + a.join("&")))
### 再分析下加密ae函数
拿到sign的加密方法之后,赋值e.sign后拿到完整的参数e:{"phoneNumber": "手机号", sign: "re操作之后的值"}
#### ae函数
搜索`function ae(`,拿到ae函数:
~~~JavaScript
function ae(e, t) {
if (t) {
var a = JSON.stringify(e);
return X(G(), a)
}
var n = C.Base64.encode(JSON.stringify(e));//Base64编码
return X(G(), n)
}
~~~
#### 函数X和函数G
发现一个函数X和函数G
分别搜索`function X(`和`function G(`,拿到X和G的函数:
~~~JavaScript
function X(e, t) {
for (var a = Z(t), n = new Array, i = 0; i < a.length; i++) {
var r = e.get(a);
r ? n.splice(i, 1, r) : n.splice(i, 1, a)
}
return ee(n)
}
function G() {
var e = new Map,
t = Z(U),
a = Z(q),
n = t.length;
t.length != a.length && console.log("密钥和原字符长度不一致!");
for (var i = 0; i < n; i++)
e.set(t, a);
return e
}
~~~
#### 函数ee和函数Z
又发现一个函数ee和函数Z,还有变量U和q
继续搜索搜索`function ee(`和`function Z(`,拿到ee和Z的函数:
~~~JavaScript
function Z(e) {
var t,
a = new Array,
n = void 0;
t = e.length;
for (var i = 0; i < t; i++)
(n = e.charCodeAt(i)) >= 65536 && n <= 1114111 ? (a.push(n >> 18 & 7 | 240), a.push(n >> 12 & 63 | 128), a.push(n >> 6 & 63 | 128), a.push(63 & n | 128)) : n >= 2048 && n <= 65535 ? (a.push(n >> 12 & 15 | 224), a.push(n >> 6 & 63 | 128), a.push(63 & n | 128)) : n >= 128 && n <= 2047 ? (a.push(n >> 6 & 31 | 192), a.push(63 & n | 128)) : a.push(255 & n);
return a
}
function ee(e) {
if ("string" === typeof e)
return e;
for (var t = "", a = e, n = 0; n < a.length; n++) {
var i = a.toString(2),
r = i.match(/^1+?(?=0)/);
if (r && 8 == i.length) {
for (var o = r.length, s = a.toString(2).slice(7 - o), l = 1; l < o; l++)
s += a.toString(2).slice(2);
t += String.fromCharCode(parseInt(s, 2)),
n += o - 1
} else
t += String.fromCharCode(a)
}
return t
}
~~~
#### 变量U和q
U = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890",
q = "752wpRiLxrbDvnXgocTyEmZVOtSPqYalf9dsM8IH6GC0FeA3K1Nzuj4WQkBUhJ";
顺便在附近还拿到了变量J和变量$...顺手牵羊吗?
#### 整合加密代码并在浏览器中执行
由于代码中有md5和base64,而且base64解码用window.atob的时候有中文会乱码,
所以百度搜了一段md5函数和base64编码解码的函数,并替换小程序中的原方法。
执行`var t={"phoneNumber":"183XXXX48"};t.sign=re(t,1);ae(t)`加密
结果为aNrKSihAtEQuPZr8qdxkxspWvzMjXwvunyoWxdKdqj8HPdxkxsxjtwrdtwYMnic8nwv4vzx1nwMuty7NnwqWOZndOsqjxHJ=
和fiddler的抓包结果是一样的,说明加密是有效的。
## 接口请求返回密文JS解密分析
和加密分析一样,之前我们得出解密函数transpositionDecryptNew=ie,依次找出用到的函数和变量
### 函数ie
~~~JavaScript
function ie(e, t) {
if (t)
return X(Q(t), C.Base64.decode(e));
var a = X(Q(), e);
return C.Base64.decode(a)
}
~~~
### 函数X和函数Q
~~~JavaScript
//函数X、函数Z、函数ee,变量U和q,刚才的加密已经有了,所以不再需要了
function Q(e) {
var t = new Map,
a = Z(e || U),
n = Z(q),
i = a.length;
a.length != n.length && console.log("密钥和原字符长度不一致!");
for (var r = 0; r < i; r++)
t.set(a, n);
return t
}
~~~
### 整合代码,执行解密post返回密文
也可以向之前那样用fd,自动响应修改js,弹出相关参数提示
# JS加解密源码下载地址
---
请使用AES/CBC/pkcs7/128位
~~~
q = "752wpRiLxrbDvnXgocTyEmZVOtSPqYalf9dsM8IH6GC0FeA3K1Nzuj4WQkBUhJ";
key=q.substr(1,16);iv=q.substr(16,16);
下载地址 :7arhyjZbN3nihvyFZtrJd+N8xXMNL2Ckx4STQfESptLuLPjB/nSBphOi1legar9ZO9SD1fL5CcTshPIj6fdzDvBvy5KXS7x+hgzAA7yVL0o=
~~~
# 有趣的发现
作为世界500强...竟然发送短信验证码的时候不做限制...这是什么操作
本帖最后由 闷骚小贱男 于 2021-11-30 18:22 编辑
2021-8-19又测试的时候变成每天20条短信上限了{:1_907:}
2021-11-28 下发短信验证码需要图片验证码 快进到破解某付宝,进去吃香喝辣,出来后被重金挖走。 有什么用?我不知道这文章意义是什么{:1_925:} xxwo4me 发表于 2021-7-29 11:35
快进到破解某付宝,进去吃香喝辣,出来后被重金挖走。
进去还想吃香的喝辣的?{:1_886:} 萌壹 发表于 2021-7-29 11:23
解个毛线,有啥用?能免费加油?
这种可以做短信哄哄{:301_997:} 名牌吧,我知道你说的是中湿滑 虽然看不太懂,但很厉害! 很详细的教程,来学习一下。
也不知是否能学会。
感谢楼主分享。 楼主很厉害虽然看不太懂 必须赞一个,谢谢分享 好好学习一下,谢谢! 可以搞一波余额之类的{:1_927:},看着我手机上余额有点伤心