本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关.本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责
感谢各位大佬的支持与观看
目标网址:aHR0cHM6Ly93d3cueW5qempnY3guY29tL2RhdGFQdWIvZW50ZXJwcmlzZQ==
前情提要
-------------------------------------------------------------------------------------------------------------------
这一篇我们直接开始讲解主题 :
过完验证码获取到数据这个栈每次翻页都需要过验证码 因此 数据也就在 请求验证码的数据包里 如下图
图片 1.png (310.23 KB, 下载次数: 0)
下载附件
2025-4-15 14:42 上传
所以 对于这个栈我们就需要 只对验证码进行分析 从而请求到我们需要的数据
-----------------------------------------------------------------------------------------------------------------------
第一步
1.1 我们先来分析出 浏览器是通过什么流程 获取到 验证码的 (其中包括 数据包 某个参数 还有图片),
我们可以刷新验证图片 或者 将整个网页都进行刷新,那么我们也只有这一个包
图片 2.png (316.8 KB, 下载次数: 0)
下载附件
2025-4-15 14:44 上传
1.2 这个包里面的数据我们可以看到 是 一些密文 我们在控制台打印来一个个分析
1.2.1 bigImage: 解密下载之后是 验证码的背景图
smallImage: 解密下载之后是 验证码的缺口图片
slideId: 后面参数加密需要
yHeight:目前对我来说 是不知名参数(哪位大佬研究出来是什么 希望评论或私信给我,感谢分享)
图片 3.png (22.33 KB, 下载次数: 0)
下载附件
2025-4-15 14:46 上传
1.3 分析的到位,接着我们就来搞掉这个载荷的密文
进入genVcode数据包 在这里我们可以刷新验证码来断点,不用刷新浏览器
图片 4.png (71.77 KB, 下载次数: 0)
下载附件
2025-4-15 14:47 上传
图片 5.png (283.19 KB, 下载次数: 0)
下载附件
2025-4-15 14:47 上传
1.4 在 send方法里面就是我们要的载荷的密文,经过多次的调试 加密的密文显然不在这里,
这一点可以验证我们在 这个函数的开头下断 如果没有密文,那他就是在这里面,
如果是传入的那我们就需要向上跟栈,去找,如下图
图片 6.png (37.61 KB, 下载次数: 0)
下载附件
2025-4-15 14:48 上传
1.5 我们刷新验证码让断点生效,我们看到了,密文是从上一个栈 传入其中
,所以我们就向上跟栈
图片 7.png (249.84 KB, 下载次数: 0)
下载附件
2025-4-15 14:49 上传
第二步 我们根据箭头向上跟栈,到第四个箭头处,在这里有个拦截器,
我们可以依次进入,在return处下断,在重新发包,让断点生效,
也就是进入到 i 里面
图片 8.png (79.69 KB, 下载次数: 0)
下载附件
2025-4-15 14:50 上传
图片 9.png (30.45 KB, 下载次数: 0)
下载附件
2025-4-15 14:50 上传
2.1 接着我们来展示 i 里面每个函数的下断处,我们让断点生效时
需要将其他断点取消 ,只留这几个 ,拦截器的断点也要取消
图片 10.png (33.08 KB, 下载次数: 0)
下载附件
2025-4-15 14:52 上传
图片 11.png (9.31 KB, 下载次数: 0)
下载附件
2025-4-15 14:52 上传
图片 12.png (21.61 KB, 下载次数: 0)
下载附件
2025-4-15 14:52 上传
图片 13.png (17.84 KB, 下载次数: 0)
下载附件
2025-4-15 14:52 上传
图片 14.png (15.61 KB, 下载次数: 0)
下载附件
2025-4-15 14:52 上传
2.2 最后在Pt.interceptors.request.use 函数体内 停下 我们也看到返回的内容里面有我们需要的密文
所以为了 检验是否在这里面 生成我们在头部也下断 ,另外其他断点就可以取消掉了,以免扰乱思路
图片 15.png (34.02 KB, 下载次数: 0)
下载附件
2025-4-15 14:53 上传
2.3 我们来发包看 密文还在不在 不在就是这个函数里面的 在那就还需要向上跟栈 我们发现出现了明文,
所以我们知道了 密文应该是这个函数里面 生成的,所以,我们就在这个函数,进行调试,来寻找看有没有我们想要的
图片 16.png (26.07 KB, 下载次数: 0)
下载附件
2025-4-15 14:54 上传
图片 17.png (44.59 KB, 下载次数: 0)
下载附件
2025-4-15 14:55 上传
2.4 我们点击图片中按钮来进行代码的调试,因为单步调试会进入其他不相干,
比如只会返回 true或 false所以 我们就直接跳过来查看 看密文 在哪出现
图片 18.png (86.41 KB, 下载次数: 0)
下载附件
2025-4-15 14:56 上传
2.5 我们调试到这里,发现出现了 密文 而这里有个params组成 所以我们就推测
密文是在这里,那么我们就可以开进行 扣取然后将数据加密来测试
图片 19.png (29.24 KB, 下载次数: 0)
下载附件
2025-4-15 14:56 上传
第三步 我们来扣取代码 进行参数加密然后请求
3.1 我们将代码扣取下来,进行分析a$e().encrypt 是我们第一次加密的函数
因为我们浏览器就能一眼看出 他先试用这个进行一次加密
u$e(s) 是我们最终的加密 s 里面的值就是
a$e().encrypt 加密得出
图片 20.png (16.3 KB, 下载次数: 0)
下载附件
2025-4-15 14:58 上传
3.2 对于参数的加密 上述的明文 是我们这个包的 里面有我们要的 验证码图片信息,
大家可以自行查看,所以3.1 所述 的代码整改就是我们的 这个包的参数加密,
那我们运行代码进行一个代码补全 实现最终的加密
图片 21.png (20.6 KB, 下载次数: 0)
下载附件
2025-4-15 14:59 上传
3.3 我们直接选中函数 进入他的位置将他扣取,随后我们就看报错
,少哪一个 我们就直接进入找到位置,进行扣取
图片 22.png (31.31 KB, 下载次数: 0)
下载附件
2025-4-15 15:00 上传
图片 23.png (18.86 KB, 下载次数: 0)
下载附件
2025-4-15 15:00 上传
3.4 我们按照每一个报错补完之后发现 又出现一个报错 就是
我们主函数里面的 o 不能进行实例化,但明明我们扣取完毕,
还是不给我们想要的,且报错,那我们就需要思考究竟是哪些原因,
在这就不卖关子了我们直接演示
图片 24.png (50.16 KB, 下载次数: 0)
下载附件
2025-4-15 15:01 上传
3.5 原因很简单就是少扣取 但是他不给你明确指示
所以在这里展示一种另类且无脑的扣取方法下图 将包含两个箭头处
和他们中间的代码全部扣取下来 这里是做了多次调试
发现报错不给,就多次调试出来的结果
图片 25.png (196.96 KB, 下载次数: 0)
下载附件
2025-4-15 15:02 上传
图片 26.png (120.64 KB, 下载次数: 0)
下载附件
2025-4-15 15:02 上传
第四步 我们运行代码发现报错 在这里的st 是一个判断
他的意思是 用global 还是 globalThis 赋值给st,也就是下图的
var st = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : {};
图片 27.png (67.49 KB, 下载次数: 0)
下载附件
2025-4-15 15:04 上传
图片 28.png (18.24 KB, 下载次数: 0)
下载附件
2025-4-15 15:04 上传
4.1 我们将代码装载运行 在这里需要补上一个 window=global 或者 window = globalThis 两者都可
图片 29.png (18.45 KB, 下载次数: 0)
下载附件
2025-4-15 15:05 上传
4.2 接着运行调试 ,看报错,是我们的最终加密,所以我们接着看报错少那个扣取那个,对于 l$e 这个报错我们需要扣取三个
图片 30.png (59.12 KB, 下载次数: 0)
下载附件
2025-4-15 15:06 上传
图片 31.png (43.84 KB, 下载次数: 0)
下载附件
2025-4-15 15:06 上传
图片 32.png (8.96 KB, 下载次数: 0)
下载附件
2025-4-15 15:06 上传
4.3 当我扣取之后 在紧接着的报错是 某某变量不是方法,就让我们很苦恼,
也就代表着我们的代码没有扣到位,那么我们,可以看到 ,他是new l$e 出现了问题,
在这里我们不去深究它里面是什么,因为我们知道在 3.5 就遇到过这种情况 报错不给,
没有明确指示是哪个问题,所以在经过多次调试,我们就知道我们要按照3.5的扣取方法
图片 33.png (84.71 KB, 下载次数: 0)
下载附件
2025-4-15 15:08 上传
图片 34.png (11.14 KB, 下载次数: 0)
下载附件
2025-4-15 15:08 上传
4.4 也是包括 箭头两处全部扣取,因为几步报错,也不指明,那我们就只能,在他周围尝试着扣取,
因为他们就是在某处定义然后使用,所以我们就将计就计 都拿来吧,就算扣取到没有的,
那我们也不用担心,多次调试优化 就可以得出简洁的代码,所以我们就直接扣取使用
图片 35.png (54.94 KB, 下载次数: 0)
下载附件
2025-4-15 15:09 上传
图片 36.png (64.94 KB, 下载次数: 0)
下载附件
2025-4-15 15:09 上传
4.5 我们运行代码,发现可以了,没有报错也没有输出,也就达到了一半 没有报错,
但是我们得要结果,没结果的事,怎么可能去做,那么下面也就要讲解一个难以发觉的错误,
也就是大量扣取,不容易被发现的浏览器的小动作
图片 37.png (76.23 KB, 下载次数: 0)
下载附件
2025-4-15 15:10 上传
第五步 代码总体没问题,存在于多扣但没有少扣取,所以就是因为我们的代码里有我们不需要的,
才导致打印为空我们可以在本地下断点就可以看到值,所以说在某处 console.log()被改写或者拦截 等等
图片 38.png (82.29 KB, 下载次数: 0)
下载附件
2025-4-15 15:11 上传
5.1 经过多次调试我们发现 代码有两处 写法一样并且运行了,这里的代码是经过多次调试,
得出的结论,发现是这里导致了代码打印为空的操作所以我们将 s$e(); i$e(); 这两处删除或者注释掉,
那么打印自然就出现
图片 39.png (42.45 KB, 下载次数: 0)
下载附件
2025-4-15 15:12 上传
图片 40.png (43.85 KB, 下载次数: 0)
下载附件
2025-4-15 15:12 上传
图片 41.png (94.08 KB, 下载次数: 0)
下载附件
2025-4-15 15:12 上传
5.2 以上就是获取验证码信息的步骤 ,接着我们讲解 怎样过验证码,如下图,这两个验证码,可以任选进行操作
------------------------------------------------------------------------------------------------------------------------------------------
[Python] 纯文本查看 复制代码# 代码1
def huakuiajuli(a,b):
"""
a ----> 背景图片 二进制的
b ----> 滑块图片 二进制的
:return: x坐标
"""
# 读取背景图片 和 滑块图片
a_img = cv2.imdecode(np.frombuffer(a,np.uint8),cv2.IMREAD_GRAYSCALE)
b_img = cv2.imdecode(np.frombuffer(b,np.uint8),cv2.IMREAD_GRAYSCALE) # 滑块
yy = []
xx = []
for y in range(b_img.shape[0]):
for x in range(b_img.shape[1]):
r = b_img[y,x]
if r<200:
yy.append(y)
xx.append(x)
b_img = b_img[min(yy):max(yy),min(xx):max(xx)]
# 识别图片边缘
a_edge = cv2.Canny(a_img,100,200)
b_edge = cv2.Canny(b_img,100,200)
#转换图片格式
a_pic = cv2.cvtColor(a_edge,cv2.COLOR_GRAY2RGB)
b_pic = cv2.cvtColor(b_edge,cv2.COLOR_GRAY2RGB)
#缺口匹配
res = cv2.matchTemplate(a_pic,b_pic,cv2.TM_CCOEFF_NORMED)
min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res) #寻找最优匹配
# 绘制方框
th,tw = b_pic.shape[:2]
tl = max_loc# 左上角点的坐标
br = (tl[0] +tw,tl[1]+th) # 右下角点的坐标
cv2.rectangle(a_img,tl,br,(0,0,255),2) #绘制矩形
cv2.imwrite("ditu01.png",a_img) #保存本地
return max_loc[0]
------------------------------------------------------------------------------------------------------------------------------------------
[Python] 纯文本查看 复制代码# 代码2 形参a,b代表二进制 的 背景图片和 缺口图片
def dddddor_post(a,b):
slide = ddddocr.DdddOcr(det = False,ocr = False,show_ad = False)
bigImage = a
smallImage = b
result = slide.slide_match(bigImage,smallImage,simple_target=True)
return result['target'][0]
---------------------------------------------------------------------------------------------------------------------------------------------
5.3 接着我们过完验证码之后 就需要请求目标数据包了 加密位置都一样只不过不同之处在于参数 所以我们来分析他加密的参数,
滑动验证码就可以看到,我们来分析参数
certificateType:””
key:"query"
name :””
pagelum:1
pageSize: 10
slideld:"1361093404070510592"
width: 143
其中 slideld 在请求的图片的包里 width猜测是滑块轨迹 但经过多次调试 除slideld外 其余都可以固定
图片 42.png (254.68 KB, 下载次数: 0)
下载附件
2025-4-15 15:15 上传
第六步 完成两次请求需要的参数了,接下来就是放出请求的结果有两种第一种 参数没有按照5.3 操作 有响应但是 没有数据
图片 43.png (213.33 KB, 下载次数: 0)
下载附件
2025-4-15 15:16 上传
第二种 显示验证码错误,这是因为 上面提供的两个验证码正确率不是太高 但代码一要不代码二 出现不正确次数少,所以推荐验证码代码 一
图片 44.png (11.1 KB, 下载次数: 0)
下载附件
2025-4-15 15:16 上传
总结
载荷加密,都是同一个 只有参数 不同 所以在操作时要看清楚 明文载荷验证码,
正确率,还请各位大佬自己 改动 已达到百分百正确第一次玩验证码,
还请各位大佬多多指点,有没有讲到的 或不清晰的,还请大佬给予提示
再次感谢各位大佬