本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关.本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责
感谢各位大佬的支持与观看
目标网址:aHR0cHM6Ly93d3cueW5qempnY3guY29tL2RhdGFQdWIvZW50ZXJwcmlzZQ==
前情提要
-------------------------------------------------------------------------------------------------------------------
这一篇我们直接开始讲解主题 :
过完验证码获取到数据这个栈每次翻页都需要过验证码 因此 数据也就在 请求验证码的数据包里 如下图
所以 对于这个栈我们就需要 只对验证码进行分析 从而请求到我们需要的数据
-----------------------------------------------------------------------------------------------------------------------
第一步
1.1 我们先来分析出 浏览器是通过什么流程 获取到 验证码的 (其中包括 数据包 某个参数 还有图片),
我们可以刷新验证图片 或者 将整个网页都进行刷新,那么我们也只有这一个包
1.2 这个包里面的数据我们可以看到 是 一些密文 我们在控制台打印来一个个分析
1.2.1 bigImage: 解密下载之后是 验证码的背景图
smallImage: 解密下载之后是 验证码的缺口图片
slideId: 后面参数加密需要
yHeight:目前对我来说 是不知名参数(哪位大佬研究出来是什么 希望评论或私信给我,感谢分享)
1.3 分析的到位,接着我们就来搞掉这个载荷的密文
进入genVcode数据包 在这里我们可以刷新验证码来断点,不用刷新浏览器
1.4 在 send方法里面就是我们要的载荷的密文,经过多次的调试 加密的密文显然不在这里,
这一点可以验证我们在 这个函数的开头下断 如果没有密文,那他就是在这里面,
如果是传入的那我们就需要向上跟栈,去找,如下图
1.5 我们刷新验证码让断点生效,我们看到了,密文是从上一个栈 传入其中
,所以我们就向上跟栈
第二步 我们根据箭头向上跟栈,到第四个箭头处,在这里有个拦截器,
我们可以依次进入,在return处下断,在重新发包,让断点生效,
也就是进入到 i 里面
2.1 接着我们来展示 i 里面每个函数的下断处,我们让断点生效时
需要将其他断点取消 ,只留这几个 ,拦截器的断点也要取消
2.2 最后在Pt.interceptors.request.use 函数体内 停下 我们也看到返回的内容里面有我们需要的密文
所以为了 检验是否在这里面 生成我们在头部也下断 ,另外其他断点就可以取消掉了,以免扰乱思路
2.3 我们来发包看 密文还在不在 不在就是这个函数里面的 在那就还需要向上跟栈 我们发现出现了明文,
所以我们知道了 密文应该是这个函数里面 生成的,所以,我们就在这个函数,进行调试,来寻找看有没有我们想要的
2.4 我们点击图片中按钮来进行代码的调试,因为单步调试会进入其他不相干,
比如只会返回 true或 false所以 我们就直接跳过来查看 看密文 在哪出现
2.5 我们调试到这里,发现出现了 密文 而这里有个params组成 所以我们就推测
密文是在这里,那么我们就可以开进行 扣取然后将数据加密来测试
第三步 我们来扣取代码 进行参数加密然后请求
3.1 我们将代码扣取下来,进行分析a$e().encrypt 是我们第一次加密的函数
因为我们浏览器就能一眼看出 他先试用这个进行一次加密
u$e(s) 是我们最终的加密 s 里面的值就是
a$e().encrypt 加密得出
3.2 对于参数的加密 上述的明文 是我们这个包的 里面有我们要的 验证码图片信息,
大家可以自行查看,所以3.1 所述 的代码整改就是我们的 这个包的参数加密,
那我们运行代码进行一个代码补全 实现最终的加密
3.3 我们直接选中函数 进入他的位置将他扣取,随后我们就看报错
,少哪一个 我们就直接进入找到位置,进行扣取
3.4 我们按照每一个报错补完之后发现 又出现一个报错 就是
我们主函数里面的 o 不能进行实例化,但明明我们扣取完毕,
还是不给我们想要的,且报错,那我们就需要思考究竟是哪些原因,
在这就不卖关子了我们直接演示
3.5 原因很简单就是少扣取 但是他不给你明确指示
所以在这里展示一种另类且无脑的扣取方法下图 将包含两个箭头处
和他们中间的代码全部扣取下来 这里是做了多次调试
发现报错不给,就多次调试出来的结果
第四步 我们运行代码发现报错 在这里的st 是一个判断
他的意思是 用global 还是 globalThis 赋值给st,也就是下图的
var st = typeof globalThis != "undefined" ? globalThis : typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : {};
4.1 我们将代码装载运行 在这里需要补上一个 window=global 或者 window = globalThis 两者都可
4.2 接着运行调试 ,看报错,是我们的最终加密,所以我们接着看报错少那个扣取那个,对于 l$e 这个报错我们需要扣取三个
4.3 当我扣取之后 在紧接着的报错是 某某变量不是方法,就让我们很苦恼,
也就代表着我们的代码没有扣到位,那么我们,可以看到 ,他是new l$e 出现了问题,
在这里我们不去深究它里面是什么,因为我们知道在 3.5 就遇到过这种情况 报错不给,
没有明确指示是哪个问题,所以在经过多次调试,我们就知道我们要按照3.5的扣取方法
4.4 也是包括 箭头两处全部扣取,因为几步报错,也不指明,那我们就只能,在他周围尝试着扣取,
因为他们就是在某处定义然后使用,所以我们就将计就计 都拿来吧,就算扣取到没有的,
那我们也不用担心,多次调试优化 就可以得出简洁的代码,所以我们就直接扣取使用
4.5 我们运行代码,发现可以了,没有报错也没有输出,也就达到了一半 没有报错,
但是我们得要结果,没结果的事,怎么可能去做,那么下面也就要讲解一个难以发觉的错误,
也就是大量扣取,不容易被发现的浏览器的小动作
第五步 代码总体没问题,存在于多扣但没有少扣取,所以就是因为我们的代码里有我们不需要的,
才导致打印为空我们可以在本地下断点就可以看到值,所以说在某处 console.log()被改写或者拦截 等等
5.1 经过多次调试我们发现 代码有两处 写法一样并且运行了,这里的代码是经过多次调试,
得出的结论,发现是这里导致了代码打印为空的操作所以我们将 s$e(); i$e(); 这两处删除或者注释掉,
那么打印自然就出现
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外 其余都可以固定
第六步 完成两次请求需要的参数了,接下来就是放出请求的结果有两种第一种 参数没有按照5.3 操作 有响应但是 没有数据
第二种 显示验证码错误,这是因为 上面提供的两个验证码正确率不是太高 但代码一要不代码二 出现不正确次数少,所以推荐验证码代码 一
总结
载荷加密,都是同一个 只有参数 不同 所以在操作时要看清楚 明文载荷验证码,
正确率,还请各位大佬自己 改动 已达到百分百正确第一次玩验证码,
还请各位大佬多多指点,有没有讲到的 或不清晰的,还请大佬给予提示
再次感谢各位大佬 |