目标网站:
aHR0cHM6Ly9qenNjLm1vaHVyZC5nb3YuY24vZGF0YS9jb21wYW55L2RldGFpbD9pZD0wMDIxMDUyOTEyMzk0NTEzMzk=
网站分析:
进入页面刷新,在加载数据前会过一道验证码,验证码左下角显示为极验验证码。经过几天观察发现,网站每天验证码类型随机,发现有五种类型验证码:滑块,文字点选,图标点选,九宫格和空间推理,验证码类型为极验3类型(极验3和极验四最大区别就是滑块,极验3需要检测滑块轨迹,极验四不需要,再就是混淆逻辑不同)。
db0K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
流程分析:
先看验证码请求逻辑,验证码完整的请求逻辑应该是先通过start接口获取challenge和gt,然后请求第一个get和ajax完成challenge和gt初始化,然后请求第二个get获取验证码图片信息,最后请求ajax提交验证。但经过测试发现可以去掉第一个get请求,第一个ajax的w值可以置空。
然后观察请求发现,start接口有内容加密,最后一个ajax有参数加密
6bbK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
加密:
startCaptcha接口:
返回内容为加密内容,断点调试发现为aes加密,密钥和iv都固定,可使用标准库实现。
39dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
ajax接口:
w值加密,这里可以搜索"\u0077"定位,也可以断点跟栈定位,就不做描述。
a4dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
b05K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
观察发现,w的值由两个值构成:h和u,u为r[$_CAIAL(738)]()函数运行的产生的值,h为m[$_CAHJk(762)](l)运行产生的值。
u:
先看u,跟进r[$_CAIAL(738)],跟进去发现这个函数实际执行语句为:var e = new U()[$_CBFJy(326)](this[$_CBGAs(766)](t)); while (!e || 256 !== e[$_CBFJy(142)]) e = new U()[$_CBGAs(326)](this[$_CBFJy(766)](!0));
其中this[$_CBGAs(766)](t)是一个随机字符串生成函数,可以固定写死,new U()[$_CBFJy(326)]是ras加密操作,这里可以使用三方库还原,也可以扣函数代码,公钥为固定值。
715K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
1b6K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
aa3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
h:
查看h之前需要处理l和o的值,因为h是对l处理加密得出,l是对o处理加密得出。
o值:向上跟栈定位o生成位置,发现o一共8个值,但其中只有u,passtime(这里取轨迹最后一个时间就行),aa和rp为变值,其余可以固定。
{ "lang": "zh-cn", "userresponse": "2ddd22df8", "passtime": 770, "imgload": 204, "aa": "U-,/-.04111-.(!!Stt(*((((((((((Rttttssssszstzsssust.(!!($))4,2h0111111111224$,-:-4I.7,2.667N91:$*p", "ep": { "v": "7.9.3", "$_BIT": false, "me": true, "tm": { "a": 1769566324330, "b": 1769566324785, "c": 1769566324789, "d": 0, "e": 0, "f": 1769566324331, "g": 1769566324331, "h": 1769566324331, "i": 1769566324331, "j": 1769566324331, "k": 0, "l": 1769566324338, "m": 1769566324777, "n": 1769566324779, "o": 1769566324797, "p": 1769566331309, "q": 1769566331309, "r": 1769566331310, "s": 1769566342149, "t": 1769566342149, "u": 1769566342149
}, "td": -1
}, "h9s9": "1816378497", "rp": "e22583d1b402b5916eb5ee92ccf71b74"} 566K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7">
6edK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
u:先看u值,u值为 H(t, i[$_CAHJk(168)]),其中t为滑动距离,i[$_CAHJk(168)]为请求使用的challenge值,H函数直接扣下来即可。
aa:aa的值需要向前跟栈,发现是使用n[$_CJJJE(986)][$_DAAAF(1024)]函数对滑动轨迹,图片请求返回的c和s进行加密处理,这里直接将函数($_BBEl和$_FDd)扣下来即可。
cd8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
rp:rp的值为X(i[$_CAHJk(176)] + i[$_CAIAL(168)][$_CAHJk(120)](0, 32) + o[$_CAIAL(714)]);三个值分别为gt,challenge和passtime,函数X可以直接扣代码。
l值:l = V[$_CAHJk(326)](yt[$_CAIAL(291)](o), r[$_CAHJk(766)]()),其中yt[$_CAIAL(291)]其实就JSON.stringify方法,r[$_CAHJk(766)]()就是之前生成的随机字符串。 V[$_CAHJk(326)]直接扣代码即可。
最后生成h值即可。
另外滑块的图片是乱序的(其中还原顺序是固定的,可以直接打canvas断点跟栈),这边直接给出还原代码,还原后直接使用ddddocr就可以获取滑动路径。
def restore_img_from_url(img_url, ut_array=None): """
从图片URL下载乱序图片,还原后返回二进制字节对象(适配ddddocr)
:param img_url: 图片的网络URL地址
:param ut_array: 拼图块的排列规则数组(默认使用原代码的Ut数组)
:return: 还原后的图片二进制字节对象 | None(失败时)
"""
# 默认排列规则(保留原代码的Ut数组)
default_ut = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43, 42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17]
Ut = ut_array if ut_array is not None else default_ut try: # 1. 下载图片(设置超时和请求头)
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
}
response = requests.get(img_url, headers=headers, timeout=10, verify=False)
response.raise_for_status() # 2. 从字节流打开图片并转为RGB模式
im = Image.open(BytesIO(response.content)).convert("RGB") # 3. 核心还原逻辑(不变)
canvas_width, canvas_height = 260, 160
new_image = Image.new("RGB", (canvas_width, canvas_height))
piece_height = canvas_height // 2 # 80px
for i in range(len(Ut)): # 计算裁剪位置
crop_x = Ut[i] % 26 * 12 + 1
crop_y = piece_height if Ut[i] > 25 else 0
crop_box = (crop_x, crop_y, crop_x + 10, crop_y + piece_height)
piece = im.crop(crop_box) # 计算粘贴位置
paste_x = i % 26 * 10
paste_y = piece_height if i > 25 else 0
new_image.paste(piece, (paste_x, paste_y)) # 4. 将还原后的Image对象转为二进制字节对象(关键修改)
img_byte_arr = BytesIO() # 保存为JPEG格式(ddddocr兼容),quality=95保证清晰度且体积适中
new_image.save(img_byte_arr, format='JPEG', quality=95)
img_byte_arr = img_byte_arr.getvalue() # 获取二进制字节
# 5. 返回二进制对象
return img_byte_arr except requests.exceptions.RequestException as e: print(f"图片下载失败:{str(e)}") return None
except Exception as e: print(f"图片处理/转二进制失败:{str(e)}") return None 4f6K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7">
滑块轨迹代码(网上copy大佬的):
def __ease_out_expo(sep): '''
轨迹相关操作
'''
if sep == 1: return 1
else: return 1 - pow(2, -10 * sep)def get_slide_track(distance): """
根据滑动距离生成滑动轨迹
:param distance: 需要滑动的距离
:return: 滑动轨迹<type 'list'>: [[x,y,t], ...]
x: 已滑动的横向距离
y: 已滑动的纵向距离, 除起点外, 均为0
t: 滑动过程消耗的时间, 单位: 毫秒
"""
if not isinstance(distance, int) or distance < 0: raise ValueError(f"distance类型必须是大于等于0的整数: distance: {distance}, type: {type(distance)}") # 初始化轨迹列表
slide_track = [
[random.randint(-50, -10), random.randint(-50, -10), 0],
[0, 0, 0],
] # 共记录count次滑块位置信息
count = 10 + int(distance / 2) # 初始化滑动时间
t = random.randint(50, 100) # 记录上一次滑动的距离
_x = 0
_y = 0
for i in range(count): # 已滑动的横向距离
x = round(__ease_out_expo(i / count) * distance) # y = round(__ease_out_expo(i / count) * 14)
# 滑动过程消耗的时间
t += random.randint(10, 50) if x == _x: continue
slide_track.append([x, _y, t])
_x = x
slide_track.append(slide_track[-1]) return slide_track 14dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7">
上面是滑块的加密流程,其他几种验证和滑块的区别是o值不一样,有3个变值(a,pic,tt)。其中pic为图片的path路径(返回的),e为点击的坐标(这里需要处理,可以打click断点进行单步调试,注意,网页调试是传入的是视图坐标,和本地下载识别坐标不一致,需要对处理逻辑简单处理一下(直接从图片对象坐标开始扣代码),还需要注意网页图片大小和下载图片大小进行坐标比例换算),tt由浏览器指纹(固定),返回的c和s加密得出。
{ "lang": "zh-cn", "passtime": 1242, // 通过时间不校验 "a": e, // 坐标 "pic": pic_path, // 返回的图片路径 "tt": function (e, t, n) {
var $_CADFN = YDbxr.$_Ct
, $_CADEk = ['$_CADIZ'].concat($_CADFN)
, $_CADGD = $_CADEk[1];
$_CADEk.shift();
var $_CADHd = $_CADEk[0]; if (!t || !n) return e;
var r, i = 0, s = e, o = t[0], _ = t[2], a = t[4]; while (r = n[$_CADFN(784)](i, 2)) {
i += 2;
var c = parseInt(r, 16)
, l = String[$_CADFN(181)](c)
, u = (o * c * c + _ * c + a) % e[$_CADFN(138)];
s = s[$_CADGD(784)](0, u) + l + s[$_CADFN(784)](u);
} return s;
}(s, c, s_s), "ep": { "ca": [
{ "x": 894, "y": 278, "t": 1, "dt": 1656
},
{ "x": 938, "y": 193, "t": 1, "dt": 415
},
{ "x": 1025, "y": 184, "t": 1, "dt": 392
},
{ "x": 1067, "y": 426, "t": 3, "dt": 1068
},
{ "x": 920, "y": 343, "t": 1, "dt": 89532
},
{ "x": 852, "y": 195, "t": 1, "dt": 448
},
{ "x": 1046, "y": 435, "t": 3, "dt": 789
}
], "v": "3.1.2", "$_FG": false, "me": true, "tm": { "a": 1768372719938, "b": 1768372720034, "c": 1768372720036, "d": 0, "e": 0, "f": 1768372719939, "g": 1768372719940, "h": 1768372719943, "i": 1768372719943, "j": 1768372720000, "k": 1768372719970, "l": 1768372720000, "m": 1768372720030, "n": 1768372720030, "o": 1768372720042, "p": 1768372720686, "q": 1768372720686, "r": 1768372720686, "s": 1768372722999, "t": 1768372722999, "u": 1768372722999
}
} // 固定
} 515K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7">
结果:
返回为sucess就表明成功,score为轨迹人机分数,分数越低越像人为操作。
a86K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7">
e83K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6U0M7$3c8F1K9h3#2Y4i4K6u0W2j5$3&6Q4x3V1k6J5k6h3I4W2j5i4y4W2i4K6u0r3j5X3I4G2k6#2)9#2k6X3g2V1K9i4c8G2M7W2)9#2k6X3S2@1L8h3I4Q4x3V1k6J5k6h3I4W2j5i4y4W2x3W2)9J5k6e0c8Q4x3X3f1$3i4K6u0r3j5$3E0W2k6r3W2@1L8%4u0Q4x3V1k6H3L8s2g2Y4K9h3&6K6i4K6u0r3N6$3W2V1k6$3g2@1i4K6u0r3K9h3#2S2k6$3g2K6i4K6u0r3K9r3q4F1k6r3I4W2i4K6u0W2M7r3&6Y4i4K6t1&6i4K6y4n7"> 编辑
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!