背景:需要编写一个爬虫爬取网站的资料,框架写好了,发现该网站所有api都进行了加密.
用fiddler抓包
网页端api如下图所示:
这里可以观察到,这确实就是网站的api.而且返回的都是一大串莫名其妙的东西,随后多抓了几个包,可以发现共同点.
不同的api返回的前面部分都是一样的,这样其实已经可以假想这是一个json,加密肯定不会是md5,base64这些单向加密了.
下载app抓包
一轮操作之后发现,安卓端是一样的返回内容.这样就可以选择逆向的方向了.一般我会先选择js,因为app有可能加壳了之类的,当然如果app没有加壳的话,直接放到jadx的话肯定可以更直观地定位到加密的位置了.
目前有三种选择:
- js逆向
- app逆向
- 从后端找突破口
先从别的地方看一下哪个方向入手比较好
前端分析
直接在前端右键选择检查元素,再右键选择查看源代码,对比如图
可以明显的看出,源代码是没有前端的代码的,只是简单的加载了js和css文件.
由此可见,
- 本网站全是js或者接口生成的界面.
- 但是又因为app端不需要接口返回前端界面,
- 但是app端的接口返回内容和网页端是一样的
综上所述,加密来源是js.app的加密是通过java代码.
js分析
在fiddler进行文件过滤之后可以发现,js只有这两个文件,其中一个是5w行代码,一个是1w行代码.
我打开哪个都会卡几秒.先从1w行的下手.
打开js在线格式化格式化一下.大致拖一下看看是不是全是乱码,实际这个操作没啥用.我们可以直接用搜索大法.目前我们得到能用的常量就是它的api路径.
直接搜索 “searchVideoByClass”
如图可见一发入魂.复制"SEARCH_VIDEOBYCLASS"继续搜索后,最后追踪到这段代码
getVideoList: function() {
var t = this;
this.hasMore && !this.isLoading && (this.setLoadingShow(!0), this.isLoading = !0, this.$axios.postCheckCache(_.SEARCH_VIDEOBYCLASS, {
flag: this.videoFlag,
vt_id: this.typeId,
typeList: this.conditions.join(","),
currentPage: this.currPage + 1,
pageSize: 10
}).then((function(e) {
var n, a = e.data,
i = a.status,
o = a.msg,
s = a.data;
1 == i ? (t.currPage++, t.hasMore = s.pageSize == s.list.length, (n = t.videoList).push.apply(n, Object(P.a)(s.list))) : (t.hasMore = !1, window.console.error("errorCode", i, o, s), t.$u5_global.toastFail("错误:".concat(o)))
})).
catch((function(e) {
t.hasMore = !1,
window.console.error(e),
t.$u5_global.toastFail("数据请求失败")
})).then((function() {
t.setLoadingShow(!1),
t.isLoading = !1
})))
},
一目了然的代码,也没说在哪里加密.只能再从"this.$axios.postCheckCache(_.SEARCH_VIDEOBYCLASS,"这段中找到postCheckCache这个函数.直接跳到函数体中继续分析
mi = {
initAxios: pi,
postCheckCache: function(t, e) {
if (t.needCache) {
var n;
if (n = "".concat(t.toString(), "?data=").concat(it(JSON.stringify(e))), st.hasItem(n)) {
var a = JSON.parse(st.getItem(n));
if (a.expiration > (new Date).getTime()) return new Promise((function(t) {
a.status = 200,
a.statusText = "OK",
t(a)
}))
}
}
return ui.a.post(t.toString(), e)
}
},
在搜索过程中发现,所有接口都是通过postCheckCache这个函数发送的.想必这就是核心代码了.
这里的代码做过压缩,也没看到什么加密.我们直接断点吧.
chrome断点调试
断点如上.然而点击刷新后发现页面卡死了…
可想而知网页做了防止debug的检测,但是直接f12是正常的,那就找一下网站上的突破口.
访问了一下之后发现.网站的框架是瀑布流懒加载的.就是当你滚到最下面的时候会继续加载更多的内容.
通过这个方式我们可以不用刷新就进入接口的断点.
如图所示,证明地方没找错.这里就是每个接口加密的位置,现在是还没加密的状态所以数据还是看得懂的.我们继续下一步.
期间看到了isvue这种东西.大胆猜测这里是判断生成界面的地方.这时候数据应该已经返回了.我们打开fiddler也证明了我的想法.接口已经被访问了.
步入这里的时候,数据已经被加密了.这时候我们就可以开始看堆栈信息.
箭头位置是我们断点的位置,圆圈位置的时候,数据已经被加密了.
综上所述,加密语句就是!!
concat(it(JSON.stringify(e)))
这一句了
直接控制台跑一下
这时候已经找到核心加密语句,只要对它进行再追踪,离成功不远了.
控制台输入函数名(it) 进行追踪之后跳到函数的位置了.学过加密的同学一看就知道是个什么东西
加密在线解密
而且他这个代码没有做过多的混淆.直接告诉你是 AES加密了 密钥和偏移也在
我们直接到在线aes加密试试看
cbc偏移量16 数据位也是128 输出hex 字节集utf8 我赌他一手
如图所示一发入魂
实在不懂AES的话可以逐个试试.也就十几二十次就出来了…886