作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!
url:'aHR0cHM6Ly9tLmZsaWdodC5xdW5hci5jb20v'
一、加密位置定位
数据包touchinnerlist的请求头里的pre在每次发包时都会变化。
直接全局搜索pre,很容易找到赋值位置,不但找到了pre赋值位置,而且找到了请求头里那个变化的键值的赋值位置。
Object.assign这个在js里里,接收的参数为键值的字典格式,并把其合在一起组成一个大字典,u.default.getToken()控制台输出就是请求头里那个变化的键值,同样也是用到了u,u在上一章我们扣请求体__m__时已经扣出来的,所以这个直接在扣__m__这个js里一起导出就好。
言归正传,pre指向的window.pt这个属性,这里要注意是取其前46个字符。既然在window属性里,那我们就hookwindow属性吧。
(function() {
'use strict';
var pre = "";
Object.defineProperty(window, "_pt_", {
get: function() {
console.log('Getting window.属性');
return pre
},
set: function(val) {
console.log('Setting window.属性', val);
debugger ;
pre = val;
}
})
})();
很轻松的就断到了window._pt_的加密位置。_0x47f515[_0x95ea('0x71')]这个函数点进去就是把传入的两个参数相加,上一步我们分析的是取其前46个字符,_0xabe1f3刚好是46个字符,因此pre=_0xabe1f3。
这个js里搜索_0xabe1f3,很容易的找到了其最后赋值的地方。
至此,加密位置分析完毕。
二、扣js
在加密位置下断点,刷新网页发现断不住,说明这个包是动态js,在来源面板中查看这个包的类型是document,说明是请求返回的包。
看其名字,还有印象吧,正是我们分析__m__逆向时要获得两个cookie所发送请求返回的包,其请求体和请求头都没有加密点,那么拿到这个js包没有问题了。把其放到浏览器里执行,可以拿到window._pt_的值。而且要在当前这个网页的环境下才行,说明进行了环境检测。
但是要放到python里就不行了,补补环境你就会发现,越补越多,这是我们最头疼的事,有没有更好更简单的方法呢。
想一想,虽然这个包是动态的,但是其代码的顺序和逻辑绝大多数是不会变的,前文分析生成pt的值没几行代码,我们是不是可以扣出这几行代码稍微补一补。如果能拿到数据,然后我们用正则匹配拿我们所扣的代码是不是也可以呢。
按照这个思路开始我们开始扣代码。这里可以下script断点,走到这个包时在我们要扣的那几行代码处下断。找我们要扣的那几行代码可以搜特征值= []。然后取消script断点,按f8就走到了我们断住的位置。复制下来,开始调试,这里调试一定要小心点,一步走过,前面所扣的代码就要重新扣了。。
首先这种_0x4a00c8的大函数对象给扣下来,就在上方,两者之间还有一些变量定义,索性一起扣下来,
然后就是_0x30bf这个大数组,ob混淆这种,肯定会对大数组进行偏移的,所以要把大数组,自执行偏移函数,都扣下来,但是扣下这个自执行函数时调试会发现出现卡死错误。应该是有些格式检测或者环境检测什么的,这个时候就要改写了,想一想我们扣这个自执行函数是对数组进行偏移的,所以与偏移不相关的都删掉。然后就过了这个错误。
来到 _0x5b538c这个函数没定义,找到位置也扣下来,就在混淆代码的最后
然后来到了这个错误,说是调用堆栈次数过多,其实这个错误在python调用时是没有影响的,我们现在调试先修改下,这个if判断在浏览器里执行是false,直接改写。
至此代码扣完,出现结果。释放断点和浏览器数据包请求头里的pre比对,完全正确。说明我们的改写和所扣的代码都没有问题。
因为这个js是请求返回的动态js,所以还要知道我们都扣了啥,以及所在位置,好用正则匹配动态提取。回想一下我们都扣了啥:开头的大数组,偏移函数(进行了修改),解密函数,包含很多函数的对象以及与主体代码之间的变量定义。还有混淆代码最后那个函数。明白了这些,剩下的就是找特征值,编写正则匹配了。
整体来说pre的逆向还是比较简单的,就是在编写正则匹配时麻烦点,据说可以用ast提取,但是本人水平有限,对ast一知半解,还不会编写针对这个的ast。