说实话,这种反爬真的是第一次见,而且反爬逻辑还算比较清晰,参数没有被过分的加密处理很容易推算出来,好了,既然都做到第十八题了,其他的废话也不多说,直接进入调试阶段。
找到请求发送的位置
第一页没有加密,跳过,直接看第二页的数据,抓到请求后,点击initiator查看请求发起位置,点进去第一个
代码如图
大眼一看,这里没有任何添加参数什么乱起八糟的逻辑,既然被标记位困难那肯定有他的道理在的,从xmlHttpRequest生成开始,一步一步 step into进去,发现xml.open时会进入一段特殊的代码,如图
这段代码有多特殊呢?几乎所有你想要调试的代码,都会指向这里,什么encrypt、secret_key= func(a,b,c),都会进入到这里来,一步一步的走有灰常繁琐,并且当看到希望时,又是给你指向到这里,而且被加密的参数在你进入这个函数前就已经生成(后面发现是鼠标的移动与点击事件生成的数据),但是还是得调试。。
确认参数生成位置
这段还是比较容易找到的,发现在首次执行这段代码时,加密参数v的生成就已经完成了
而且细心的话会发现那个特殊的函数传进来的第一个参数"_"的组成有些眼熟,_[1][0]
是一个CryptoJS对象,虽然找不到在哪里生成的,但是大概可以确定这是一个AES加密了,并且填充方式为pkcs7。
加密过程hook
虽然猜出大概是AES加密,但是却怎么也找不到encrypt函数位置,即使找到了,还是会进入_U__
这个函数,虽然进入这个函数内,但这明显不是真正的位置,此时我们尝试hook这个函数,在点击翻页首次到达这里时下断点,然后在console运行如下代码
var old = _[1][0]['CryptoJS']['AES'].encrypt;
_[1][0]['CryptoJS']['AES'].encrypt = function(a, b, c, d, e) {
debugger;
var bb = old(a, b, c,d,e);
console.log(bb.toString())
debugger;
return bb;
};
取消断点,点击进入下一个断点,果然如设想,进入到了我们写的hook函数内部,如下
再次点击进入下一个断点,查看发送的请求,返现v的值与bb.toString()
的值完全一致,所以这里就是加密点了,好了,我们可以愉快地查看key,iv ,text和填充方式了,通过console查看加密的关键参数
_[1][0]['CryptoJS'].enc.Utf8.stringify(a) // text
3|247m329,246m329,246d329,246u329,211u12
_[1][0]['CryptoJS'].enc.Utf8.stringify(b) // key
"6058747d6058747d"
_[1][0]['CryptoJS'].enc.Utf8.stringify(c.iv) // iv
"6058747d6058747d"
text起始就是页码加鼠标事件产生的一些数据,除了page之外|之后的可以写死。
那么key和iv是怎么来的呢?这个就涉及到经验了,我是尝试了一会发现找不到,休息的时候看了几个key
的样例发现就key
是一个八位字符串乘以two,而且请求中查询字符串除了v
就只有时间戳了,所以key的生成必然与时间戳有关,将前八位转成十进制发现就是t
参数的十六进制,到此就over了