HTML表格伪造二维码需通过DOM结构识别:匹配≥30行×≥30列的table,td含黑白背景色、无文本/链接/图片、父容器无语义标签;其URL需结合诱导文案、JS跳转逻辑及注释中的混淆字符串推断。

如何识别 HTML 表格伪造的二维码
纯 HTML 表格绘制的二维码在邮件或网页中无法被传统 OCR 或图像扫描引擎捕获,但对安全审计人员来说,它暴露在 DOM 结构里——只要遍历到足够深的 <table> + <tr> + <td> 嵌套层级,且单元格具备高密度黑白背景色分布,就值得标记为可疑。
实操建议如下:
- 优先匹配
<table>元素下连续出现 ≥30 行<tr>,每行含 ≥30 个<td>的结构(对应 QR Code Version 2+) - 检查每个
<td>的style属性是否含background、bgcolor或background-color,且值集中为#000000/#ffffff/black/white - 忽略
width和height值小于 6px 的单元格(过小则无法被扫码工具识别,大概率非恶意) - 若表格内无文本、无链接、无图片,且父容器无语义化标签(如
<figure>或<aside>),风险权重应上调
为什么不能只靠 img 标签检测二维码
很多自动化审计脚本只扫描 <img> 标签并提取 src,但这在当前钓鱼手法下完全失效。攻击者已将二维码从“资源”转为“结构”,绕过所有基于图像加载、OCR 解析或 MIME 类型过滤的检测逻辑。
关键差异在于:
立即学习“前端免费学习笔记(深入)”;
-
<img src="qrcode.png">会触发 HTTP 请求,可被代理/网关拦截;而 HTML 表格是静态内联渲染,不发请求 - 邮件客户端(如 Outlook Web)默认禁用远程图片,但允许执行内联 CSS 背景色;表格二维码因此始终可见
- 沙箱环境若只做静态 HTML 解析而不模拟渲染,根本看不到二维码图案,更无法提取其中编码的 URL
如何从表格中还原隐藏的跳转 URL
HTML 表格本身不包含 URL,但其视觉图案可被扫码工具识别——这意味着 URL 实际藏在生成该表格的后端逻辑里。审计时无法直接“解码”表格,但可通过上下文推断其恶意载荷。
重点关注以下线索:
- 检查页面中是否存在 JavaScript 动态拼接的
location.href或window.open(),参数是否来自某个隐藏<input>或data-属性 - 查找紧邻表格的诱导性文字,例如 “扫码确认账户状态” —— 这类文案常与域名
lidoustoo[.]click或tmp.arpa子域配合使用 - 观察 URL 参数是否含
$符号后接邮箱格式(如$user@domain.com),这是动态绑定收件人的典型特征 - 若页面源码中存在注释块(
<!-- ... -->)包含十六进制字符串或 Base32 片段,极可能为混淆后的目标 URL
容易被忽略的渲染兼容性陷阱
表格二维码在桌面浏览器中可能显示为拉伸、模糊或错位,导致人工审计时误判为“排版错误”。但它在移动端 WebView(如微信内置浏览器、iOS Mail)中往往能正确渲染并被识别——这正是攻击者选择该手法的核心原因。
审计时必须模拟真实终端环境:
- 用 Chrome DevTools 切换至 iPhone SE / Android Pixel 尺寸,并启用 “Disable cache” 和 “Network Throttling: Fast 3G”
- 禁用所有扩展和广告拦截器,避免 CSS 注入干扰原始布局
- 特别注意
table { border-collapse: collapse; }是否被重置,否则单元格间距会导致扫码失败,攻击者通常会显式设置cellspacing="0" cellpadding="0" - 若发现
<meta name="viewport">缺失或initial-scale=1.0被篡改,需额外警惕——这是为了让二维码在小屏上占据更大面积
最危险的情况,是表格嵌套在 <noscript> 块里,同时页面又加载了混淆的 JS 脚本用于 fallback 渲染。这种组合会让多数静态扫描器直接跳过分析。



















