目录
- 前言
- 一、分析
- 二、验证
- 总结
- 借鉴
前言
极验第四代好像简单了特别多,没有什么技巧,环境党直接5分钟拿下。
网址: aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vYWRhcHRpdmUtY2FwdGNoYS1kZW1v
一、分析
直接去它官网,滑动滑块打开控制台瞅瞅
可以看到有个verify请求,看它返回的这个请求应该就是提交移动距离的地方了,接下来再看看提交了哪些数据,可以看到极验的老样子,还是w参数。(其他参数都可以再load那个请求里面得到,这里不再赘述,读者可以自己去看看)
打开启动器,去往上跟堆栈,跟到这一步就差不多了
这个就是我们想要的w参数
再往上看,这个r的调用方式就这么直接给出来了,现在追进去看看它这个方法
可以看到传入的这两个参数,第一个参数很明显就是移动距离和时间的信息,先不管它,看看第二个参数,这是一个对象,并且没有办法直接复制下来(我是懒得很的,我非要把它弄下来,双击第二个参数,可以发现这个r方法里,就使用了它其中的一个值)
这个值我们是可以复制下来的(那就很舒服了),到这里,参数的传入基本上都清楚了。
接下来不要急,补环境嘛,省时间,那我们就直接开始观察一下它这个js,可以发现,就是一整个js加载,然后里面瞎捣鼓,那不正好,直接全部拿下来,一把梭哈了它。
拿下来后,小小魔改一下代码,我们直接分析了,这里只需要t其中的一个值,那就把那个值当作参数传进去就好了。
然后把整个r给导出就完事了
接下来,当然不是直接本地运行,先丢到浏览器去,看看这个代码能不能正常跑。正常出值了,然后这个参数,拿去请求也是可以过的(这里不演示了,浪费时间)
那接下来,当然是直接扔到我们的nodejs去造了。
window=global;
document={};
better_proxy = function (o, callerName){
return new Proxy(o, {
set(target, property, value){
console.table([{"类型":"set-->","调用者":callerName,"属性":property,"值":value}]);
return Reflect.set(...arguments);
},
get(target, property, receiver){
console.table([{"类型":"get<--","调用者":callerName,"属性":property,"值":target[property]}]);
return Reflect.get(...arguments);
},
}
);
}
window = better_proxy(window, "window")
document = better_proxy(document, "document")
这里给大家一个简单的代理,创建一个对象就代理一次(方法笨了点,但是不用想太多,无脑补就对了),下面这些undefined,就是需要补的,这里带大家简单补两个。
下面就是我随便补的两个,每次添加一个对象,记得都要给它上一个代理噢。
window=global;
document={};
better_proxy = function (o, callerName){
return new Proxy(o, {
set(target, property, value){
console.table([{"类型":"set-->","调用者":callerName,"属性":property,"值":value}]);
return Reflect.set(...arguments);
},
get(target, property, receiver){
console.table([{"类型":"get<--","调用者":callerName,"属性":property,"值":target[property]}]);
return Reflect.get(...arguments);
},
}
);
}
window = better_proxy(window, "window")
document = better_proxy(document, "document")
window.location = {
"ancestorOrigins": {},
"href": "https://www.geetest.com/adaptive-captcha-demo",
"origin": "https://www.geetest.com",
"protocol": "https:",
"host": "www.geetest.com",
"hostname": "www.geetest.com",
"port": "",
"pathname": "/adaptive-captcha-demo",
"search": "",
"hash": ""
};
window.navigator= {
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36',
appName:'Netscape'
}
document.body = {}
document.head = {}
document.documentElement = {}
window.location = better_proxy(window.location, "window.location")
window.navigator = better_proxy(window.navigator, "window.navigator")
document.body = better_proxy(document.body, "document.body")
document.documentElement = better_proxy(document.documentElement, "document.documentElement")
其实上面补的都差不多了,就差最后一个(自己补吧),全部给出来,好像不太好。
结果如下:
不扯什么混淆,就强暴式补出来,但是吧,这第二个参数这么多,都要用来加密吗
作为一位懒人,我就直接给它上了个代理,可以看到这么多就使用了一个pt,那就给一个pt就完事了。
到这里,这个极验4就完事了。
二、验证
那整出来了,不得验证去玩一下,回到之前的load请求,可以看到很多参数都是verify请求需要的。里面还包含了验证码的背景图片和验证码缺口图片。
拿到postman去转成python,然后,我们就可以做下一步了,验证码缺口识别。
我使用了下面大佬的代码
如何用python识别滑块验证码中的缺口_python
import cv2
def identify_gap(bg,tp,out):
'''
bg: 背景图片
tp: 缺口图片
out:输出图片
'''
# 读取背景图片和缺口图片
bg_img = cv2.imread(bg) # 背景图片
tp_img = cv2.imread(tp) # 缺口图片
# 识别图片边缘
bg_edge = cv2.Canny(bg_img, 100, 200)
tp_edge = cv2.Canny(tp_img, 100, 200)
# 转换图片格式
bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
# 缺口匹配
res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配
# 绘制方框
th, tw = tp_pic.shape[:2]
tl = max_loc # 左上角点的坐标
br = (tl[0]+tw,tl[1]+th) # 右下角点的坐标
cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2) # 绘制矩形
cv2.imwrite(out, bg_img) # 保存在本地
# 返回缺口的X坐标
return tl[0]
把两张图片传进去就行了,最后一个参数是输入结果图片的位置。(两张图片在load请求返回回来的返回体上面)
最后得到他需要移动的距离。
再去调用js,把这个移动距离传进去就行了(传给第一个参数)
function init(data_x){
let mydata = '{"setLeft":'+data_x+',"passtime":1915,"userresponse":'+data_x+'.81178591310345,"device_id":"自己搞(网页上都有的)","lot_number":"自己搞(网页上都有的)","pow_msg":"自己搞(网页上都有的)","pow_sign":"自己搞(网页上都有的)","geetest":"captcha","lang":"zh","ep":"123","rigp":"199241198","yeg6":"d6w9","em":{"ph":0,"cp":0,"ek":"11","wd":1,"nt":0,"si":0,"sc":0}}'
mydata_obj={
"pt": "1",
}
mydata_obj = better_proxy(mydata_obj, "mydata_obj")
result = window.code(mydata, mydata_obj)
console.log(result)
}
module.exports = {
init
}
总结
没啥难度,越来越简单了,新手可以拿来当作入门课程
借鉴
如何用python识别滑块验证码中的缺口_python