声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【K哥爬虫】联系作者立即删除!
前言
最近很多粉丝反馈,某验三代的滑块一直返回 forbidden,不知道为什么通过不了,尝试了很多方法都不行。其实是因为之前只校验了第三个 w 参数的值,现在官网加强了校验,前面两个 w 参数也需要逆出来,三个 w 参数相互关联,有一个不对,就无法通过验证。目前只发现官网做了更新,今后其他网站可能也会再上点强度。本文将会对每个 w 参数逐一逆向分析。
逆向目标
- 目标:最新某验 3 代滑块分析
- 网址:
aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby8=
抓包分析
刷新页面,通过抓包发现, register-slide 接口会返回 challenge 和 gt 值,为接口 get.php 的主要请求参数:
get.php 接口会返回 c 和 s,后面会用到,新版界面此接口里的 w 不可以置空,旧版则可以置空:
点击按键验证,会弹出滑块窗口,同时抓到了一个 ajax.php 接口,这个接口会返回验证码的类型,虽然没用,但是如果不请求或者请求不带 w 后面都会报错。旧版的话这个接口也是必须请求,但是 w 也是可以置空,且后面不会报错:
紧着着,我们要又抓到一个 get.php 接口,这个接口仍然给我们返回 c 和 s,请求不一样的是,这个接口里面还给我们返回滑块图片以及底图:
紧接着,我们滑动完成拼图,得到验证结果 validate 参数,这个参数就是后续登录的令牌,在后续操作的请求中会用到:
逆向分析
第一个 w
从 get.php 接口处跟栈,或者直接搜 “\u0077” 即可成功定位,w=i+r:
关键代码如下:
var r = t[$_CEFDY(1196)]()
o = $_BEH()[$_CEFCV(1127)](fe[$_CEFDY(431)](t[$_CEFCV(370)]), t[$_CEFDY(1143)]()) i = R[$_CEFDY(1197)](o)
很明显,这几个参数对于我们都不陌生了,我们进入 l 参数,发现 this[$_CGHDO(1143)](e)
为 16 位随机字符串将 new G()[$_CGHDO(93)]
这个函数扣一下即可,这里很明显,构造了一个 G 函数,所以我们只需要把 G 函数扣一下即可:
或者我们进入 G 的原型链 set_public 中,下断点,将他的 RSA 公钥和模值找到即可。所以 r 为 RSA 加密 16 位随机字符串。至此 r 值已经分析完毕。
接下来是 o 值,加密方法为 $_BEH()[$_CEFCV(1127)]
,传入参数为 t[$_CEFDY(1143)]()
和 fe[$_CEFDY(431)](t[$_CEFCV(370)])
。我们发现 t[$_CEFDY(1143)]()
为 rsa 加密的 key,t[$_CEFDY(1143)]()
和 fe[$_CEFDY(431)](t[$_CEFCV(370)])
为明文参数。进入加密方法,打断点调试,我们发现是 AES 加密,同时初始向量是 0000000000000000:
直接扣代码,或者引库复现即可:
function Aes_encrypt(text, key_value) {
var key = CryptoJS.enc.Utf8.parse(key_value);
var iv = CryptoJS.enc.Utf8.parse("0000000000000000");
var srcs = CryptoJS.enc.Utf8.parse(text);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
for (var r = encrypted, o = r.ciphertext.words, i = r.ciphertext.sigBytes, s = [], a = 0; a < i; a++) {
var c = o[a >>> 2] >>> 24 - a % 4 * 8 & 255;
s.push(c);
}
return s;
}
现在,我们来分析一下明文的关键参数,这里我们采用 K 哥工具站,来解析一下,关键参数如下:
-
gt,challenge:第一个接口 /register-slider 返回;
-
offline, static_servers : static_servers 其他参数固定即可。
至此我们 o 就分析完毕,终于只剩下一个 i 值,接下来我们分析一下 i 值,我们进入 R[$_CEFDY(1197)]
函 数,发现 i 值为 t 中的俩个 value 值相加,t 的定义在断点上方:
传入的参数 e 为我们上一个步骤 aes 加密后的值,跟进到 this[$_IJDN(480)]
中,我们发现他属于 m 模块下的函数:
将整个 m 扣下来,复现如下:
小结:第一个 w 和以前扣法基本一致,只是明文上有参差之分。
第二个 w
目前,我们第一个接口已经完成,拿到了返回的 s 和 c,接下来我们进入 ajax.php 接口,还是跟栈进入。
我们依然搜索定位参数"\u0077" ,发现并没有搜到,所以这个 w 和我们以前的扣法有点不一样!!!不过通过,跟栈的方式,我们找到正确位置。位置的话在 var n = {}; 这个地方,我们下断点:
w 值就是 t[$_CFEHG(1160)]
,前面我们发现 var t=this,然后经过 t[$_CFEHG(1191)]()
,我们的 w 值就生成了。我们进入这个函数之中,进入以后发现异常的熟悉,这不就是无感系列的 w 吗?
当然如果你是第一次扣,也不要心急,我们找到 w 定位的地方:
i[$_CFHIs(1160)] = R[$_CFHIs(1197)](c[$_CFHIs(93)](r, i[$_CFHIs(1143)]()))
我们简单修改一下代码,大概如下 w=R["encrypt"](r,key)
,没错这个 R 方法其实与第一个 w 中 i 生成方式一样。所以现在,我们只需要解决 r 参数就可以完成第二个 w 的逆向。我们看一下 r 参数包括那些,我们依旧使用 K 哥工具站进行解析:
nr = {
"lang": "zh-cn",
"type": "fullpage",
"tt": "M3*8Pjp8Pj9HbUp8PN9U),,:A(,(5(,(m-BJBFB:bgfA9/1O6*:I:JkNjRj31RkK**2KDRjE1S0OMM9*)-2.k6h)).E-:-)-9-:(:5b9-:1Mal2UK1RjY1I****)*:F3)pM0/JBBBA(((((,((iB9(((((,(5bn)BBBo95(,(qcjc*)R)