好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 小亮丶1 于 2026-5-17 13:29 编辑
以下内容主要作为学习使用,如有侵权请联系删除。
网址:aHR0cHM6Ly9pZC4xNjMuY29tL21haWwvcmV0cmlldmVwYXNzd29yZD9wZD1tYWlsMTYzJnBraWQ9Q3ZWaUh6bCMvdmVyaWZ5QWNjb3VudA==
易盾一共需要发送的数据包一共有4个
分别为下图所标记出的请求,请求顺序为
1:Getconf
2:up
3:get
4:check
我们先从第一个包开始看
1:Getconf包
分析发现里面只有一个id值有用这个是站点固定的,不同站点为不同的id。开发时需要注意留出来自定义方便后续扩展多个站点。
其他的参数则都是固定值 其中callback的生成可使用以下js代码生成即可
function callback(){
return '__JSONP_'+Math.random().toString(36).slice(2, 9)+'_0'
}
其他则没有什么需要注意的地方了 在返回值中 我们需要取回2个参数供后续功能使用
data[‘"ir"]["pn"]
data["ir"]["token"]
2:up(主要的环境效验请求,最难的一部分)
先看他的请求参数
发现这里的P就是第一次请求时返回的data[‘"ir"]["pn"]具体也就是这样
data={
"p":ir_pn,#上面data内的pn
"v":"2.0.13_yanzhengma",
"vk":"d44593ca",
"n":n,
"d":d
}
那么现在知道了提交参数中有2个加密 n与d那么接下来我们去代码中找到n与d的实现
发现了n与d的生成位置 我们一个个分析 先看n 发现n很简单就一个随机生成字符串并没有什么环境之类的算法在里面,所以我们直接拿下这一段代码直接使用即可。
接下来就是重头戏d了,进入d我们看见是这样的很乱,但是别急我们一点点分析
这个v的执行就是return 了一个方法执行后的结果,那么我们看他的执行方法时传了什么参数
通过我们断点发现其中的n是代码加载时就已经初始化的一些值,并不是现在生成的那么我们就需要去看n是如何生成的。过程比较痛苦因为生成是通过异步的,避免看的迷糊就不把这段很绕的分析放出来了,这里就直接说分析结果。我们最终分析到的初始化位置是在这里上面执行的代码为初始化时就调用完成了不是单独调用的方法,也就是我们只需要初始化那么他会帮我们把所有的参数加密都搞定
传入的参数为
{
"productId": "YD00192283058223",
"apiServer": ["https://ir-sdk.dun.163.com", "https://ir-sdk.dun.163yun.com"],
"timeout": 6000
}
现在知道他是如何初始化环境以及调用了,那么我们就需要找到他的环境生成位置去分析,这样我们才能实现补出来的环境与他需要的环境一致,我们只需要随便找一处调用window取值的地方断点那么他异步执行的取环境方法就会调用过来,通过断点我们最终定位在了
找到他取环境的方法了那么接下来就是一个一个补出来让本地环境一致即可。当我们补完环境后,需要在js中进行一些修改来实现调用js生成我们需要的代码
我们已知这里是初始化会执行到的地方,我们让他初始化时就向我们的window对象写出结果,具体调用代码如下
function getVResult() {
// 初始化
test = {
"productId": "YD00192283058223",
"apiServer": ["https://ir-sdk.dun.163.com", "https://ir-sdk.dun.163yun.com"],
"timeout": 6000
};
aaa = window.createNECaptchaGuardian(test);
aaa.getToken(); // 触发流程
}
getVResult()
因为这里初始化是异步的 所以返回结果是没有用的 需要通过代理捕捉上面修改的window.v_result写入的值就是我们需要的加密结果当结果出来后,再进行请求则会返回如下内容
返回结果中我们需要的是 data[“tk”] 到此第二个包分析就结束了 接下来是第三个数据包
3:get(功能为获取图片,涉及部分环境加密,非常简单)
还是一样先看请求提交内容
上层传入的参数有(dt,irToken,id)需要加密的参数有(fp,cb)我们先解决简单的cb这个没有环境相关的东西只需要扣出来代码即可通过搜索 定位到生成位置 会发现有好几个一样的生成位置应该是分别对应不同的类型 如点选等等 所以我们需要在每一个搜到的地方都打上断点让他断下
断下后进入这个方法内,根据缺啥扣啥的方式将这个代码扣出来即可,没什么好讲的,能运行出结果了就是正确的了。
接下来是fp,稍微比cb要麻烦点 我们跟到最上层后发现最后值是给了window.gdxidpyhxde那么就直接用油猴插件进行定位了
(function() {
console.log('拦截启动')
Object.defineProperty(window, 'gdxidpyhxde', {
set: function(v) {
console.log('拦截到值:', v);
debugger;
},
configurable: true
});
})();
找到了就简单了 我们直接把这个方法扣下来即可,这个方法会有取环境的一些动作 具体是否效验环境没做太多研究,直接将第二个包的环境复制过来就行了。然后就是返回数据
返回数据中bg为背景图,front为滑块图,token是最后一步需要的需要的参数总结(bg,front,token)
4:check(提交结果,比较简单)先看提交信息
分析结果 需要传入的参数(dt,id,token)需要加密的参数(cb,data)cb就是第三步我们扣出来的方法执行出来的结果,这个就不再讲了主要讲data参数Data看着很长实际我们将他分开后会发现参数并不多
data={
'd': d,
'm': '',
'p': p,
'f': f,
'ext': ext
}
一共就4个参数 我们一个个分析 首先是d 通过跟栈发现d的参数是执行的_0x1b7568["sample"](this["traceData"], _0x27edd5)
但是在这方法内没看见traceData的赋值 所以我们向上找 发现在这里赋值
我们打上断点看看他是怎么操作的
看来是先生成了一个数组x,y,time,1一共4个参数
然后经过加密再push进traceData数组内也就是说我们需要扣出来_0x564a9f这个加密方法 参数1为第三步取回的结果token,参数2为上面数组的文本型,也就是7,0,71,1 那么第一步的加密我们就分析清楚了_0x4a4a62 = _0x1b7568["sample"](this["traceData"], _0x27edd5)现在traceData有了然后再扣出来_0x1b7568["sample"]这个方法就取到最终加密所需要的参数了 接下来回到_0xa8a0c6(_0x4a4a62['join'](':'))这个位置现在就需要抠出来_0xa8a0c6的加密即可 这里都没有环境效验 只需要扣出来能执行出结果即为正确加密。这里就是最终加密 到此d结束
接下来是p,p比较简单0xa8a0c6(_0x564a9f(_0x319bb4, parseInt(this['$jigsaw']["style"]['left'], 0xa) / this["width"] * 0x64 + ''))进去将parseInt(this['$jigsaw']["style"]['left'], 0xa)这个方法扣出来即可加密方式也和d一样 是2层 方法也一样,先用token加密一遍后面的计算出来的结果 再进行最终加密
接下来是f,f则是将d的轨迹 先用方法进行了处理 扣出方法即可没什么特别好讲的 他们加密都是一样的 2层
接下来是ext,_0xa8a0c6(_0x564a9f(_0x319bb4, this['mouseDownCounts'] + ',' + this['traceData']['length'])) _0x319bb4=token,this['mouseDownCounts']=鼠标按下次数这里是1+“,”+轨迹数量 然后通过上面一样的2层加密 。到此易盾最新版就结束了。
第四步需要注意的点拿到的底图是480宽度的,但是在代码内实际计算滑动距离却是420 所以我们需要对图片进行处理 要缩放到420,210 代码如下
res=requests.get(imgurl,headers=headers)
img=res.content
img_data = io.BytesIO(res.content)
img = Image.open(img_data)
img = img.resize((420, 210), Image.LANCZOS)
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=90)
image_data=base64.b64encode(buffer.getvalue()).decode('utf-8')
meta = 'True'
secret_key = ''
type_id = '2000'
# 准备请求数据
data = {
'secret_key': secret_key,
'type_id': type_id,
'image': image_data,
'meta':meta
}
# 发送请求
response = requests.post(
'http://api.yydsocr.com/verify_api',
json=data,
headers={'Content-Type': 'application/json'}
)
# 处理响应
if response.status_code == 200:
result = response.json()
print('识别结果:', result)
print('data内容:', result['data']['data'])
return True,result['data']['data']
else:
print('请求失败:', response.text)
return False,None
运行结果展示:
我这里使用的是识别平台进行识别,因为后台有结果预览方便判断坐标是否正确,我这里用的是元识AI平台进行识别,目前正在做活动,每个人免费可得50元额度,反正能白嫖就懒得写识别代码了。
下面是我的轨迹算法
def generate_trajectory_fixed(target_x):
num_points = max(45, int(target_x / 1.5) + 20)
trajectory = []
current_x = current_y = 0
current_time = 67
current_time += random.randint(20, 50)
overshoot = target_x * random.uniform(0.08, 0.18)
max_x = target_x + overshoot
for i in range(num_points):
progress = i / (num_points - 1)
if progress < 0.7:
speed_factor = 1.0 - (progress * 0.3)
time_inc = random.uniform(7, 9)
else:
speed_factor = 0.3 + ((progress - 0.7) * 0.5)
time_inc = random.uniform(12, 20)
if random.random() < 0.05:
time_inc += random.uniform(15, 40)
if progress < 0.75:
target_x_now = max_x * (progress / 0.75)
else:
retreat_progress = (progress - 0.75) / 0.25
target_x_now = max_x - (overshoot * retreat_progress)
x_offset = random.uniform(-2, 2) * (1 - abs(progress - 0.5))
current_x = target_x_now + x_offset
y_base = math.sin(progress * 10) * 2
y_noise = random.uniform(-1.5, 1.5) * (0.5 + 0.5 * progress)
current_y = y_base + y_noise
current_time += time_inc
trajectory.append([
int(round(current_x)),
int(round(current_y)),
int(round(current_time)),
1
])
trajectory[-1][0] = target_x
trajectory[-1][1] = int(round(current_y))
return trajectory
只需要将识别结果+20像素,然后通过我的轨迹生成代码生成轨迹即可。至于为什么要+20像素,因为每个平台识别出来位置都不同。所以不是用同一个识别平台就不要乱加了。 |
免费评分
-
查看全部评分
|