关注微信公众号:K哥爬虫,继续分享爬虫进阶、JS/安卓逆向等技术干货!
申明
本文章中所有内容仅供学习交换,抓包内容、敏感网址、数据接口均已做脱敏解决,严禁用于商业用途和非法用处,否则由此产生的所有结果均与作者无关,若有侵权,请分割我立刻删除!
逆向指标
- 指标:X 球投资者社区 cookie 参数
acw_sc__v2
加密剖析 - 主页:
aHR0cHM6Ly94dWVxaXUuY29tL3RvZGF5
- 逆向参数:Cookie:
acw_tc=27608267164066250867189...
抓包剖析
咱们的爬虫指标是:精髓 —> 今日话题 —> X球热帖,热帖是 Ajax 加载的,很容易找到数据接口,接口没有其余的加密参数,次要是 cookie 里有一些值,没有 cookie 是无法访问的,其中,cookie 里又有一个 acw_sc__v2
的值,是通过 JS 生成的,其余值都是首次拜访首页失去的,抓包如下:
加密查找
咱们革除一下 cookie,关上 F12 开发者工具,刷新页面,发现会进入反调试,呈现了有限 debugger,往上跟调用栈,能够看到这个办法里有一大串混同后的代码,拼接起来其实就是 debugger,如下图所示:
过掉 debugger 也很简略,须要留神的是这个站比拟刁钻,第一次拜访首页间接是混同的 JS 代码,前面才会跳转到失常的 HTML 页面,如果你想本地替换 JS 的话,debugger 倒是过掉了,不过后续就有可能无奈调试了,感兴趣的敌人能够本人试试,这里K哥就间接右键 Never pause here 永不在此处断下了:
咱们察看这个混同代码,间接搜寻 acw_sc__v2
,能够看到最初面有设置 cookie 的操作,其中 x 就是 acw_sc__v2
的值:
参数逆向
咱们往上跟调用栈,看看 x 是怎么得来的,这里 setTimeout 工夫一到就会执行 '\x72\x65\x6c\x6f\x61\x64\x28\x61\x72\x67\x32\x29'
,控制台输入一下会发现就是 reload 办法,传入的参数是 arg2,arg2 的值就是 acw_sc__v2
的值,如下图所示:
arg1 在头部定义了,须要留神的是,每次刷新,这个 arg1 会变,所以咱们在前面取值时要动静获取,咱们把要害代码独自拿进去剖析一下:
var arg1 = '6A6BE0CAF2D2305297951C9A2ADBC2E8D21D48FD';var _0x5e8b26 = _0x55f3('0x3', '\x6a\x53\x31\x59');var _0x23a392 = arg1[_0x55f3('0x19', '\x50\x67\x35\x34')]();arg2 = _0x23a392[_0x55f3('0x1b', '\x7a\x35\x4f\x26')](_0x5e8b26);
能够看到次要就是这个 _0x55f3()
办法,如果你间接把这个办法扣下来的话,本地运行会间接进入死循环,多调试几遍就会发现 _0x5e8b26
调用函数传参每次都是一样的,每次的后果也是一样的,所以能够间接写成定值,arg2 的 _0x23a392[_0x55f3('0x1b', '\x7a\x35\x4f\x26')]
其实就是用了一个匿名函数,如下图所示:
咱们间接跟进这个匿名函数,能够看到外面同样调用了很多 _0x55f3()
办法,咱们间接在控制台输入一下,而后把后果间接拿到本地即可:
所有后果替换掉后,会发现还会依赖另一个匿名函数,最初将这两个匿名函数全副扣下来即可:
当然如果遇到调用十分多 _0x55f3()
办法的状况,那就不可能挨个替换了,就须要进一步剖析该函数外面的逻辑,在本地单步调试,看是因为什么起因进入了死循环,外面十分多的 if-else 语句,必定是短少某个环境导致进入 else 语句,从而导致死循环了,间接删除 else 语句、补环境走 if 语句等做法都是能够的。
残缺代码
GitHub 关注 K 哥爬虫,继续分享爬虫相干代码!欢送 star !https://github.com/kgepachong/
以下只演示局部要害代码,不能间接运行! 残缺代码仓库地址:https://github.com/kgepachong...
JavaScript 加密代码
/* ==================================# @Time : 2021-12-29# @Author : 微信公众号:K哥爬虫# @FileName: get_acw_sc_v2.js# @Software: PyCharm# ================================== */var _0x5e8b26 = '3000176000856006061501533003690027800375'var getAcwScV2 = function (arg1) { String['prototype']['hexXor'] = function (_0x4e08d8) { var _0x5a5d3b = ''; for (var _0xe89588 = 0x0; _0xe89588 < this['length'] && _0xe89588 < _0x4e08d8['length']; _0xe89588 += 0x2) { var _0x401af1 = parseInt(this['slice'](_0xe89588, _0xe89588 + 0x2), 0x10); var _0x105f59 = parseInt(_0x4e08d8['slice'](_0xe89588, _0xe89588 + 0x2), 0x10); var _0x189e2c = (_0x401af1 ^ _0x105f59)['toString'](0x10); if (_0x189e2c['length'] == 0x1) { _0x189e2c = '0' + _0x189e2c; } _0x5a5d3b += _0x189e2c; } return _0x5a5d3b; }; String['prototype']['unsbox'] = function () { var _0x4b082b = [0xf, 0x23, 0x1d, 0x18, 0x21, 0x10, 0x1, 0x26, 0xa, 0x9, 0x13, 0x1f, 0x28, 0x1b, 0x16, 0x17, 0x19, 0xd, 0x6, 0xb, 0x27, 0x12, 0x14, 0x8, 0xe, 0x15, 0x20, 0x1a, 0x2, 0x1e, 0x7, 0x4, 0x11, 0x5, 0x3, 0x1c, 0x22, 0x25, 0xc, 0x24]; var _0x4da0dc = []; var _0x12605e = ''; for (var _0x20a7bf = 0x0; _0x20a7bf < this['length']; _0x20a7bf++) { var _0x385ee3 = this[_0x20a7bf]; for (var _0x217721 = 0x0; _0x217721 < _0x4b082b['length']; _0x217721++) { if (_0x4b082b[_0x217721] == _0x20a7bf + 0x1) { _0x4da0dc[_0x217721] = _0x385ee3; } } } _0x12605e = _0x4da0dc['join'](''); return _0x12605e; }; var _0x23a392 = arg1['unsbox'](); arg2 = _0x23a392['hexXor'](_0x5e8b26); return arg2};// 测试输入// var arg1 = '2410463826D86A52A5BB43A13A80BAE6C4122A73';// console.log(getAcwScV2(arg1))
Python 测试代码
# ==================================# --*-- coding: utf-8 --*--# @Time : 2021-12-29# @Author : 微信公众号:K哥爬虫# @FileName: main.py# @Software: PyCharm# ==================================import reimport execjsimport requestsindex_url = "脱敏解决,残缺代码关注 GitHub:https://github.com/kgepachong/crawler"news_test_url = "脱敏解决,残缺代码关注 GitHub:https://github.com/kgepachong/crawler"headers = { "Host": "脱敏解决,残缺代码关注 GitHub:https://github.com/kgepachong/crawler", "Referer": "脱敏解决,残缺代码关注 GitHub:https://github.com/kgepachong/crawler", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",}def get_complete_cookie(): complete_cookie = {} # 第一次不带参数拜访首页,获取 acw_tc 和 acw_sc__v2 response = requests.get(url=index_url, headers=headers) complete_cookie.update(response.cookies.get_dict()) arg1 = re.findall("arg1='(.*?)'", response.text)[0] with open('get_acw_sc_v2.js', 'r', encoding='utf-8') as f: acw_sc_v2_js = f.read() acw_sc__v2 = execjs.compile(acw_sc_v2_js).call('getAcwScV2', arg1) complete_cookie.update({"acw_sc__v2": acw_sc__v2}) # 第二次拜访首页,获取其余 cookies response2 = requests.get(url=index_url, headers=headers, cookies=complete_cookie) complete_cookie.update(response2.cookies.get_dict()) return complete_cookiedef news_test(cookies): response = requests.get(url=news_test_url, headers=headers, cookies=cookies) print(response.json())if __name__ == '__main__': complete_cookie = get_complete_cookie() news_test(complete_cookie)