本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【K哥爬虫】联系作者立即删除!
继上次粉丝提问,K哥出了对应站点的分析文章之后,又有不少小伙伴提出了在逆向一些网站的时候碰到的问题,态度都很友好,K哥会尽力满足粉丝需求,不过只能一个个慢慢来,本文先对其中一个进行逆向分析:
aHR0cHM6Ly9zZWFyY2guaWNrZXkuY24vP2tleXdvcmQ9RVJKVTAzRjEwMDJW
打开开发者人员工具,随便搜索一个型号的芯片,在 Network 中即会抓包到相应的数据接口,即 /search/ajax-get-res-v001
:
请求参数如下,keyword
大概率就是加密的搜索内容,v_
是固定值,font_ident
、p
、_csrf
都会动态变化,需要逐个研究分析:
该网站存在风控,会弹出极验四代语序点选的验证码,这里就不赘述了,感兴趣的可以阅读K哥往期文章 【验证码逆向专栏】极验三代、四代点选类验证码逆向分析:
该接口是 XHR(XMLHttpRequest)类型的请求,可以直接下个 XHR 断点,这样定位到的位置通常在加密处理完成之后,已经准备发送请求了,优点是便于踪栈,更容易找到加密的地方。在开发者人员工具 Source 面板右侧的 XHR/fetch Breakpoints 中添加截取的接口 URL:
刷新网页即会断住:
向上跟栈到 ajax 中,于 send 处打下断点,F8 下步断点,断过来,可以看到,此时 keyword 参数的值是明文,也就是搜索的芯片型号:
接下来就需要找一下这段明文是在哪被加密的,向上跟栈到 psB-acac185595.js
中,很明显,该 js 经过了 OB 混淆(Obfuscator),感兴趣的可以使用 AST 技术解一下,关键的加密逻辑大概率就藏在这里面。跟到下图处,出现了几个接口所需的请求参数,这里的 keyword 仍是明文状态:
直接在 psB-acac185595.js
中 ctrl+f 搜索 keyword,总共有 23 个结果,不多,逐个分析下,在可能是加密算法的位置打断点分析,ERJU03F1002V
在下图处被加密成了 RVJKVTAzRjEwMDJW
:
跟进到 _0x7f9865[_0xfe4009(0x82c)]
函数中,直接把算法扣下来:
我们来分析下这是什么算法,倒着看,_0x70f89f
、_0x1d4342
之类的是一些十进制数,keyStr.charAt(_0x70f89f)
就是获取 keyStr 字符串特定位置的字符值,最后拼接起来:
keyStr 就是源码中的 this["_keyStr"]
,其值如下,长度为 65 位:
这一串完全符合 Base64 编码索引表的特征,包含大写字母(A-Z)、小写字母(a-z)、数字(0-9)、加号(+)和斜杠(/),64 位,还有一个填充字符(=),Base64 编码的基本流程如下,例如编码 Hello 字符串:
72 101 108 108 111
;72 101 108
和 108 111 0
;72 101 108
得到 01001000 01100101 01101100
,首尾相连,形成 24 位的二进制数;ASCII 码表和 Base64 索引表可于公众号回复关键词 ascii 或 base64 获取,Base64 编码图解:
其实该数据接口对于 Base64 编码也有所提示 乛◡乛:
可以去 K哥爬虫工具站 验证一下,结果一致:
至此 keyword 参数就分析完成了。
前文提到几个加密参数都在一块,如下图所示,断住后观察一下,v
为 _0x501622
,定义在上面几行,就是 13 位时间戳:
font_ident 直接从 this 中取到,其值不是通过加密算法生成的,在该网页的源代码中,可以直接使用 xpath 或者正则表达式匹配出来:
p 参数值长度为 32 位,看着很像是 MD5 加密,我们来跟一下,p 参数在下图处生成:
跟到 _0x101cba[_0xfe4009(0x412)
函数中去,p 参数的值就是 window['x']
:
直接 hook 一下 window 中的 x 参数,断住后跟栈分析,使用 Fiddler 或者油猴之类的都可以,hook 脚本如下:
刷新网页,成功断住,此时 window['x']
的值已经生成了:
向上跟栈到 VM 中,可以看到 window.x = hex_md5('xxx'),这里像是 MD5 加密的源码:
我们直接拿加密内容去爬虫工具站测试一下,发现值并不一样,这里的 MD5 算法可能经过了魔改:
先直接将整段代码扣下来,保存到本地,简单改改能直接运行:
来看看传入的 17104110xxx
是什么,接着向上跟栈到下图处,这里的逻辑就很有意思了,_0x4c3be9
就是 MD5 加密的参数:
跟进到 _0x24f5ec["decode"]
函数中分析一下,取消 hook,断进去,_0xc8f1ce
就是 _0x2b037f
,是一个固定的字符串,这里的算法逻辑是不是很眼熟,和 keyword 参数一样,是 base64,不过这里是解码的过程,将一大串字符串还原成了刚刚的 MD5 算法,用 replace 方法替换 mwqqppz
字符串传入待加密值,最后使用 eval 方法执行解码出的 JavaScript 代码,实现加密操作:
接着跟栈分析 17104110xxx
,跟到 handleParamsV1
中去,加密参数就是由 p1
、p2_
、code
三个参数拼接而成的:
往后跟下栈就会发现,p1
参数是个时间戳,其值和前文所讲的 v
参数的值相同,p2_
就是搜索的芯片型号经过 base64 编码后得到的值,code
定义如下:
与前面的不同,$.md5
使用的是标准的 MD5 加密算法:
window.relwarckcuf
的值会变化,其值需要从该页面的源代码中获取:
生成 code 同样使用到了 eval 方法,逻辑就是将 tmp 参数值传到了 window.relwarckcuf
函数中,生成了最终的 code 值,较为别致,跟进到这个函数中去:
跳转到 79baf82e5b7315e32957b68b5b3d0260
文件中,这个文件名是会动态变化的,每次刷新页面都不一样,同样可以从网页源代码中提取出来,完整链接 https://search.ickey.cn/x/c/79baf82e5b7315e32957b68b5b3d0260
:
就是套了两个 switch,做了些运算,不同文件 4|1|2|3|6|5|0
的顺序会变,但算法的执行顺序其实是固定的,唯一会变的值就是 _0x5b2c03['lQMEJ']
,先将函数部分扣下来:
JavaScript 代码:
Python 复现:
前文提到,下图的这个值是会改变的:
我们来分析一下,这个值为什么会变,跟进到 _0x2a0d2b
函数中去,这里都是通过传一个整数和一个字符串,_0x2c3e()
就是个大数组,会变化,从数组中按索引取值然后计算得到最终的参数值,0x1c2
位置的值也并非固定的,数组和这个值都需要匹配出来:
_0x7ebea5(大数组)
以及一些值需要动态提取,这段代码简化后如下:
一般情况下,可以使用 AST 技术或者正则表达式,将上述动态变化的值匹配出来,然后传入到算法中,即可得到最终的结果:
跟到 '_csrf': _0x66ec8(_0x506031(0x1e8) + 'rf')[_0x370168(0x7a1)]()
中分析一下就会发现,_csrf
参数与 font_ident
参数一样,都是从网页源代码中获取到的:
至此,所有参数都分析完成了。
cookies 中有个参数值 seaut,如果该值或者加密参数不对,是无法获取到数据的(网页端的 cookies 可删除、修改参数值):
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。