本文只是简单地分析了安居客滑块验证码,没有涉及爬虫部分哦。
完整 URL:
aHR0cHM6Ly93d3cuYW5qdWtlLmNvbS9jYXB0Y2hhLXZlcmlmeS8/aGlzdG9yeT1hSFIwY0hNNkx5OXphR0Z1WjJoaGFTNWhibXAxYTJVdVkyOXRMMk52YlcxMWJtbDBlUzkyYVdWM0x6RXlOekV6TWc9PSZuYW1lc3BhY2U9YW5qdWtlX3hpYW9xdV9wYyZzZXJpYWxJRD0yZDZjYTQ3YTE3ODhkMjdjNTcwMmM4YTQzMTczNjYyNl8wZjk4ZGM1YmI4NTA0YWIwODlhYmNlZjlmYTBlNzI5YiZjYWxsYmFjaz1zaGllbGQmZnJvbT1hbnRpc3BhbQ==
简化 URL:aHR0cHM6Ly93d3cuYW5qdWtlLmNvbS9jYXB0Y2hhLXZlcmlmeS8/Y2FsbGJhY2s9c2hpZWxkJmZyb209YW50aXNwYW0=
请求参数
sessionId: 4cc3cd35a39c4eb4b03680e0812f6b98 在访问验证码页面的HTML代码里包含sessionId
showType: embed 固定
track: 固定
clientType: 1 固定
clientId: 1 固定
language: zh-CN 固定
dInfo: 0zKKrvsczg7QXGpGHiLxEepUoismp8P1rvEnnE8n95JH8Sril...省略 貌似不校验
请求响应
{
"code":0,
"data":{
"ntpStatus":1,
"ntp":"0",
"status":0,
"responseId":"cea3453145194aaa88ce0f6b3171dad8",
"info":"I1vWKDGkPlxzM/1krtxMm8mDmkMZ1cfhpygfkAyS2lb1l3kC7gOr5NSjtPoUQAVDyu65emjI7u0D...省略"
},
"message":"成功"
}
sessionId
在访问验证码页面的 HTML 代码里包含,直接使用正则提取即可
dInfo
直接使用 DevTools
工具中的 search
搜索 dInfo:
,直接就会定位到下图位置
直接下断重新刷新页面,会断在下图位置,直接在 控制台
打印 l[_0x1vk[7]][_0x1vk[164]]((0,i)(), r[_0x1vk[104]])
输出看下内容
发现好像就是 dInfo
参数,
发现关键字 AESEncrypt
,那么就破案了,但是也要继续跟进验证下,主要看下 AES 加密的 内容
、key
、mode
、padding
等信息,方便我们自己加密测试是否与网站的结果是一样的
发现 sessionId
,很眼熟,就是上面最开始在验证码页面获取的,可以把这行代码整理下,整理如下
l[_0x1vk[7]][_0x1vk[164]]((0,i)(), r[_0x1vk[104]])
l[_0x1vk[7]][_0x1vk[164]](i(), r[_0x1vk[104]])
这样就稍微清楚些, l[_0x1vk[7]][_0x1vk[164]]
这个函数主要有两个参数,第一个是 i()
,第二个是 r[_0x1vk[104]](也就是sessionId)
,那么先看下 i()
是什么,老样子,在控制台打印输出下即可
接着进入加密函数看下
e = e[_0x1vk[388]](_0x1vk[23])[_0x1vk[745]](function(t, e, n) {
return n % 2 == 0 ? t + _0x1vk[23] : t + e;
}, _0x1vk[23])
e
是对传入的 sessionId
做了一些处理,比如 9d811d9936354dcf90c2410390f7a5e1
处理后变成了 d1d965df02130751
e = r[_0x1vk[683]](e)
e
把 e
进行了处理又重新赋值给了 e
,那么 e 就是 AES 的 key
t = _0x1vk[70] == typeof t ? t : JSON[_0x1vk[720]](t)
t
把 第一个参数转换成字符串
t = s[_0x1vk[746]](t, e, {
iv: e,
mode: u[_0x1vk[747]][_0x1vk[748]],
padding: f
}),
AES 对象,声明了 iv
为 key
,两者一样,mode
为 CBC
,padding
为 Pkcs7
e = o[_0x1vk[720]](t[_0x1vk[749]])
对第一个参数进行加密
encodeURIComponent)(e)
对加密后的内容再次进行 URL 编码,到此 dInfo
参数处理完成,然后自己使用库进行 AES 加密即可,使用 Python 实现并请求接口返回数据如下
发现返回后的数据是加密的,使用 AES 解密即可
请求参数
sessionId: 98533e7b1323471c82f42bda694af2aa 同上
responseId: b0f1474ffe8a41a8bbe225f9daa22e23 接口1返回的
dInfo: 9bGgD6bvcFdJCXEikdLVj48M39SK6%2FI%2FsZwk1iqjrY5Ky%2BtqN7Pk%2BsHpRLRQxuNk...省略
language: zh-CN 固定
data: IsRd8Fl22naf8FS6...省略
请求响应
{
"code":0,
"data":{
"ischange":false,
"status":1
},
"message":"校验失败"
}
dInfo
与上面接口 1 的处理方式一样
这里主要看下 t
,打断点依次调用栈往上找, 找到了下图位置
熟悉的配方 AES,看下都加密了什么内容
c[_0xw19[162]](r[_0xw19[7]][_0xw19[164]](e, c[_0xw19[25]][_0xw19[104]]));
e
为轨迹相关的数据,c[_0xw19[25]][_0xw19[104]])
是 sessionId
,下面是 e
的内容,包含了一个 x坐标
、track轨迹
、p坐标
'{"x":77,"track":"16,22,1|17,22,17|18,22,22|19,22,29|20,22,34|21,22,37|22,22,42|23,22,46|24,22,51|25,22,53|26,22,58|27,22,62|27,23,64|28,23,66|29,23,68|30,23,72|31,23,76|32,23,80|33,23,85|34,23,88|35,23,91|36,23,98|37,23,103|38,23,107|39,23,109|40,23,110|41,23,112|42,23,113|43,23,116|44,24,119|45,24,124|46,24,124|47,24,128|48,24,133|49,24,134|50,24,135|51,24,138|52,24,141|53,24,144|54,24,147|55,24,149|56,24,153|57,24,158|58,24,159|59,24,164|60,24,167|61,24,172|62,24,175|63,24,179|64,24,183|65,24,187|66,24,189|67,24,194|68,24,198|69,24,202|70,24,209|71,24,211|72,24,220|73,24,225|74,24,231|75,24,231|76,24,236|77,24,245|78,24,254|79,24,256|80,24,263|81,24,271|82,24,277|83,24,280|84,24,287|85,24,293|86,24,298|87,24,301|88,24,307|89,24,313|90,24,319|91,24,323|92,24,333|93,24,353|93,24,448|","p":[0,0]}'
代码 GitHub 地址:关注【趣码周】公众号获取