看起来一样,实际不同 - 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 栏中域名是否正确的习惯。
相关术语
常见问题
同形异义攻击利用了 Unicode 的什么特性?
利用字形相似但码位不同这一特性。拉丁字母 a 是 U+0061,西里尔字母 а 是 U+0430;域名要先转换成 Punycode 再解析,因此只要差一个字符,看起来相同的地址也会指向另一台服务器。
什么是零宽字符?
屏幕上不显示的Unicode字符。但会影响字符串比较和哈希计算,因此被滥用于密码混入、机密文档水印、源代码篡改等。
浏览器能防御同形异义攻击吗?
主流浏览器会把混用多种文字体系的域名以 Punycode 形式显示。但整个标签只用一种文字体系写成的拼法 (UTS #39 所称的 whole-script confusable) 不满足这一条件,因此浏览器还会一并判断它与知名域名的相似程度。不要完全相信屏幕上显示的名称,逐字核对拼写才是最后的防线。