最近有粉丝老铁私信问我,能不能分析36氪文章下逆向,粉丝的要求必然要满足,这不就来了嘛
目标地址
分析页面数据来源
打开控制台,随便搜索文章内容的关键字,提示没有搜索到
右键点击
显示网页源代码
都是些js代码,并没有实际的文章内容
从上面测试来看,文章属于后台加密返回的,然后再通过js解密显示而来,我们的目标就是要找到返回的加密数据&js解密函数的地方
找到js解密的地方
输入decrypt(
查询,点击文件进入
格式化代码
文件中搜索
decrypt(
,总共3个,在出现的位置都打上断点,刷新页面
断点成功进入到我们其中的一个
打印下
oe
的值
oe是个对象,state的内容是密文
这里解释下这段代码
//ne是经过efabccee-b754-4c utf-8编码得到的
var ne = ee.a.enc.Utf8.parse("efabccee-b754-4c");
//oe中state存放的值就是对应的密文
var re, oe = window.initialState || {};
//判断oe的字段isEncrypt是否为True,也就是是否加密,如果加密,则调用后面的解密函数
oe.isEncrypt && (oe = JSON.parse((re = window.initialState.state,
//这里可以看出用的AES算法进行解密的
ee.a.AES.decrypt(re, ne, {
mode: ee.a.mode.ECB,
padding: ee.a.pad.Pkcs7
}).toString(ee.a.enc.Utf8).toString())));
到代码执行完解密函数的时候,我们可以看大oe的值已经变了,现在可以看到明文了
因为用的是AES算法,我们来看下这个算法是不是标准的
输出ee.a
的值,看的出来这是一个算法包,里面各种算法包都有,这种情况下99.9%是标准算法,一般我们的前端人员也不会去改写
那就可以用标准的算法库来替换
var CryptoJS = require('crypto-js')
var ne = CryptoJS.enc.Utf8.parse("efabccee-b754-4c");
state = 'xxxxx'
function get_plain(message) {
oe = JSON.parse((re = message,
CryptoJS.AES.decrypt(re, ne, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8).toString()));
console.log(oe['articleDetail']['articleDetailData'])
return oe
}
console.log(get_plain(state))
这里能够输出正确的明文信息
确定返回密文的位置
- 首先查了返回的XHR这几个接口,并没有对应的密文数据
- 因为明文是
window.initialState
中获取的,那我们就直接全局搜索这个关键字 在页面这里发现了,这个值是藏在页面中的,并不是特地接口返回的
python通用解析密文
可以通过python程序获取页面源码
通过xpath提取window.initialState
,再通过正则表达式获取具体的值
python调用js,执行对应的解密方法,获取到明文数据