免责声明:本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

逆向目标

逆向过程

逆向过程基本上与消消乐与五子棋一致。说说不同的几点。

  1. 关于验证码加载接口

入参只有risk_type不一样,其余都一致。文字点选的risk_type为word,消消乐的为match,五子棋的是winlinze。接口返回的数据也基本一致,不同的是imgs对应的是点选验证码的底图,即要点击的图片,而ques这是要点击的文字的图片。如下图:

可以看到,ques中图片的顺序与要点击的文字的顺序一一对应。

  1. 关于验证码验证接口

入参完全一致,生成w参数的e对象结构也一致,如下图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"passtime":2617,
"userresponse":[[993, 1025], [1793, 5472], [3793, 1874]],
"device_id":"9f5faf6dc7a77e1d394c8634f0893812",
"lot_number":"dac26749dcc54f758675ffa7280d52b3",
"pow_msg":"1|0|md5|2023-05-24T00:19:56.722398+08:00|54088bb07d2df3c46b79f80300b0abbe|dac26749dcc54f758675ffa7280d52b3||f1c8f88b905d4249",
"pow_sign":"57c50f085e4c13fe6d23c870b96d5b1b",
"geetest":"captcha",
"lang":"zh",
"ep":"123",
"mrc5":"103342051",
"em":{
"ph":0,
"cp":0,
"ek":"11",
"wd":1,
"nt":0,
"si":0,
"sc":0
}
}

userresponse正是点击背景图上三个文字产生的坐标,但是这个坐标数值比较大,而实际的背景图大小是宽为300px,高为200px的,所以这个坐标肯定是经过处理的。

扒一扒userresponse的生成过程:

添加如下断点:

image-20230524012849614

一路跟踪到这里:

image-20230524013702426

其中,t[left],t[top],t[width],t[height]都是固定值,分别为:103,320,300, 200。简单分析一下知,r和i分别是点击的位置坐标在整个背景图上的横纵坐标所占百分比,也即是某个汉字在整个背景图上横纵坐标的占比。最后,把这个百分比扩大100倍取整即可。

分析出来了userresponse坐标的生成过程,接下来就是文字点选最关键的目标检测与识别。

  1. 文字位置的检测与识别

首先是底图文字位置的检测,使用ddddocr库,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import ddddocr
import cv2

det = ddddocr.DdddOcr(det=True)

with open("4138cab002ce453696bd84d92cc5322f.jpg", 'rb') as f:
image = f.read()

poses = det.detection(image)
print(poses)

im = cv2.imread("4138cab002ce453696bd84d92cc5322f.jpg")

for box in poses:
x1, y1, x2, y2 = box
im = cv2.rectangle(im, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2)

cv2.imwrite("result.jpg", im)

输出三个坐标,同时标记了验证码图片上文字的位置。

举例几张图片如下:

image-20230524101252194
image-20230524101252194

并输出坐标为:[[78, 18, 131, 71], [122, 102, 174, 152], [175, 89, 227, 139]]。

接下来就是文字识别,根据每个文字的四个顶点坐标把文字依次裁剪下来,代码如下:

1
2
3
4
import cv2

img = cv2.imread("4138cab002ce453696bd84d92cc5322f.jpg")
cropped = img[18:71, 78:131] # 裁剪坐标为[y0:y1, x0:x1]

得到的图片依次为:

result1](https://raw.githubusercontent.com/lyy077/blg-pic/main/pic/202305241745081.jpg)![result2](https://raw.githubusercontent.com/lyy077/blg-pic/main/pic/202305241746166.jpg)![result3
result1](https://raw.githubusercontent.com/lyy077/blg-pic/main/pic/202305241745081.jpg)![result2](https://raw.githubusercontent.com/lyy077/blg-pic/main/pic/202305241746166.jpg)![result3

然后再用ddddocr依次对其做文字识别:

1
2
3
4
5
6
7
8
9
import ddddocr

ocr = ddddocr.DdddOcr()

with open("1.png", 'rb') as f:
image = f.read()

res = ocr.classification(image)
print(res)

识别结果如下:

image-20230524174831372

识别还是挺准确的。

除了底图的文字位置检测与识别,还有上边的标题需要识别,如下图:

image-20230524175041775

这些文字都是比较规整,并且同一个汉子的图片的md5的文件名基本上是不变的,大约只有400多个汉字,所以提前跑一个脚本,把它们收集起来即可。如下图:

image-20230524175703147

承载汉字的md5码名称的图片文件与汉字一一对应,并保存到data.pickle文件中。

运行与测试

运行与测试结果如下:

image-20230524190803029

识别2个或者3个汉字,才能验证成功。通过测试可知,汉字的识别率还是挺低的,还是需要自己收集数据训练。后边会专门出一篇文章介绍自己训练这一块。

若需要完整代码,扫描加微信。

image-20230517010053227