看起来一样,实际不同 - Unicode 的视觉攻击

apple.comаpple.com 在你看来一样吗?它们实际上是不同的。第二个 URL 中的第一个"а"不是拉丁字母"a",而是西里尔字母"а" (U+0430)。人眼无法区分,但对计算机来说它们是完全不同的字符,因此是不同的域名。

Unicode 是一个能够统一处理世界各地字符的革命性系统,但其丰富的字符集也带来了安全威胁。

同形异义词攻击 - 如何创建假域名

同形异义词攻击 (IDN 同形异义词攻击) 使用看起来相同 (或非常相似) 的不同字符创建假域名。

  • 拉丁字母"a" (U+0061) 和西里尔字母"а" (U+0430)
  • 拉丁字母"o" (U+006F) 和西里尔字母"о" (U+043E)
  • 拉丁字母"p" (U+0070) 和西里尔字母"р" (U+0440)
  • 拉丁字母"e" (U+0065) 和西里尔字母"е" (U+0435)

组合这些字符,你可以创建 аррle.com (开头的「а」和两个「р」是西里尔字母),一个在视觉上与 apple.com 无法区分的域名。用作钓鱼网站 URL,即使是谨慎的用户也可能被欺骗。

浏览器对策

主流浏览器通过将混合脚本 (多种书写系统) 的域名显示为 Punycode 表示法来对抗同形异义词攻击。上面的 аррle.com 混用了西里尔字母和拉丁字母,因此地址栏会显示成 xn--le-6kc8da.com,伪装一眼即破。

不过,西里尔字母的帕拉奇卡 (U+04CF) 与拉丁字母「l」极为相似,攻击者可以借它把整个标签都写成西里尔字母 (аррӏе.com = xn--80ak6aa92e.com)。Unicode 技术标准 UTS #39 把这种形态称为 whole-script confusable,它不触发混合脚本这一条件,因此浏览器还须叠加其他判断,例如对与知名域名高度相似的单一脚本标签也显示 Punycode。

不可见字符 - 零宽字符的威胁

Unicode 包含几个不在屏幕上显示的"零宽字符"。

  • U+200B:零宽空格
  • U+200C:零宽非连接符
  • U+200D:零宽连接符
  • U+FEFF:零宽不换行空格 (BOM)

这些字符不可见但会影响字符串比较和哈希计算。

  • 水印:在机密文档中嵌入零宽字符以识别泄漏者的技术。通过为每个接收者插入不同模式的零宽字符,可以从泄漏文档中的模式识别泄漏者
  • 密码问题:复制粘贴密码时,如果包含零宽字符,就会出现"正确的密码无法登录"的情况
  • 代码篡改:制造看起来相同但行为不同的源代码。2021 年公布的 Trojan Source (CVE-2021-42574) 是这一手法的代表,其核心是下一节介绍的方向控制字符,零宽字符和同形字符则作为变种使用

方向控制字符 - 操纵文本流向

Unicode 包含控制文本显示方向的字符。由于阿拉伯语和希伯来语是从右到左书写的,这些控制字符有合法用途,但也可以被利用进行攻击。

  • U+202E:从右到左覆盖。强制所有后续文本从右到左显示

例如,文件名 document_‮fdp.exe 在屏幕上显示为 document_exe.pdf。用户以为是 PDF 文件并双击,但实际上是 .exe 文件 (可执行文件)。

开发者应注意什么

  • 接受用户输入时,清理 (删除) 零宽字符和方向控制字符
  • 验证域名时,转换为 Punycode 后再比较
  • 显示文件名时,删除或转义方向控制字符
  • 代码审查时,使用工具检测零宽字符注入 (例如 grep -P '[\x{200B}-\x{200F}\x{202A}-\x{202E}]')

总结

Unicode 是一个能够统一处理世界各地字符的卓越系统,但其丰富性也带来了安全威胁。同形异义词攻击、零宽字符、方向控制字符,了解这些威胁可以提高你对钓鱼网站 URL 和可疑文件名的警惕性。访问 IP 确认时,养成验证 URL 栏中域名是否正确的习惯。

相关术语

钓鱼 使用同形异义词攻击创建假域名来冒充合法网站的技术。 DNS 国际化域名 (IDN) 被转换为 Punycode 并通过 DNS 解析。 HTTPS 即使是假域名也可以获得 TLS 证书,因此仅有 HTTPS 不能保证安全。 IP 地址 不同的域名指向不同的 IP 地址。同形异义词攻击的假域名指向不同的 IP。

常见问题

同形异义攻击利用了 Unicode 的什么特性?

利用字形相似但码位不同这一特性。拉丁字母 a 是 U+0061,西里尔字母 а 是 U+0430;域名要先转换成 Punycode 再解析,因此只要差一个字符,看起来相同的地址也会指向另一台服务器。

什么是零宽字符?

屏幕上不显示的Unicode字符。但会影响字符串比较和哈希计算,因此被滥用于密码混入、机密文档水印、源代码篡改等。

浏览器能防御同形异义攻击吗?

主流浏览器会把混用多种文字体系的域名以 Punycode 形式显示。但整个标签只用一种文字体系写成的拼法 (UTS #39 所称的 whole-script confusable) 不满足这一条件,因此浏览器还会一并判断它与知名域名的相似程度。不要完全相信屏幕上显示的名称,逐字核对拼写才是最后的防线。