某音a_bogus纯算分析
由于不会补环境,所以只能去搞纯算了
本篇文章可能不是很适合纯新手来看,倒是很适合正在搞纯算的你
某音的xbogus算法已经改成了abogus了,虽然xb还能用,但是也该更新了
![image-20240603124507081](upload/attach/202406/901977_HR4CKWE6GMSH7H3.jpg)
jsvmp插桩:
1 2 3 | "位置 1" , "索引m" , m, "索引r" , r, "值p: " , JSON.stringify(p, function(key, value) { if (value = = window) { return undefined} return value})
"位置 2" , "索引m" , m, "索引r" , r, "值p: " , JSON.stringify(p, function(key, value) { if (value = = window) { return undefined} return value})
|
在哪定位加密位置就不多说了,网上一大堆呢
直接步入正题
参数加密
打开我们的日志,映入眼帘的就是下面这个场景
![image-20240527231219295](upload/attach/202406/901977_AEJDXKXMBBPERNB.jpg)
可以看到reg里面有一串数组,最开始后面还没有参数,等到第五行的时候,我们的请求参数出现了
经过了2次不为人知的操作,我们的参数变成了一行数组。
从此处我们就可以得知,这个数组,是参数转化过去的。
所以我们在下面这个索引位置设置条件断点,就可以进入到加密的过程了
![image-20240527231139019](upload/attach/202406/901977_74D2R9674RSHQCD.jpg)
找到加密过程之后自己抠出来或者手动实现都是可以的。
再继续往下看,会发现又经过了reg这个数组,然后嗖的一下,出现了一个新的数组
![image-20240527231258186](upload/attach/202406/901977_EJEWNAQVDPMJKRA.jpg)
而且这个新数组的上一个地方的末尾,嘿,出现了上面的数组。这就说明下面这个数组是上面数组生成出来的,我这么猜测没有问题吧。
测试一下,果然一样
![a961d79795d4bd27e1f3844b8f9ca8c](upload/attach/202406/901977_GP33ME95EHW3CCG.jpg)
![4580cbd88b31853d37fb40a6d3026c0](upload/attach/202406/901977_6JA29PTGTP2N5KX.jpg)
至此我们迈出了历史性的一小步
突然有一位靓仔就很奇怪,明明我的操作一样,怎么出来的结果不一样啊?
因为看东西要自己看全面,这个参数的最后还加上了cus这三个字符
千万不要全听全信,写教程的也不一定的是对
![image-20240527231038151](upload/attach/202406/901977_QDU29CDUTY3HY4P.jpg)
有了上面的经验之后,我相信看这篇文章的帅哥美女,已经能下面这个是加密什么的了
![image-20240527231018291](upload/attach/202406/901977_RZP9DQNTF96R3FH.jpg)
没错,就是加密了cus,把cus的字符串经过了两次数组转换。
如果没有post就只加cus,如果有的话就在post参数的末尾加上cus
这两个参数的加密到这里就完成了
我们得到了两个数组
先放在这里,后面要用。
UA加密
之前研究过某音的小伙伴一定知道,如果请求的ua改变的话,生成的这个加密参数就会失效。
所以呢,ua也肯定是校验的一部分。
我们该怎么知道这个jsvmp是如何操作ua的呢
当然是继续看日志了!
![image-20240527225844688](upload/attach/202406/901977_XB8GKP4VHGDG3HZ.jpg)
没往下滑几行,就看见了我们亲切的ua。
但是好像没对我们的ua操作什么,倒是出现了一个奇怪的unicode
我们亲切的把它称为小乱码,那这个小乱码是怎么来的呢
看到这个神奇的小数组没有[0.00390625,1,14]
我们把他扔到控制台里,然后获取对应字符
![image-20240527230306506](upload/attach/202406/901977_UM7T7W84JWGV3VC.jpg)
嗯,一模一样啊
什么?你想知道0.00390625是怎么来的?
那我就满足你的好奇心
其实是这么得到的
![image-20240527230606745](upload/attach/202406/901977_H5VD4C59RGB74YS.jpg)
不过这个乱码是有好几个类型的
![image-20240527231427689](upload/attach/202406/901977_8K66DT8CFV4N4EY.jpg)
这个倒是无所谓,我就根据第一个来
还没走几步呢,我们的日志又出现新东西了
![image-20240527231545927](upload/attach/202406/901977_K55PCQJA2W4NA4J.jpg)
从这日志上来看,我可以大胆地推测,后三行那一堆乱七八糟葫芦蛋糕的东西,是从这里进入生成的
![image-20240527231630914](upload/attach/202406/901977_VW8A7VHF8YWBHK4.jpg)
为了确定我们的推测,肯定不能光靠眼睛看了
我们去插日志点的位置打上条件断点
m==17&&r==1379
重放后一步一步的跟栈,我们会进入一个新的jsvmp
进入之后不要慌,我们直接在老地方插上日志点
继续分析
UA乱码生成
![image-20240527232112051](upload/attach/202406/901977_TUNN78TS24T36AP.jpg)
我们刚进入这个jsvmp,就发现这个日志跑了好多东西
慢慢往下滑,滑到256这里
可以发现是生成了长度为256的空数组
搞纯算,不能光看,还得写
我们直接实现一下![image-20240527232315802](upload/attach/202406/901977_AJF6ZKU6MBXM7GC.jpg)
然后继续看
这里我就直接把我当时的记录放上来吧
然后给大家演示几个
![image-20240527232731917](upload/attach/202406/901977_ZRBNQM2AHBGPVPQ.jpg)
大家看不懂很正常,因为我现在都有点看不懂了
我就演示一个给大家看看,你们多加油
![image-20240527233112085](upload/attach/202406/901977_5H4PMJFXEUS6Y9B.jpg)
因为我们生成了256位的数组,肯定不是白生成的
要往里面填充东西的
我截图的是演示的第三位
为什么第一个红框的第三位是1呢
正常来说应该是0,1,2,3,应该是2才对
实际上就是因为前面在计算数值的时候,会把算之前的位数,放到算出来的地方
比如,从日志可以看出
2+1=3
"\u0000\u0001\u000e".charCodeAt(2)=14 ![image-20240527233524731](upload/attach/202406/901977_7QBBG97V6NCVBQA.jpg)
3+14=17
算出来17之后,把第三位替换成17,然后把1放到第17位上
![image-20240527233627636](upload/attach/202406/901977_9HNPJ5USAF8EB84.jpg)
就是这样循环的,直到最后一位
然后我们得到了一个新数组
接着,就是新的一部分
新部分就是我们的上面的数组,跟我们亲爱的UA,进行一些不为人知的交易
这里我就用文字描述一下吧
把新数组设为a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | a[ 0 ] + a[ 1 ]
0 + 218 = > * * 218 * *
a[ 1 ] = a[ 218 ]
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36" .charCodeAt( 0 )
77 a[ 220 ] = > 216 2 + 218 = > 220
77 ^ 216 = > 149
String.fromCharCode( 149 )
* * 218 * * + a[ 2 ] = > * * 235 * *
a[ * * 235 * * ] = > 127
分割线
a[ 2 ] = 127
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.160 Safari/537.36" .charCodeAt( 1 )
127 + 17 = > 144
111 ^a[ 144 ] 233 = > 134
String.fromCharCode( 134 )
* * 235 * * + a[ 3 ] = > * * 255 * *
a[ * * 255 * * ] = > 149
a[ 3 ] = 149
255 + a[ 4 ] = > 280 280 - 256 = 24
|
我上面的记录,都是可以从日志里看出来的
因为这个数组太长了不好截图演示,就这样看吧
UA经过这一系列的加密,最后生成了一个超级大的乱码
UA长字符串
![image-20240527234918425](upload/attach/202406/901977_R298V7PT5QFDGAE.jpg)
这次又没走几步,就变成了一大串字符串了
好家伙,这下聪明的你肯定知道怎么搞了
我们去定位生成位置的上面,然后单步调试进入一个新的jsvmp
![image-20240527235037298](upload/attach/202406/901977_AR9QJZX5WDY95EG.jpg)
我们又要开始新的日志观察了,写到这里我已经有点疲惫了
但我还是得继续写!
这里的部分其实还是之前xb那样,4位一组,如此遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | s.chatAt( 0 ) << 16 2293760
s.chatAt( 1 ) << 8 22016
0 ^ 1 2315776
^s.chatAt( 2 )<< 0 7
2315783
2315783 & 16515072
2097152 >> 18
8
2315783 & 258048
217088 >> 12
53
2315783 & 4032
1536 >> 6
24
2315783 & 63
7 >> 0
7
|
下面我来解释一下
![image-20240528000051325](upload/attach/202406/901977_4395SS798HVM6FZ.jpg)
这个大乱码取第一位的ascii码=82
![image-20240528000330772](upload/attach/202406/901977_FBVNH6PWXDEGREC.jpg)
然后82<<16 = 5373952
第二位取ascii码 = 176
176 <<8 = 45056
5373952^45056 = 5419008![image-20240528000646475](upload/attach/202406/901977_W3MS5DM8MWQCCQU.jpg)
![image-20240528000522370](upload/attach/202406/901977_A3U32SHAV98CVZX.jpg)
然后取ascii第三位 得 240
5419008^240=5419248![image-20240528001014867](upload/attach/202406/901977_U2MGDWM92HM5CCT.jpg)
5419248&16515072 = 5242880
5242880 >>18=20
![image-20240528001151427](upload/attach/202406/901977_2QAJTDW39QWSNJR.jpg)
![image-20240528001053891](upload/attach/202406/901977_M8WZJYRSNWBNWPD.jpg)
第一位就这样推出来了,剩下的就靠宝贝你自己了
搞纯算没有耐心是不行的哦
静下心来慢慢看日志,总有一天能搞出来
然后我们长字符串就生成出来了!神奇吧
简直是一模一样
![image-20240528001532030](upload/attach/202406/901977_MCAUZZTDNTAXMEH.jpg)
![image-20240528001554252](upload/attach/202406/901977_FJ858E84K37KYWC.jpg)
然后又对我们的长字符串进行了一个数组的生成,这里直接用我们上面写好的代码就可以
下面就到了我们的环境监测点了
![image-20240528001804936](upload/attach/202406/901977_FHM3KSNCWUD6JAC.jpg)
环境检测点生成
这里倒是没什么难的,其实就是把每一位字符串的ascii码放到了数组里
![image-20240528001855367](upload/attach/202406/901977_6MKFSTXCF4Y8PT2.jpg)
![image-20240528001918993](upload/attach/202406/901977_XZMHFZPH4RKFDGM.jpg)
自己写一下就可以
炒鸡大数组生成
再往下走,映入眼帘的就是一个炒鸡大的数组了
![image-20240528002042053](upload/attach/202406/901977_CDWAD9B5TEWFMUS.jpg)
这个大数组可谓是集百家之长,东边偷一点,西边偷一点。
不过我们从日志上来分析,还是有迹可循的
就比如96,58这两个数字
![image-20240528002510339](upload/attach/202406/901977_9HXT9XNF8TJYD2C.jpg)
从这个图上是不是就能看出来
是第一个数组的21位,第二个数组的21位
后面的64,51 就是第二个数组的22位,第二个数组的22位
剩下的就麻烦您多费心了,静下心来看日志,一会就搞出来了
里面有固定的也有不固定的,可以抓两次日志对比着来
加油!
接着我们把写好的数组和之前的环境ascii码数组组合起来
在我们组合起来之前呢,我们要把大数组的每一位进行异或,得到的一个结果,放到我们环境数组的末尾
然后再把这俩数组合起来
得到了最终的超级无敌宇宙爆炸大数组
最终之战
这篇文章马上就要步入尾声了,虽然写的不是很详细,但是我觉得一定对你有帮助
![image-20240528003539959](upload/attach/202406/901977_RDS4AES25SXMXTJ.jpg)
从上面的日志来看,我们前面生成了3次乱码,然后合并
接着又把三次合并的乱码跟一个乱码合并
再合并之前呢,这个乱码是先由我们的超级无敌宇宙爆炸大数组,String.fromCharCode生成
然后经过上述提到的UA乱码生成写的代码,最终加密得到一个乱码
最后,我们把这一个乱码经过上文提到的UA长字符串生成
就得到了我们的a_bogus!!!!
成果展示!
![image-20240528004124215](upload/attach/202406/901977_V5XJA43G876XNQA.jpg)
不重要的话
在搞纯算的时候,网上也不乏有各种教程,但是有的教程还不如不发出来,因为太误导人了
不过大部分大佬写的教程还都是很棒很详细的
如果你在我这里看到的芝士还不够你搞出来纯算
你还可以利用搜索引擎去寻找一下别人的教程
集百家之长,这样一定可以完成ab纯算
[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!