顶象全家桶

**声明:**本文仅作技术交流,严禁用于任何非法用途(如有冒犯,请联系我删除此文)

顶象验证码

在这里插入图片描述

type类型:
0.滑块
1.文字点选
2.刮刮乐
3.图标识别:图标点选
4.空间语义:点击三角形
5.语序点选:按语序依次点击
6.乱序拼图
7.旋转验证
8.面积验证
9.语言识别
10.差异点击:不同图案或文字
12.字体识别:选择不同风格的字体
13.滑动还原

分为私有版本和公共版本,私有版本的js不会变化,这里以滑块为例

1.加载

在这里插入图片描述
在这里插入图片描述

2.流程分析

2.1 引用 constid-js/index.js?_t=

每日会变两次,主要是get_c 加密算法,通过ast和基础的补环境,可以定位到加密方法,并且导出加密方法

2.2 引用 ctu-greenseer/greenseer.js?_t=

每日会变两次,主要是轨迹算法会改变,直接通过补环境生成ac轨迹参数

2.3 请求api/a?

参数:

https://cap.dingxiang-inc.com/api/a?
w=300    宽
h=150    高
s=50     应该是按钮
ak=73360ce3e32b708eb1a2a95602a614fe apiKey
c=669f75e7FcI7M330PgZPDwaJwObHZqmHrK3akEm1 客户端c
jsv=1.5.44.2 js版本
aid=dx-1721726464301-53773798-1 时间戳+随机数
wp=1     请求图片格式0是png,1是wepg
de=0
lf=0
cid=11484111  客户端id
_r=0.5289396790558949 随机数

返回值:

{
    "sid": "2f0e3af4361962bd0fa0383412e1d403",
    "cid": "11484111",
    "y": 41,
    "p1": "/customiz/wupE6GtgUX/zib3/e12ec5f8a45d4ad399538a84a0280d39.webp",
    "p2": "/customiz/wupE6GtgUX/zib3/23d470178a234c68a4e40a36d10fc4b7.webp",
    "p3": null,
    "type": 0,
    "logo": "/captcha-custom-image/cf4afa73946b46168210b9f02d5db480.png",
    "logoSwitch": 1,
    "tp1": null,
    "cw": null,
    "sc1": null,
    "icons": null,
    "verifyType": null,
    "childVerifyType": null,
    "imgName": null,
    "color": null,
    "chs": null,
    "ot": 0,
    "tk1": null,
    "speed1": 0.0,
    "speed2": 0.0,
    "bgUrl": null,
    "sliderUrl": null,
    "sliderBarUrl": null,
    "extra": null,
    "success": true,
    "msg": null,
    "t": null,
    "result": 1,
    "bc": null
}

2.4 请求/api/v1

