[V1.4版]支付宝全自动领随机福卡的安卓APP及相关post操作中rdsBizNo等参数的简单逆向
本帖最后由 闷骚小贱男 于 2021-2-5 13:49 编辑# 写在前面的话
这个帖,我也不太清楚应该发在哪个板块。。因为有成品,也有分析。。
单说分析的话,好像JS的分析并没有单独发帖的版块把?
所以我发在了原创发布区。如有违规,好吧,我知道了.应该发在软件调试区..谢谢
APP是E4a编写,有可能会报毒,无视或添加信任即可。
【APP为防止被随意修改,所以上了爱加密的壳子。】
【最近好像发几条短信就会不再发短信。。。】
---
# APP介绍
测试机型:VIVO X20A 安卓8.0+无障碍完美运行(别的机型和版本的安卓效果没测试过)
安卓APP,本APP是通过监听通知栏获得验证码,不会读取手机短信!
支持自定义活动列表和自定义从第几项开始执行
①需要手动开启无障碍功能(辅助功能)才能使用。
【需要开启的是“开启辅助功能”】
【1.3版本需要开启的是“五福”】
②需要联网使用
③APP需要有在通知栏显示的权限[不需要短信权限]
④屏幕需要常亮且不能锁屏
---
# 自定义活动列表
直接修改“活动id:”后面文本框中的内容即可,格式:活动,活动,活动
[注意:逗号为英文半角]
---
# 自定义从第几项开始执行
上次执行完第几项,这次+1,点击OK即可。比如:上次领完13,关了APP,这次就输入14,点击OK
---
# 运行截图
---
# 下载地址
## V1.5
在V1.4的基础上新增了操作上限的设置
密码:52pj下载地址:https://wwa.lanzouj.com/i9UEJlcdefa
## V1.4
在V1.3的基础上新增了延时和已下发验证码的提示
密码:52pj下载地址:https://wwa.lanzouj.com/iLl2tlay17i
## V1.3
修改无障碍(辅助功能方法,1.3版请开启名为"五福"的无障碍辅助功能)。
密码:52pj下载地址:https://wwa.lanzouj.com/iteGKl9breh
## V1.2
[有点小问题:通知栏需要手动清理]每次通知都在文本框中显示。
密码:52pj下载地址:https://wwa.lanzouj.com/i98Ysl94lpa
## V1.0
[有点小问题:通知栏需要手动清理]
密码:52pj下载地址:https://wwa.lanzouj.com/imktFl8z6wh
---
# 关于POST参数的分析和用e4a模拟发送验证码+提交验证码的方法
## 使用的工具:
chrome浏览器的开发者模式+fiddler抓包(fd可有可无)
## 实操
### 打开开发者模式
空白页F12 打开开发者模式,这个应该不陌生吧。(为的是抓到所有的请求包)
### 打开网页
在之前的页面打开领副卡的活动页面
### 下发验证码之前的captcha.htm的分析
#### 抓包一下
点击“开启福气盲盒”,输入手机号,点击“发送验证码”,我们可以抓到关于“alipay.tradecsa.biz.blessingprod.wufu2021.sendVerifyCode”接口的参数分别为
| rdsBizNo | rdsToken |
| ------------- |:-------------:|
|8de19c9820fe40b1a36b6e51e29f7c81162a6ce03e0b4ab48fc112859aaa1b18 | d5bc029eadf24cd1808a896b6378e86b3ea7e10722e64a5bae14513ca12a02e2 |
那么这两个参数是怎么来的呢?
#### 分析rdsBizNo参数
我们一个一个来分析,先rdsBizNo,我们ctrl+F搜索“8de19c9820fe40b1a36b6e51e29f7c81162a6ce03e0b4ab48fc112859aaa1b18”,发现rdsBizNo出自https://rds.alipay.com/captcha.htm中返回的token
#### captcha.htm-验证码token获取
那么我们看captcha.htm的post参数有哪些
#### 打断点分析
那么我们现在具体要看的就是bizNo和data的参数是怎么来的。
我们分别点击这两个JS文件(会自动在Sources中打开,点{}格式化一下代码)
我们分别搜索“bizNo”和“rdsBizNo”并多打几个断点查看他们是怎么处理来的
#### 重发验证码 断点
重新发送下验证码,会自动断点,我们能看到此时的rdsBizNo=e=“62cdca05ee1748b495d8eb7d5d007b4091872ce4f93b4e00ae9b3eecf192c9c0” 【因为每次发送验证码的参数都不一样,所以不能按照第一次抓包的参数来解】
#### Qm
我们可以看出这个bizNo是又Qm函数传递而来,那我们搜索Qm(看看哪里调用了Qm函数
得出captcha.htm中的bizNo参数 = e = ("" + R() + R()).replace(/-/g, "")
#### R()
那么这个R()函数是干嘛的呢。我们去看看
~~~JavaScript
function I(e, t, n) {
e = e || {};
var r = e.random || (e.rng || T)(); //发现一个T
if (r = 15 & r | 64,
r = 63 & r | 128,
t) {
n = n || 0;
for (var a = 0; a < 16; ++a)
t = r;
return t
}
return D(r) //发现一个D
}
~~~
#### T
让我们看看T是什么鬼
~~~JavaScript
E = _, O = new Uint8Array(16);
function T() {
if (!d && (d = "undefined" !== typeof crypto && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || "undefined" !== typeof msCrypto && "function" === typeof msCrypto.getRandomValues && msCrypto.getRandomValues.bind(msCrypto),
!d))
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
return d(O)//又发现一个d函数和O参数O = new Uint8Array(16);
}
~~~
#### d
那么我们看看d是什么鬼(这绕来绕去的,真晕,搞这么多干什么。。简单点不好吗)
d=getRandomValues()???我们看上面的抛出异常发现crypto.getRandomValues()。那么d=crypto.getRandomValues()吗?测试下
看来d真的是crypto.getRandomValues(),那么T解开迷雾了,接下来解D的迷雾
#### D函数
我们追过去看下D函数
~~~JavaScript
function M(e) {
var t = arguments.length > 1 && void 0 !== arguments ? arguments : 0
, n = (j] + j] + j] + j] + "-" + j] + j] + "-" + j] + j] + "-" + j] + j] + "-" + j] + j] + j] + j] + j] + j]).toLowerCase(); //发现野生j
if (!N(n))
throw TypeError("Stringified UUID is invalid"); //uuid无效?
return n
}
~~~
#### j变量
我们断点打印一下j
有没有很熟悉?没错,我之前写e4a随机mac的时候用到过这个10进制转16进制的这种255=ff
所以我们用最笨的方法可以自己写JS来代替j
~~~JavaScript
var str='00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f,60,61,62,63,64,65,66,67,68,69,6a,6b,6c,6d,6e,6f,70,71,72,73,74,75,76,77,78,79,7a,7b,7c,7d,7e,7f,80,81,82,83,84,85,86,87,88,89,8a,8b,8c,8d,8e,8f,90,91,92,93,94,95,96,97,98,99,9a,9b,9c,9d,9e,9f,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,ca,cb,cc,cd,ce,cf,d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,da,db,dc,dd,de,df,e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,ea,eb,ec,ed,ee,ef,f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff';j=str.split(",");
~~~
#### 小小总结一下现有的函数和参数
| 函数/参数 | 值 |
| ------------- |:-------------:|
| d | crypto.getRandomValues() |
| O | new Uint8Array(16) |
| T | d(O)=crypto.getRandomValues(new Uint8Array(16)) |
| j | 就是一个16进制的数组集,也就是上面咱们自写的一个j |
| D | j]+....+j]一系列操作 |
| O | new Uint8Array(16) |
#### 我们自己写一个生成bizNo的js代码
因为我用的是e4a,所以要直接调用网页的函数/变量/或者是自写函数/变量,因为无法直接调用,所以要写生成bizNo的代码。
~~~JavaScript
var str = '00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f,40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f,50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f,60,61,62,63,64,65,66,67,68,69,6a,6b,6c,6d,6e,6f,70,71,72,73,74,75,76,77,78,79,7a,7b,7c,7d,7e,7f,80,81,82,83,84,85,86,87,88,89,8a,8b,8c,8d,8e,8f,90,91,92,93,94,95,96,97,98,99,9a,9b,9c,9d,9e,9f,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,aa,ab,ac,ad,ae,af,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,ca,cb,cc,cd,ce,cf,d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,da,db,dc,dd,de,df,e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,ea,eb,ec,ed,ee,ef,f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,fd,fe,ff';
j = str.split(",");
M = function (e) {
var t = arguments.length > 1 && void 0 !== arguments ? arguments : 0,
n = (j] + j] + j] + j] + "-" + j] + j] + "-" + j] + j] + "-" + j] + j] + "-" + j] + j] + j] + j] + j] + j]).toLowerCase();
return n
};
e = e || {};
t = null;
var r = crypto.getRandomValues(new Uint8Array(16));
if (r = 15 & r | 64, r = 63 & r | 128, t) {
n = n || 0;
for (var a = 0; a < 16; ++a);
t = r;
console.error(t)
};
M(r);
~~~
#### 分析data参数
前面我们只是分析了bizNo,现在到了data的时候了。
captcha.htm中有scene=DO_NOTHING的参数,那我们搜DO_NOTHING
找到data:t,看下面有extra: {token: t},结合抓包captcha.htm得到的结果,可得知t就是data,我们往上看
~~~JavaScript
var d = this
, t = "00000000000000000000000000000000";
try {
t = antcap.fnGetRdsData()
}
~~~
那么data = t = antcap.fnGetRdsData() ,data结案。
### 发送验证码(mgw.htm页面sendVerifyCode的post参数)
前面我们几乎把所有的参数和函数都解了一遍,并且可以自己自写函数并生成相对于的bizNo和data,那么mgw.htm页面的参数也就全都浮出水面了。
| captcha.htm | mgw.htm | 由来|
| :------------- |:-------------:| -----:|
| bizNo | rdsBizNo | 前面写的自写bizNo代码 |
| data.extra.token | rdsToken | captcha.htm返回 |
### 提交验证码(mgw.htm页面outPrize的post参数)
这个就比较简单了。。。3给参数。我就不一一解了。。
# 小结
我们能通过JS自写bizNo代码然后调用网页页面antcap.fnGetRdsData()生成data参数,来过captcha.htm生成token
并拿着token和之前的bizNo,下发验证码,然后通过监听通知栏拿到短信中的验证码,并自动提交验证码。。即可达到全自动领盲盒的效果。
PS:在调试的过程中我发现,下发验证码的source参数固定不边,提交验证码的source参数更改也能领卡。
值得注意的是:小弟没学过java,不太清楚java需要实现这个功能是怎么写的代码,我这是用的e4a编写。
# 大意了
评论区也有用python直接随机生成一个bizNo,获取token:https://www.52pojie.cn/forum.php?mod=redirect&goto=findpost&ptid=1364891&pid=36744526
我用易语言随机生成bizNo和data试了下,结果经常能正常收到短信!!!
我还在这白白分析JS代码,白白截图写帖子。。。。
以下为下发验证码的易语言源码。
密码:52pj下载:https://wwa.lanzouj.com/iE1zwla11wf
~~~e
.版本 2
.支持库 spec
.程序集 窗口程序集_启动窗口
.程序集变量 data, 文本型
.程序集变量 返回结果, 文本型
.程序集变量 biz, 文本型
.程序集变量 token, 文本型
.程序集变量 手机号, 文本型
.子程序 __启动窗口_创建完毕
手机号 = “183xxxxxx72”
.如果真 (手机号 = “”)
返回 ()
.如果真结束
biz = 文本_取随机字符 (64, 位或 (1, 2))
data = 子文本替换 (data, “++phone++”, 手机号, , , 真)
data = 子文本替换 (#常量1, “++data++”, 文本_取随机字符 (64, 位或 (1, 2)), , , 真)
data = 子文本替换 (data, “++biz++”, biz, , , 真)
调试输出 (data)
返回结果 = 编码_Utf8到Ansi (网页_访问 (“https://rds.alipay.com/captcha.htm”, 1, data, , , “content-type: application/json”))
返回结果 = 子文本替换 (返回结果, #引号, “'”, , , 真)
token = 文本_取出中间文本 (返回结果, “token':'”, “'”)
调试输出 (返回结果)' 请求captcha.htm
调试输出 (token)
返回结果 = 编码_Utf8到Ansi (网页_访问 (“https://mobilegw.alipay.com/mgw.htm?_fli_online=true&operationType=alipay.tradecsa.biz.blessingprod.wufu2021.sendVerifyCode&requestData=[%7B%22mobile%22%3A%22” + 手机号 + “%22%2C%22source%22%3A%22DEFAULT%22%2C%22rdsBizNo%22%3A%22” + biz + “%22%2C%22rdsToken%22%3A%22” + token + “%22%7D]&_=1612356526737&callback=jsonp1612356512610”, , , , , ))
调试输出 (返回结果)' 下发验证码请求
.子程序 _按钮1_被单击
子程序_提交验证码 (手机号, “DEFAULT”, “短信验证码”)
.子程序 子程序_提交验证码
.参数 手机号1, 文本型
.参数 类型, 文本型
.参数 验证码, 文本型
返回结果 = 编码_Utf8到Ansi (网页_访问 (“https://mobilegw.alipay.com/mgw.htm?_fli_online=true&operationType=alipay.tradecsa.biz.blessingprod.wufu2021.outPrize&requestData=[%7B%22mobile%22%3A%22” + 手机号1 + “%22%2C%22source%22%3A%22” + 类型 + “%22%2C%22ackCode%22%3A%22” + 验证码 + “%22%7D]&_=1612357768558&callback=jsonp1612356512611”, , , , , ))
调试输出 (返回结果)
~~~
哈哈,其实如果你不带data参数,也可以正常获取到token的:lol
我写的python直接随机生成一个bizNo
digits = 32
hex = codecs.encode(os.urandom(digits), 'hex').decode()
data = {
'appid': "blessingprod_wufu_otp",
'bizNo': hex,
'mobile': mobile,
'refer': "",
'scene': "DO_NOTHING",
'type': "silence",
'useragent': "Mozilla/5.0 (Linux; U; Android 10; zh-CN; MI 9 Build/QKQ1.190828.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 Quark/4.3.3.145 Mobile Safari/537.36 Edg/89.0.4389.6"
}
self.s.options(self.getCaptchaUrl)
try:
r = self.s.post(self.getCaptchaUrl, json=data,
headers=self.headers)
有点小bug 华为会把通知都叠一起 如果不手动清除上一条通知 就读取不到第一条同号码发来的验证码 只有每发一条验证码然后领完之后清除通知栏通知 然后下一条验证码才能读取到 有智能短信识别的,需要关闭智能识别,然后不用修改前缀就可以用,还有就是延时是不是太长了啊,屏幕需要常亮,要不是就锁屏了! 真是复杂啊,编程自学中 厉害厉害 有点复杂啊,看见有人出钱收万能福。。。 笑己可笑 发表于 2021-2-3 10:49
有点复杂啊,看见有人出钱收万能福。。。
。。不看下面的解析的话,单独下载APP全自动操作。。这有啥复杂的。/。。{:301_1008:} 安装失败了 貌似很好玩,试试看 youjianpps 发表于 2021-2-3 10:52
安装失败了
有点着急,忘记签名了。。
重新下载即可密码52pj地址https://wwa.lanzouj.com/imktFl8z6wh JS分析,比APP有意思了 看起来有点强大