本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!若有侵权,请添加(wx:ShawYbo)联系删除
目标网站
网站:
aHR0cHM6Ly90aWViYS5iYWlkdS5jb20vZj9pZT11dGYtOCZrdz0lRTYlOTglQkUlRTUlOEQlQTEmcG49MzE=
目标:验证码图片初始化响应及图片正确顺序处理、轨迹参数构造。
分析过程
初始化请求:获取验证码会话信息
-
图片数据请求:获取加密的验证码图片数据
-
数据解密:解密图片下载地址和拼接规则
-
图片重构:下载并重新拼接验证码图片
-
数字识别:识别图片中的数字及坐标
-
轨迹生成:生成符合人类行为的点击轨迹
-
数据加密:构建并加密提交参数
-
结果提交:提交验证结果
前两步没什么好说的,参数都是死的,直接照搬就行。查看devtools我们可以看到,请求回来的验证码是乱序的,正确的顺序在初始化请求中,需要先解密,然后重新拼接图片,最后进行识别:


通过XHR断点可以找到,初始化验证码图片请求是BiocCaptcha.js发出来的,粗略看一下这个js可知这是vmp,混淆强度不大且结构清晰:
-
M[2]: 栈操作指令
-
M[3-4]: 变量赋值和取值指令
-
M[5-8]: 常量加载指令
-
M[29-41]: 算术运算指令
-
M[47]: 方法调用指令(核心)
-
M[51-53]: 控制流指令
M[47]就是这个vmp指令执行的核心了,给这里插桩,分析日志。
M[47] = function(t, n) {
for (var r = n.X, i = r[t[1]].get(), o = i[r[t[2]].get()], c = [], a = t[3]; a < t[4]; a++) {
var s = r[a].get();
c.push(s)
}
n.V = new e(o.apply(i, c))
}
首先解密/webapi/verint/img请求响应中的enc_data,该响应包含了验证码图片的正确拼接顺序和请求地址。通过插桩日志可以看出,先构建一个字符串,具体规则为:r+ak+bid+'{bioc_slat}',r和bid的值同为当前响应,ak为固定值(同个网站相同),然后使用sha1对该字符串加密,再截取前16位作为后续解密的key。具体的解密算法为aes-cbc,key我们已经获取到了,iv是固定值16fe0555d0c6d15d

最终的解密结果示例:
接下来就是按照config["pm"]中的规则还原底图。数组第一位config["pm"][0]表示切割方块的长宽(150,50),由于原图是300*200,所以整好被分为了8快,接下来config["pm"][1]到config["pm"][8]代表每一块原本的位置。
我们以底图左上角为坐标起点,按照config["pm"][0]划分坐标系。比如config["pm"][2]就是第二块图,他的值为0_50_150_0,由于只看左上角的坐标,所以去前两个点位0_50,那么他对应的实际位置即为3(当前为2)。
{
"master":"https://bioc-captcha.cdn.bcebos.com",
"standby":"https://bioc-captcha-su-standby.cdn.bcebos.com",
"imgUrl":"cimages/20231017/2655e4dbd8784149b40b242c6801160b.jpeg",
"config":{
"pm":[
"150_50",
"150_0_0_0",
"0_50_150_0",
"0_150_0_50",
"150_100_150_50",
"0_0_0_100",
"0_100_150_100",
"150_150_0_150",
"150_50_150_150"
],
"clickCount":1,
"question":{
"type":"string",
"value":"请点击最小的数值"
}
}
}


还原好底图后,就可以获取点击坐标了,我这里是使用的某打码平台,后续会自己训个模型。
接下来就是构造轨迹和加密payload了,轨迹直接用贝塞尔,几个点位一连接就行。
payload中有lil、la、rl、bfi等,这几个值是先前js文件的加载时间戳与BiocCaptcha.js初始化时间错的差值,hook一下date.now即可得知,这里不赘述了。
在正真加密之前,先对payload进行base64编码,通过日志可以看出他对编码的字符集随机调换了位置。

完成编码后,payload进行aes-cbc加密,具体流程可见下图,key的获取和解密enc_data时一样,其中af8b9d6a68de383f7141a92faff7730bdd38047b为固定值(初始化的时候已加载),截取sha1前16位作为key,iv为固定值。

PS: 这个vmp样本还是比较简单的,直接找到call、apply插桩即可,该样本既没有高强度混淆,也没有devtools检测,也没有代码展开检测,插完桩分析日志即可。
结果验证

可添加宫中号:冰敷逆向笔记
一起交流学习。。。

598

被折叠的 条评论
为什么被折叠?