https://cap.dingxiang-inc.com/api/v1
ac=4380%23j2XnQGHDtkv5IhS3XX4vJROa%2Fy3jm2mW8T%2FSjEVS43CpfrQ4kLVgYYoSsTZpsL21ZE3eu65KFXTpnYgUsNngXLnEUM%2FEij9nILy03trpfT3yFtWmiY503trEn3rEnESYPEyeYE7EiCgJihoisAIA3t2CRAWUXXHdiFWnfw37YrXmSX%2FXmUDc7J%2FhXXTHD9bBXrXEbbJMVs6u5nFAVpk85fJtrUUY7ZJMVehuQ4Rz9kPh7bjLC8IXuXJXmjrPrX88XXXXXXJXX7WPrX88mrXi5WvcZhvpmiImqrrXsBD9uJ2ctraSbH%2FdUdwli20gFYQGYKSkYttsiKSop5oGhMwPEgQeMb0ePIospKSnYrXmSXfXsJPYOg%2FEq28KXWcCfuqZCjwag%2FdmFe8yOqLOAQoQaV373VKIDWfs5V0EBBOzoXfXsJPYfXfcC8TuXWcCfuqZCjwag%2FdmFe8yOqLOAQoQaV373VKIDWfs5V0EBBOzoXVXY1Cy4ig2U%2FSXj8Xn%2B1TVLjX7hrXZXXCSOPRdIXTiXXVXY1Cy4F22X%2FSZj8Xn%2B1TV7wXvhrVZXXCSOPRoImvijXVXY1Cy4ZW21VSij8Xn%2B1TVdwjphrSZXXCSOPR1IFZiYrVXY1Cy4Ig2M%2FSij8Xn%2B1T9IwjuhrSZXXCSOP%2FdIIbiYrVXY1Cy4Rg2V%2FSij8Xn%2B1T9vwj%2BhrSZXXCSOP%2F0IiviYrVXY1Cy4TX2SySij8Xn%2B1T9uLYxhrSZXXCSOP%2FHIs4iYrVXY1Cy48f20ySij8Xn%2B1T9jwY7hryZXXCSOPaNInOiY8VXY1Cy4Dg2r%2FSnj8Xn%2B1T9OLYjhrrZXXCSOPa0InbiYXVXY1Cy4aW2E%2Fxdj8Xn%2B1T9DwYihzWZXXCSOPaPInxi42VXY1Cy4%2Fg2EVxdj8Xn%2B1T9QjYshzWZXXCSOPDpIvTi42VXY1Cy44r2c3xdj8Xn%2B1TtZwYahzWZXXCSOPnBIvOi4rVXY1CyWE%2F2y3xNj8Xn%2B1TtsLYThzfZXXCSOPn%2FIvZi4rVXY1CyWCg2yVxNj8Xn%2B1TtmLYWhzfZXXCSOPvdIv9i4rVXY1CyWz22zyxNj8Xn%2B1TtHRYJhzfZXXCSOPvzIvbi4rVXY1CyWAg2A3xNj8Xn%2B1TtDwYOhzfZXXCSOPiBIvxi4rVXY1CyWxW2AVxNj8Xn%2B1TtrjYkhzfZXXCSOPiPZNTi4rVXY1CyW03dO3xNj8Xn%2B1TtBw4chzfZXXCSOPs6ZNai4rVXY1CyWQfdOyxNj8Xn%2B1Ttww4zhzfZXXCSOPIdZN4i4rVXY1CyWt8dOVxNj8Xn%2B1TwPw4rhzfZXXCSOPIFZNui4rVXY1CyWNWdfyxNj8Xn%2B1TwTw4LhzfZXXCSOPZnZNZi4rVXY1CyWqfdk3xNj8Xn%2B1TwcL4ohz%2FZXXCSOPFBZNMi48VXY1CyWbIdk%2Fx9j8Xn%2B1TwdL4phz%2FZXXCSOPF4ZN7i48VXY1CyWjWdkVxNj8Xn%2B1T2Wj40hzfZXXCSOPmrZNbi4rVXY1CyWv8dkVxNj8Xn%2B1T2Nw40hzfZXXCSOPjHZNCi4rVXY1CyWRrd%2B3xNj8Xn%2B1TMkw4ShzfZXXCSOPuWZNCi4r3X7XdCWh9Kfz7zkEVVsaMEHA4pshIQ%2B6T0WVapO6MKftVVULyKFRfLs6Zp%2BAbukAaoHAIQZjgKFLodFYIQWzxlHAIQZYVrfd7AOtmxO1bwn1bEHYVLsDnQZjgNUtIQWtVVUwWLs6v7DPCBJD7pktVVHzCBkEIQkDClk1OpOD5QZYVlFyrlF%2Fx0fz2lFj7EktSbRhSgF1bt%2BDbKHATciL2giL2K%2B14lJDylF%2FVlFjM0Wc4S%2BzxK%2B1ZliL2KkdvD%2B1xqHACL%2Bc4zO1x0fAaonzcKWN4pnA7A%2B670iL2KkdvD%2B1xqHArQ42%3D%3D
ak=4efbf53ceebc7b351e8d4e27114bcc83
c=669f75e7FcI7M330PgZPDwaJwObHZqmHrK3akEm1
uid=
jsv=1.5.44.2
sid=fae0ece4461f52caf3fcf10a32dc573f
aid=dx-1721729209168-20039217-1
x=185
y=59

