重庆南川网站制作价格,关键词点击排名软件,营销网站设计上海天气,百度seo自动优化某信用中心之加速乐实战分析 某信用中心之加速乐实战分析声明逆向目标逆向分析第一层cookie获取第二层cookie获取调试分析JS文件 模拟执行致谢 某信用中心之加速乐实战分析
声明
本文章中所有内容仅供学习交流#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理#x… 某信用中心之加速乐实战分析 某信用中心之加速乐实战分析声明逆向目标逆向分析第一层cookie获取第二层cookie获取调试分析JS文件 模拟执行致谢 某信用中心之加速乐实战分析
声明
本文章中所有内容仅供学习交流抓包内容、敏感网址、数据接口均已做脱敏处理严禁用于商业用途和非法用途否则由此产生的一切后果均与作者无关若有侵权请联系我立即删除
逆向目标 逆向分析
通过打开F12抓包查看是否存在加密参数
发现我们需要的数据在xhr请求中 再查看标头和负载初步看好像没有加密参数所以我们直接发送request请求尝试能不能获取到数据。 发送请求后发现返回一个js文件 如果有了解过的同学就知道这是加速乐cookie反爬虫是知道创宇推出的一款网站CDN加速、网站安全防护平台。
加速乐的特点是访问网站一般有三次请求
第一次请求网站网站返回的响应状态码为 521响应返回的为经过 AAEncode 混淆的 JS 代码第二次请求网站网站同样返回的响应状态码为 521响应返回的为经过 OB 混淆的 JS 代码第三次请求网站网站返回的响应状态码 200即可正常访问到网页内容。
我们可以在网页中清除cookie后再尝试抓包查看是否和我们上述所说 接下来就是重点分析这三个cookie文件
第一层cookie获取
直接查看 response 是显示无响应内容的所以我们通过之前发送请求包中返回的响应包代码进行分析 分析响应包可以看到第一个xyxx-list.do返回的响应内容经过 AAEncode 加密大致内容如下可以看到一堆颜表情符号还挺有意思的
scriptdocument.cookie(_)(_)(j)(s)(l)(_)(c)(l)(e)(a)(r)(a)(n)(c)(e)(_)(s)()(-~{})(6)(36)(~~[])(24)(26)(([2]02))((1[4]1))((12))(9)(.)(1[0]-(1))((21))(1[0]-(1))(|)(-)(-~0)(|)(I)(G)(j)(P)(44)(l)(r)(j)(q)(T)(P)(y)(q)(v)(O)(i)(44)(N)(i)(n)(G)(B)(O)(f)(r)(k)(s)(%)(12)(D)(;)(m)(a)(x)(-)(a)(g)(e)()(12)(33)(~~[])(~~{})(;)(p)(a)(t)(h)()(/);location.hreflocation.pathnamelocation.search/scriptdocument.cookie 里的颜表情串实际上是第一次 __jsl_clearance_s 的值可以直接通过正则提取到加密内容后使用execjs.eval()方法即可得到解密后的值
import re
import execjsjs_clearance re.findall(cookie(.*?);location,response.text)[0]
jsl_clearance_s execjs.eval(js_clearance).split(;)[0]
print(jsl_clearance_s)// __jsl_clearance_s1690686292.777|-1|uzTU5s0inLnvhCVdFmuyRXtr69k%3D第二层cookie获取
第二层cookie获取可以直接查看第一个xyxx-list.do的响应包或者通过第一层cookie获取后的__jsl_clearance_s 和__jsluid_s两个cookie参数发包请求也能获得对应响应代码如图所示 将文件复制出来分析后发现是一个经过 OB 混淆的 JS 文件我们需要对其进行调试分析所以我们首先需要寻找找这个js代码的加密位置先清除本地浏览器的cookie。 然后在源代码中勾选住脚本这样网页执行的每一个js文件都会被我们断住了当然也可以使用hook注入等方式寻找加密位置 刷新网页然后不断进行F8往下我们首先会看到我们之前分析过的第一个cookie文件继续F8往下走 成功找到我们所需要的js文件 调试分析JS文件
由于网站是cookie加密所以每次刷新JS文件的一些参数都是在动态变换的所以我们可以使用本地替换的方式固定一套下来再进行调试。然后在该 JS 文件中通过 CTRL F 搜索 document只有一个在第 596 行打断点调试选中_0x1739(0x93, 3RK) ie后进入控制台输入会发现这里就是 cookie 经过混淆后的样式 将等号后面的内容全部选中进入控制台输入可以发现这里生成了 Cookie 中 __jsl_clearance_s 参数的值 至此我们知道了 Cookie 生成的位置接下来就需要了解其加密逻辑和加密方法然后通过 python 对其进行复现了document 部分完整的代码如下
document[_0x1739(0x93, 3RK) ie] _0x3fa957[_0x1739(0x9b, 9PBK) W](_0x3fa957[_0x1739(0x43, 7C)) W](_0x3fa957[_0x1739(0xbc, ML*i) X](_0x3fa957[_0x1739(0x37, tfb]) X](_0x5a3a5f[tn] , _0x4bca4c[0x0]), _0x1739(0x114, XV)) _0x1739(0x10f, )!ai) ), _0x5a3a5f[vt]), _0x1739(0x20, 711Q) _0x1739(0xda, R2lr) \x20/);这里等号后面的内容比较冗杂其实我们想要获取的是 jsl_clearance_s 参数的值通过逐步分析调试可以看到其值由(_0x5a3a5f[tn] , _0x4bca4c[0x0])生成: 继续分析可知_0x5a3a5f[tn]对应的部分是__jsl_clearance_s而其值是_0x4bca4c[0x0]因此我们需要进一步跟踪 _0x4bca4c 生成的位置。 通过搜索在第 587行可以找到其定义生成的位置打断点调试可以看到_0x4bca4c[0x0]其实就是取了 _0x4bca4c 数组中的第一个位置的值 我们来进一步分析 _0x4bca4c 后面代码各自的含义,完整代码如下
_0x3fa957[_0x1739(0x11, 3)Nv) V](_0x29f4ef, _0x5a3a5f[ct], _0x5a3a5f[_0x1739(0x68, GmG)]);通过控制台可知_0x3fa957[_0x1739(0x11, 3)Nv) V]取的是后面参数中第一个参数当做函数体第二和第三个值当做参数传入。
_0x5a3a5f[ct])取的是 go 函数传入的字典中 ct 参数的值 分析可知将_0x5a3a5f[_0x1739(0x68, GmG)]数组中的值按照某种规则进行拼接就是 __jsl_clearance_s 参数的值并且_0x1739(0x68, GmG)对应字典中 bts 的值
所以需要进一步跟踪 _0x29f4ef可以发现其是个函数体第 582 行 return 后的返回值就是 __jsl_clearance_s参数的值 在第 581 行打断点调试能知道 hash 后 _0x2cc335 为 __jsl_clearance_s 参数的值 hash( _0x2cc335) 的值为 _0x2cc335 经过加密后的结果在本例中加密结果特征分析很明显能看出是SHA256的加密长度其实通过查看之前获取的go字典也能看到他写出了用的什么加密方式。
但加密的方法即 hash 方法不全是 SHA256多刷新几次发现会变化实际上这个 hash 方法与原来调用 go 函数传入的字典中 ha 的值相对应ha 即加密算法的类型一共有 md5、sha1、sha256 三种所以我们在本地处理的时候要同时有这三种加密算法通过 ha 的值来匹配不同算法。 进一步观察这里还有个 for 循环分析发现每次循环 hash(_0x2cc335) 的值是动态变化的原因是 _0x2cc335 的值是在动态变化的_0x2cc335 中只有中间两个字母在变化不仔细看都看不出来 跟进 _0x2cc335 生成的位置分析可知 _0x2cc335 参数的值是由 _0xf7137b 数组的第一个值加上两个字母再加上该数组第二个值组成的结果 _0x2cc335的源代码混淆参数很多不好直接分析建议解混淆后再进行分析
var _0x2cc335 _0xf7137b[0x0] _0x5a3a5f[_0x1739(0x89, BSbR) s][_0x1739(0xb8, jBDG) tr](_0x107bb7, 0x1) _0x5a3a5f[_0x1739(0x105, kvMu) s][_0x1739(0x6e, m%$p) tr](_0x4ec95b, 0x1) _0xf7137b[0x1];解混淆后代码如下
var _0x2cc335 _0xf7137b[0x0] _0x5a3a5f[chars][substr](_0x107bb7, 0x1) _0x5a3a5f[chars][substr](_0x4ec95b, 0x1) _0xf7137b[0x1];中间两个字母是将底下这段写了两次生成的即 _0x5a3a5f[chars][substr][1] 取字典中 chars 参数的一个字母取了两次这里通过 for 循环在不断取这两个值直到其值加密后与 _0x1c0bb7即 ct的值相等则作为返回值传递给 __jsl_clearance_s 参数
_0x1c0bb7为ct的值 最前面_0x3fa957[_0x1739(0xf0, oMaE) E]是个方法我们进一步跟进过去看这个方式里面实现了什么样的逻辑
其内容如下可以看到这个方法返回的值是两个相等的参数
模拟执行
综上所述_0x29f4ef 函数中的逻辑就是判断 _0x2cc335 的值经过 hash 方法加密后的值是否与 ct 的值相等若相等则将返回值传递给 __jsl_clearance_s 参数循环完后还未有成功匹配的值则会执行提示失败传入参数中 ha 的值是在变化的即加密算法也是在变化的有三种加密方式 SHA1、SHA256 和 MD5我们可以扣下三种 hash 方法也可以直接使用 crypto-js 库来实现
var CryptoJS require(crypto-js);function hash(type, value){if(type md5){return CryptoJS.MD5(value).toString();}if(type sha1){return CryptoJS.SHA1(value).toString();}if(type sha256){return CryptoJS.SHA256(value).toString();}
}function cookies(_0x5a3a5f){var _0x26fd06 new Date();function _0x29f4ef(_0x1c0bb7, _0xf7137b) {var _0x5dfb01 _0x5a3a5f[chars][length];for (var _0x107bb7 0x0; _0x107bb7 _0x5dfb01; _0x107bb7) {for (var _0x4ec95b 0x0; _0x4ec95b _0x5dfb01; _0x4ec95b) {var _0x2cc335 _0xf7137b[0x0] _0x5a3a5f[chars][substr](_0x107bb7, 0x1) _0x5a3a5f[chars][substr](_0x4ec95b, 0x1) _0xf7137b[0x1];if ((hash(_0x5a3a5f[ha],_0x2cc335) _0x1c0bb7)) {return [_0x2cc335, new Date() - _0x26fd06];}}}}var _0x4bca4c _0x29f4ef (_0x5a3a5f[ct], _0x5a3a5f[bts]);return {__jsl_clearance_s : _0x4bca4c[0]};
}console.log(cookies({bts: [1690639070.278|0|ihl, l%2FaY6Y3B%2FKq8I4GT55NZvc%3D],chars: iMyDvZzWmPBnCGdujVpCAJ,ct: fb9fe0ec006b42f92ffbd372dc71b4612c989e2bf4d095afb8abbfce8ed3d35f,ha: sha256,is: false,tn: __jsl_clearance_s,vt: 3600,wt: 1500
}))获取结果如下 python代码只演示部分关键代码完整代码可私信联系我
def get_first_cookie():global cookiesresp_first requests.post(url, headersheaders, datadata)# 获取 cookie 值 __jsluid_scookies.update(resp_first.cookies)# 获取第一层响应内容, AAEncode 加密content_first re.findall(cookie(.*?);location, resp_first.text)[0]jsl_clearance_s execjs.eval(content_first).split(;)[0]# 获取 cookie 值 __jsl_clearance_scookies[__jsl_clearance_s] jsl_clearance_s.split()[1]def get_second_cookie():global cookies# 通过携带 jsluid_s 和 jsl_clearance_s 值的 cookie 获取第二层响应内容resp_second requests.get(urlurl, headersheaders, cookiescookies)# 获取 go 字典参数go_params re.findall(;go\((.*?)\)/script, resp_second.text)[0]params json.loads(go_params)return paramsdef get_third_cookie():with open(jsl.js, r, encodingutf-8) as f:jsl_js f.read()params get_second_cookie()# 传入字典third_cookie execjs.compile(jsl_js).call(cookies, params)cookies.update(third_cookie)def main():get_first_cookie()get_third_cookie()resp_third requests.post(url, headersheaders,cookiescookies , datadata)resp_third.encoding utf-8print(resp_third.text)if __name__ __main__:main()获取结果如下 致谢
部分思路代码通过以下文章学习【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解