⚠️前言⚠️
本文仅用于学术交流。
学习探讨逆向知识,欢迎私信共享学习心得。
如有侵权,联系博主删除。
请勿商用,否则后果自负。
网址
aHR0cHM6Ly9zZWMueGlhb2R1bi5jb20vb25saW5lRXhwZXJpZW5jZS9zbGlkaW5nUHV6emxl
1. 先整体分析一下接口
1_1. 验证码信息下发接口 validatecode/v1
- 参数 - 加密值不少,表慌不复杂
- 响应内容
1_2. 验证接口 validatecode/v1
- 参数 - 和信息下发接口一致 p1 - p9,加密逻辑应该是一致的
- 响应信息1 - 验证成功
- 响应信息2 - 验证失败,重新返回验证码信息
2. 底图还原
2_1. 乱序底图
2_2. canvas 断点
-
简单调试一下就会发现几个关键位置
-
CanvasRenderingContext2D.getImageData(sx, sy, sw, sh):返回一个ImageData对象,用来描述 canvas 区域隐含的像素数据,这个区域通过矩形表示。【简单来说,其实就是对原图的一个切割】
sx:将要被提取的图像数据矩形区域的左上角 x 坐标。
sy:将要被提取的图像数据矩形区域的左上角 y 坐标。
sw:将要被提取的图像数据矩形区域的宽度。
sh: 将要被提取的图像数据矩形区域的高度。 -
CanvasRenderingContext2D.putImageData(imagedata, dx, dy): 是 Canvas 2D API 将数据从已有的 ImageData 对象绘制到位图的方法。
imageData:ImageData,包含像素值的数组对象。
dx:源图像数据在目标画布中的位置偏移量(x 轴方向的偏移量)。
dy:源图像数据在目标画布中的位置偏移量(y 轴方向的偏移量)。
- 原图切割和还原的位置找到之后,现在只需要得到还原数组就可以还原底图了
- 大致就是这个位置了,字符串 QOQ0oo 中的每个字符转化成 int 类型就是还原数组
- 而这个字符串,存在于验证码信息接口中
2_3. 还原结果
3. 加密值分析
3_1. 加密位置
3_2. p1
- oOoQQ0 固定值
- window._fmOpt.token 生成位置
- window._fmOpt.partner 固定值
- window._fmOpt.appName 固定值
3_3. p2
- p2 值的生成 主要就是这个 blackBox 值,由 window._fmOpt.getinfo() 生成
- window._fmOpt.getinfo() 存在于另一个js文件中 fm.js,参数由接口 /profile.json 返回的 tokenId 可固定
- fm.js 文件本部复杂,大家可自行分析一下代码
3_4. p3
- ooQQ0Q 进行 aes 加密,ooQQ0Q = MD5(p1 + ‘^^’ + p2) + + ‘^^’ + ‘|’ + ‘^^’ + ‘|’ + ‘^^’ + ‘|’ + + md5(‘161155^||^'时间戳’)
- aes 加密有魔改, 我是直接扣的代码, 有兴趣的小伙伴也可以自行研究一下
3_5. p4
- 对 mouseInfo 信息AES加密, 经测试 mouseInfo 可固定
3_6. p6
- 8位随机字符串 + window.location.href, AES 加密
3_7. p7
- 需要用到 【p6】 和 【生成p3时生成的时间戳字符串】, 分别 md5 之后 + 32位随机字符串
3_8. p8
- 生成p6时用到的 8 位随机字符串
3_9. p9
- 【生成p3时的时间戳字符串】, AES加密
3_10. 至此,就可以顺利拿到验证码信息了,验证码验证时,p2 和 p3 生成时的参数所不同, 其他不变
- p2:后面固定即可
- p3:aes之前,拼接上了验证码信息以及滑动信息
3_11. 加密并不难,就是混淆的有点难受,把各值对应好即可。下面来说一下两个需要注意的点
- 生成加密时用到的md5, 为原生md5, 可直接代码实现
- 涉及到 AES 加密用到的 iv 值, 生成各加密值过程中需保持不变