需要自己生成的是:x、轨迹数组
js内容主要是:
1.执行
let init = window._dx.UA.init( {“token”: sid});

2.触发滑动事件
触发滑块事件mousedown
触发滑块事件mousemove,并传入轨迹

3.执行
init.sendSA()
init.sendTemp({xpath: divPath, x: x, y: y});

3.参数分析

clickword-Captcha-js.js和basic-Captcha-js.js 还有greenseer.js 这三个js好像都是从captcha-ui/index.js中引用的
分析加密时,只需要反混greenseer.js文件就行

3.1 c参数

是设备指纹参数,从constid-js/index.js加密请求生成的,需要经过两次c请求,然后返回
解决方法:
1.只要找到加密方法,就能直接使用算法生成,使用ast,可以快速找到加密方法,分析加密参数
2.通过补环境,自动发送两次c1请求,就能生成,如果混淆得很厉害,就使用这种方案

3.2 图片还原

1.还原算法:通过hook canvas的图片拼接函数,可以快速得到算法步骤
2.通过扣js补环境执行canvas 的方式,还原图片,适合js代码无法还原的情况,应该很少用

3.3 计算坐标

将背景和图片都进行灰度化处理:
def handle_img(self, path, threshold1, threshold2):
img = cv2.imread(path)
edge = cv2.Canny(img, threshold1, threshold2)
pic = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
return pic

def get_distance(self, fg_path, bg_path):
    # 对滑块进行图片处理
    fg_pic = self.handle_img(fg_path, 1000, 200)
    # 对背景进行图片处理
    bg_pic = self.handle_img(bg_path, 1000, 200)
    # 使用【相关系数匹配 和 归一化相关系数匹配】
    methods = ["cv2.TM_CCOEFF", "cv2.TM_CCOEFF_NORMED"]
    results = {}
    move = 0
    for meth in methods:
        # 模板匹配matchTemplate
        res = cv2.matchTemplate(bg_pic.copy(), fg_pic, eval(meth))
        loc = cv2.minMaxLoc(res)[3]  # 左上角点的位置:最大值的索引位置
        results[meth] = loc  # 方便测试
        move = loc[0]  # 左边方框距离
    # 绘制方框【方便查看】
    th, tw = fg_pic.shape[:2]
    bottom_right = (loc[0] + tw, loc[1] + th)  # 右下角点的坐标
    cv2.rectangle(bg_pic, loc, bottom_right, (0, 0, 225), 2)  # 绘制矩形
    cv2.imshow("bg_img.png", bg_pic)
    cv2.waitKey(0)
    logger.debug(f"匹配参数: {results}: 移动距离:{move}")
    distance = math.floor((move + 34) * 3 / 4) - 24
    return distance

3.4 生成事件

轨迹算法生成涉及参数比较多,并且算法每天都会改变,所以采用补环境的方式,生成轨迹算法
流程:初始化、执行轨迹事件、执行加密(每种类型的验证码可能不一样)、发送模板(sendTem每种类型的值可能不同)
初始化:统一都是window._dx.UA.init(token)
事件触发,通过hook 事件的执行,来观察触发了哪些事件:

// 保存原始的 addEventListener 方法
const originalAddEventListener = EventTarget.prototype.addEventListener;
// 重写 addEventListener 方法
Object.defineProperty(EventTarget.prototype, 'addEventListener', {
    value: function(type, callback, options) {
            console.log("绑定事件:", type.toLowerCase(), this);
            const wrappedCallback = function(event) {
                console.log("执行事件:", type.toLowerCase(), this);
                callback.call(this, event);
            };
            originalAddEventListener.call(this, type, wrappedCallback, options);
    },
    configurable: true,
    enumerable: true,
    writable: true
});

4.结果

在这里插入图片描述

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值