首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
AI 自身安全
发新帖
3
8
[原创] 浅谈梯度分析与样本对抗:以vlm和ddddocr为例
发表于: 2026-4-15 12:16
9879
[原创] 浅谈梯度分析与样本对抗:以vlm和ddddocr为例
the_hs
1
2026-4-15 12:16
9879
## 0x00 Background 早在2018年,便有<a href="elink@924K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6S2M7Y4S2A6N6W2)9J5k6h3!0J5k6#2)9J5c8X3q4T1M7#2)9J5c8U0p5^5x3o6S2Q4x3X3f1H3y4K6V1@1y4b7`.`.">学者</a>发现可以通过仅修改几个像素来干扰模型对输入的预测。 作为一篇社区博客,本文将谈论如何**构造**验证码,而不是如何解决验证码,以避免不必要的副面影响(构造验证码来保护在线业务几乎总是有利于保护网络安全环境的)。请勿恶意构造其他数据,或利用类似方法做对抗性滤波,避免对他人服务产生影响。 那么,闲话休提,让我们开始吧。 ## 0x01 验证码识别器的原理 在开始谈论对抗性验证码构造前,我们必须了解验证码识别器的原理。 绝大多数的人工智能识别器,从ResNet到Yolo,都是基于卷积层的。卷积层是网络的核心,其运算并非数学严格定义上的卷积,而是互相关运算。给定一个二维输入张量X,其维度为高度H和宽度W,卷积核K为一个大小为kH乘以kW的张量。输出特征图矩阵中的每一个元素Y(i, j)是通过卷积核在输入图像上的滑动窗口内进行逐元素相乘并求和得到的。从数学角度看,这可以表示为在每一个空间位置上,输入局部区域向量与卷积核权值向量的内积再加上偏置项。由于同一个卷积核在整个输入空间上滑动,这种权值共享极大减少了参数数量,并利用了图像统计属性的局部平稳性。在卷积操作之后,通常会施加一个非线性激活函数,最常用的是修正线性单元ReLU,即函数f(x)等于max(0, x)。引入非线性的目的是为了使网络能够拟合复杂的非线性函数,否则多层线性卷积层在数学上等价于单层线性变换,将失去深层结构的表达能力。 这里,为了更教育意义,我们这里先自己训练一个甚至有一点过度简化(只有数字识别、没有位置检测和分割功能)的验证码识别器。在产业中,这一步可以直接替换为使用攻击者使用的模型进行防御。 我们先对mnist数据集进行一些简单的扰动,代码如下: ```python # img is 28x28 numpy array, uint8 # Random shift -2 to 2 shift_x, shift_y = random.randint(-2, 2), random.randint(-2, 2) M1 = np.float32([[1, 0, shift_x], [0, 1, shift_y]]) img = cv2.warpAffine(img, M1, (28, 28), borderValue=0) # Random scale -> resize and crop/pad to 28x28 # Target size within 26x30 to 30x26 t_width = random.randint(26, 30) t_height = 56 - t_width # keeping sum around 56, matching 26x30 ~ 30x26 boundaries if t_width == 28: t_height = 28 else: t_height = random.randint(26, 30) img = cv2.resize(img, (t_width, t_height)) # Pad or crop to 28x28 canvas = np.zeros((28, 28), dtype=np.uint8) start_y = max((t_height - 28) // 2, 0) start_x = max((t_width - 28) // 2, 0) c_start_y = max((28 - t_height) // 2, 0) c_start_x = max((28 - t_width) // 2, 0) copy_h = min(28, t_height) copy_w = min(28, t_width) canvas[c_start_y:c_start_y + copy_h, c_start_x:c_start_x + copy_w] = img[start_y:start_y + copy_h, start_x:start_x + copy_w] img = canvas angle = random.uniform(-20, 20) M2 = cv2.getRotationMatrix2D((14, 14), angle, 1.0) img = cv2.warpAffine(img, M2, (28, 28), borderValue=0) # Add 10 random noise pixels for _ in range(10): nx, ny = random.randint(0, 27), random.randint(0, 27) img[ny, nx] = random.choice([0, 255]) return img.astype(np.float32) / 255.0 ``` 效果如图所示  很多传统的验证码生成器就到此为止了(生成随机干扰点和线)。必须指出,尽管在今天看来,这种扰动是毫无意义的(任何合理的OCR都能无视这种扰动),但是它可以避免我们接下来的构建的识别器过度简单,从而不能正确地反应其他识别器的弱点。 ## 0x02 验证码识别器的构建 我们可以随手(嗯,真的是随手,根本没怎么调优)设计一个CNN网络,比如说如图所示:  代码如下: ```python class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() self.conv1 = nn.Conv2d(1, 16, kernel_size=3, padding=1) self.relu = nn.ReLU() self.pool = nn.MaxPool2d(2, 2) self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1) self.fc1 = nn.Linear(32 * 7 * 7, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): x = self.pool(self.relu(self.conv1(x))) x = self.pool(self.relu(self.conv2(x))) x = x.view(-1, 32 * 7 * 7) x = self.relu(self.fc1(x)) x = self.fc2(x) return x ``` 并画上那么几秒钟进行一个简单的训练。五秒钟后,尽管模型的准确率只有95%,并且没有分割等功能,但是已经足够我们下一步使用了。 ```log Epoch 20/20, Loss: 0.0017 Time elapsed: 5.03 seconds Test Accuracy: 95.10% ``` ## 0x03 对抗性样本的构造 构造对抗性样本有很多种不同的方法,这里展示一种笔者<a href="elink@be8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6G2M7r3g2F1j5h3y4U0k6i4y4K6i4K6u0W2N6r3S2W2j5%4k6X3i4K6u0W2j5$3!0E0i4K6u0r3j5$3!0F1N6r3g2F1N6q4)9J5c8V1W2o6b7#2j5J5x3o6t1#2i4K6u0r3K9s2c8E0L8q4)9J5c8V1N6S2L8#2)9#2k6V1k6S2M7%4c8v1f1@1#2m8i4K6g2X3b7h3y4U0k6h3I4W2M7X3q4@1K9h3&6Y4i4K6g2X3d9X3q4U0L8$3u0A6j5h3&6Q4x3X3c8T1j5i4y4W2k6q4)9#2k6W2y4S2L8r3W2W2L8X3y4&6i4K6g2X3e0h3q4H3i4K6g2X3b7i4c8@1j5h3y4C8M7#2)9#2k6Y4c8Z5M7X3!0#2k6$3S2Q4y4h3k6s2M7X3q4V1K9h3g2F1N6q4)9#2k6V1c8W2j5$3!0#2M7r3I4A6L8X3N6Q4y4h3k6u0b7@1y4h3i4K6g2X3x3U0l9J5y4g2)9#2k6Y4m8S2M7r3g2J5i4K6u0W2K9s2c8E0L8l9`.`.">前日设计的方法</a>的变种:取预测中高置信度的部分作为优化目标,进行逐点干扰。这里,为了确保不被滤波器滤除,同时没有benchmark需求,我们选择随机构造扰动幅度,代码如下: ```python img_adv = img_tensor.clone().detach().requires_grad_(True) # A T = set() for step in range(50): if img_adv.grad is not None: img_adv.grad.zero_() output = model(img_adv) model.zero_grad() output[0, target_class].backward(retain_graph=True) grad_target = img_adv.grad.clone() img_adv.grad.zero_() output[0, source_class].backward() grad_source = img_adv.grad.clone() D = (0.5 * grad_target - grad_source).squeeze() D_flat = D.view(-1) for t_idx in T: D_flat[t_idx] = -float('inf') max_idx = torch.argmax(D_flat).item() T.add(max_idx) # B magnitude = random.uniform(0.3, 0.6) direction = torch.sign(D_flat[max_idx]).item() if direction == 0: direction = 1 with torch.no_grad(): flat_img = img_adv.view(-1) flat_img[max_idx] += direction * magnitude # C flat_img.clamp_(0, 1) img_adv.requires_grad_(True) ``` 上述代码中A处是为了避免重复修改相同像素,B处是刚才提到的随机扰动,C处是为了避免生成的值不再是图像;这些点比较琐碎,但不正确的实现还是会导致效果不对。g+与g-的混合因子、试探方式与paper中存在微小出入,是为了更好地适配ddddocr进行的工程优化。那么,就,大功告成。 ## 0x04 效果测试 4339  ddddocr-数字模式:识别失败  几个常见的vlm: 7984 9339 4239  ddddocr-全量模式:y33g  PaddleOCR-VL: 936.9  因此可以认为我们的验证码对于常见的机器学习方法拥有足够的抵抗力。 ## 0x05 碎碎念 本文所展示的对抗性样本构造方法,其唯一目的在于学术探讨及网络安全防御应用,旨在通过提升验证码的抗 AI 识别能力,帮助开发者更好地保护在线业务免受恶意自动化程序的攻击。请勿将本文涉及的技术、代码或逻辑用于任何非法或违背道德的行为,包括但不限于样本投毒、恶意绕过他人的安全防御系统或干扰正常网络服务。在进行任何相关实验或应用时,请确保严格遵守《生成式人工智能服务管理暂行办法》及所在地区的相关法律法规。技术的使用应始终保持在合法、合规且符合伦理的框架内。 1. 不知道配置本地的深度学习研究环境是否回对坛友们构成阻碍...如果有存在本地显卡,但是卡在配置python环境上了的坛友,可以在留言中说一声(显卡型号/内存大小/操作系统版本)之类的...如果说的人比较多后续我可能做一个整合包,方便坛友本地跑... 2. 不知道坛友对AI模型内部的什么方向感兴趣 3. 本文允许转载,无需额外询问,但请标明出处 AI安全目前还是很新的方向,本人只敢说略懂一二;如有纰漏之处,还烦请诸位斧正。
登录后可查看完整内容
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
收藏
・
3
点赞
・
8
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
Valdoivre
为你点赞!
2天前
黑洛
你的分享对大家帮助很大,非常感谢!
4天前
需要渗透高手
为你点赞!
2026-4-18 22:25
MsScotch
+1
非常支持你的观点!
2026-4-17 13:12
蜗蜗722
+1
非常支持你的观点!
2026-4-16 22:35
孤独的街
感谢你的贡献,论坛因你而更加精彩!
2026-4-16 11:31
马来
你的分享对大家帮助很大,非常感谢!
2026-4-15 19:27
Saileaxh
你的帖子非常有用,感谢分享!
2026-4-15 12:20
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
5
)
Saileaxh
雪 币:
3110
活跃值:
(2919)
能力值:
( LV6,RANK:80 )
在线值:
发帖
18
回帖
49
粉丝
108
关注
私信
Saileaxh
1
2
楼
技术有深度,语言很易懂。好文章
2026-4-15 12:21
0
mb_tvavcucw
雪 币:
20
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
3
粉丝
0
关注
私信
mb_tvavcucw
3
楼
Saileaxh
技术有深度,语言很易懂。好文章
您好,我想求助,拜托怎么联系呀?
2026-4-16 11:01
0
需要渗透高手
雪 币:
114
活跃值:
(280)
能力值:
( LV2,RANK:10 )
在线值:
发帖
0
回帖
42
粉丝
1
关注
私信
需要渗透高手
4
楼
点个赞
2026-4-18 22:26
0
dbgbgtf
雪 币:
198
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
3
粉丝
0
关注
私信
dbgbgtf
5
楼
太强了,这方面有没有可用的项目试试呢?还有个问题是这种阻断需要针对模型吗?
2026-5-14 18:41
0
the_hs
雪 币:
2906
活跃值:
(2128)
能力值:
( LV6,RANK:90 )
在线值:
发帖
18
回帖
22
粉丝
52
关注
私信
the_hs
1
6
楼
dbgbgtf
太强了,这方面有没有可用的项目试试呢?还有个问题是这种阻断需要针对模型吗?
(才看到)
一般来说只要psanr足够低就不需要针对特定模型;项目的话学术性的偏多(因为还是要卡)
2026-7-19 21:56
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
the_hs
1
18
发帖
22
回帖
90
RANK
关注
私信
他的文章
[原创]wp:第八题:亥子合辰·塔影迷楼
22
[原创] wp: 第七题:戌时·暗能潜流
51
[原创]wp: 第二题:巳时·绿光幽语
32
[讨论]被kimi k3吓哭
345
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部