某盾cd,fp获取(一)

这里是某盾的第一篇,接下来还会有完整的分享

1.开始对目标进行抓包

目标地址: aHR0cHM6Ly9kdW4uMTYzLmNvbS90cmlhbC9qaWdzYXc=

1.https://c.xxx.com/api/v3/get?referer=# 获取图片和滑块的接口,待分析参数 acToken,cb, fp2.https://c.xxx.com/api/v3/check?referer=# 提交参数进行验证 待分析参数 data, actoken 

最开始分析的时候是上一个版本,没想到刚看了一天,这个网站就升级了,内心XXX,上一个版本第一步并没有验证acToken。这里还有一个问题是 如果你之前没有分析过,你抓包感觉是两个http请求就可以了,但其实绝对不是你想的那样。
本篇先对cb fp两个参数进行分析

2.开始调试

全局搜索cb参数,打断点
某盾cd,fp获取(一)
cb 就是 _0x244142()这个函数生成的,而且在cb生成之前,fp已经生成了,继续看cb,点到后面的函数里面去看看
某盾cd,fp获取(一)
_0x387005 = _0x2877  _0x387005就是最上面的那个大数组进行移动之后的数组,里面包含很多字段信息,这里用来让代码混淆起来,增加分析难度,和某验类似
某盾cd,fp获取(一)
第一个函数生成一个字符串,又经过_0x18975f进行二次加密, 就得到了最后的结果,接下来看第一个函数
某盾cd,fp获取(一)
这里面是一个uuid函数,可以直接抠出来,缺少什么补什么,接着看第二个函数,
某盾cd,fp获取(一)
同样是一个普通的函数,也是一样的操作,缺啥就调试补充进去啥,我这里是用node执行,
某盾cd,fp获取(一)
cb参数获取就很简单,接下来是fp,这里有个新的问题,我们调试的js链接最后面有一个v=275609 后面的数字大概刷新页面一两次就会变,导致你之前调试的断点,就会失效,你可以选择用reres保存一份js进行替换,或者记住你上次断点的地方,刷新后立马下断点,立刻再刷新,这样就很麻烦,不过也可以用。还有你刷新了好几次,发现你打的断点没有任何作用,一种可能 你断点,打错了,还有可能是这个是第一次你进入这个网站,他才会生成,就需要clear site data一下。刷新,就会发现它断在断点处。
下面马上来看下fp的生成吧。
某盾cd,fp获取(一)
fp = _0x4fa361 , _0x4fa361是被_0x47ecbd[_0x19d935(0x1af)]赋值,_0x47ecbd = _0x1e67e3[_0x19d935(0xa43)]  所以fp 是_0x1e67e3的一部分,
某盾cd,fp获取(一)
这里的fingerprint和fp的值是一样的,也就是说fingerprint就是fp,接下来找fingerprint怎么生成的。然后在当前js搜索fingerprint,发现了这个
某盾cd,fp获取(一)
fingerprint是在这里生成的,因为他上下参数和上面那个图的字段都对得上,然后看_0x556ecc是怎么生成的,发现是和window有关,在控制台打印一下_0x327e87(0x8e7)
某盾cd,fp获取(一)
fp被fingerprint赋值,fingerprint是被window['gdxidpyhxde']赋值,接下来就开始寻找gdxidpyhxde是怎么生成的,全局搜索gdxidpyhxde,发现在只找到了有一个在js开头的大数组中,除了这一个地方,没有其他的地方
某盾cd,fp获取(一)
那换种方法搜索一下吧。搜索(0x8e7) 发现也只有一个
某盾cd,fp获取(一)
那肯定就是被隐藏起来的了呗,那就换个思路去寻找,这里先说一个笨方法,既然这个参数和window有关。那就可以使用正则 window[.*?= 去搜索一下,在所有出现被赋值,就是说在 = 左面出现的位置,进行打断点。
某盾cd,fp获取(一)
有25个可以一个地方一个地方查看一下,这样可以找到,这个办法有点笨,但是实用,如果window[出现的地方太多,这个办法就不是很方便,可以说会很难受,但这个案例是可以使用的。

下面介绍第二种方法
先将移位后的大数组复制出来。同时验证一下复制出来的数组是否正确
某盾cd,fp获取(一)

第0x8e7位和上面图中的值是一样的,接下来根据数组来替换整个js中需要该数组的地方。

import re# 数组太大,自己去控制台复制吧_0x4b23 = ''''''.strip().split("xxx")print(len(_0x4b23))def _0x2877(_0x1f7720):    return _0x4b23[_0x1f7720 - 0x12f]print(_0x2877(0x8e7))with open("core_all.js", 'r', encoding='utf-8') as f:    js_str = f.read()# 将所有 =_0x2877的变量替换成_0x2877func_list = re.findall("var (.*?) = _0x2877", js_str)print(len(func_list))print(func_list)last_js_str = js_strfor func in func_list:    last_js_str = last_js_str.replace(func, "_0x2877")_0x2877_func_list = re.findall("(_0x2877\(0x.*?\))", last_js_str)print(len(_0x2877_func_list))print(_0x2877_func_list)result_js = last_js_strfor each in _0x2877_func_list:    result_js = result_js.replace(each, '"' + eval(each) + '"')with open("new_core.js", 'w', encoding='utf-8') as f:    f.write(result_js)

替换前
某盾cd,fp获取(一)

替换后的结果
某盾cd,fp获取(一)

接下来在我们生成的js中进行搜索,x,还是只有两处,继续看看还有没有其他的大数组
某盾cd,fp获取(一)

某盾cd,fp获取(一)
在这里又发现了几个数组,猜测可能和这里有关吧,提取一下这几个数组看看,和上面做类似的处理看看。

某盾cd,fp获取(一)
nice,找到了一个新的地方,看看_0x4b1f33在哪里调用了
某盾cd,fp获取(一)
原来在这里,将字符串所有字母转成小写,再看一下_0x62bf4c在哪里调用了
某盾cd,fp获取(一)
在这里,被赋值为Null,就在这打个断点,调试一下吧,当我在重新刷新的时候,发现js文件变了,我这里没有进行替换,你们可以使用reres替换一下啊,在上次找到的位置打个断点。
某盾cd,fp获取(一)
继续向下调试
某盾cd,fp获取(一)
最终在这里发现我们要的fp在这里生成。接下来就是扣代码的时间,补充一下window环境。

某盾cd,fp获取(一)

成功生成。

3.总结:

cb参数获取简单,fp参数混淆的复杂一些,我因为不会ast,所以会走一些弯路,感兴趣的同学可以学一下,我后面正则替换的地方用ast会更容易一些。

今天的分享就到这里,仅供学习,若有侵权,请联系我删除,希望大家可以点个赞支持一下。

广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!