2017年4月,安全研究员Xudong Zheng注册了一个特殊的域名。当他在Chrome浏览器地址栏输入这个域名时,显示的是"apple.com"——苹果公司的官方网址。但这个域名实际上与苹果公司毫无关系,它使用的是西里尔字母而非拉丁字母。整个互联网社区为之震惊:我们赖以信任的浏览器地址栏,竟然可以被一个字母欺骗。
这不是孤立的案例。根据USENIX Security 2021发表的研究论文,研究人员分析了3.47亿条DNS记录,发现了1,855个针对热门域名的同形字钓鱼域名。更令人担忧的是,即使是最安全的Chrome浏览器,也只能检测出其中64.1%的恶意域名;Firefox和Safari的检测率分别只有6.1%和9.7%。
问题的根源在于Unicode——这个包含超过15万个字符的编码系统。当互联网从ASCII时代迈向Unicode时代时,我们获得了支持全球语言的能力,却也打开了潘多拉的魔盒。
看不见的字符陷阱
Unicode 17.0标准定义了超过297,000个字符,覆盖154种书写系统。这些字符被组织成不同的"脚本"(Script),如拉丁文、西里尔文、希腊文、阿拉伯文、中文等。问题在于,不同脚本中存在大量视觉上完全相同或高度相似的字符。
最经典的例子是拉丁字母"a"(U+0061)和西里尔字母"а"(U+0430)。在绝大多数字体中,这两个字符看起来完全一样。但计算机把它们当作两个完全不同的字符——它们有不同的Unicode码点,在DNS解析中被视为不同的域名。
西里尔字母与拉丁字母的重叠并非偶然。历史上,西里尔字母从希腊字母演变而来,而拉丁字母同样源于希腊字母。三条演化路径产生了大量"同形字"(Homoglyphs)。根据Unicode技术标准UTS #39的数据,仅西里尔字母与拉丁字母之间就有超过20个常见的易混淆字符对:
| 拉丁字符 | Unicode | 西里尔字符 | Unicode | 希腊字符 | Unicode |
|---|---|---|---|---|---|
| a | U+0061 | а | U+0430 | α | U+03B1 |
| c | U+0063 | с | U+0441 | - | - |
| e | U+0065 | е | U+0435 | ε | U+03B5 |
| o | U+006F | о | U+043E | ο | U+03BF |
| p | U+0070 | р | U+0440 | ρ | U+03C1 |
| x | U+0078 | х | U+0445 | χ | U+03C7 |
| y | U+0079 | у | U+0443 | υ | U+03C5 |
这意味着,攻击者可以用西里尔字母"а"替换域名中的拉丁字母"a",创建一个视觉上完全相同的域名。例如,“apple.com"可以被伪造为"аррӏе.com”(全部使用西里尔字母),两个域名在屏幕上显示完全相同,却指向完全不同的服务器。
Punycode:双刃剑的诞生
国际化域名(Internationalized Domain Name, IDN)的设计初衷是善意的:让全球用户能够使用自己的母语访问互联网。2003年,IETF发布IDNA2003标准,随后在2010年更新为IDNA2008(RFC 5890-5894),为非ASCII字符在DNS中的使用铺平了道路。
DNS基础设施最初只支持ASCII字符(a-z, 0-9, 连字符)。为了让Unicode域名能够在现有DNS系统中工作,工程师们设计了Punycode编码。Punycode是一种将Unicode字符串转换为ASCII兼容编码(ACE)的算法,编码后的域名以"xn–“开头。
例如:
- “münchen.de” → “xn–mnchen-3ya.de”
- “短.co” → “xn–s7y.co”
- “аррӏе.com”(西里尔字母)→ “xn–80ak6aa92e.com”
当浏览器遇到一个IDN域名时,它会:
- 将域名分割成标签(以点分隔)
- 对每个标签应用Punycode解码
- 决定显示Unicode形式还是Punycode形式
关键的安全决策发生在第3步。浏览器必须判断:这个Unicode域名是否可疑?如果可疑,就显示原始的Punycode形式(如"xn–80ak6aa92e.com”),让用户能够识别出这不是他们想访问的域名。如果不可疑,则显示Unicode形式(如"münchen.de"),方便用户阅读。
问题在于:如何判断一个域名是否可疑?
浏览器的防御困境
2001年12月,Evgeniy Gabrilovich和Alex Gontmakher在论文《The Homograph Attack》中首次系统性地描述了这个问题。他们指出:“许多英文字母可能被同形伪造——通过用非拉丁字母替换来恶意拼写错误。”
这篇开创性的论文引发了浏览器厂商的警觉,但真正有效的防御机制却花了十多年时间才逐步建立。原因在于:防御同形字攻击需要在安全性和可用性之间进行艰难的权衡。
混合脚本检测
最常见的防御策略是禁止在同一域名标签中混合使用来自不同脚本的字符。例如,如果一个域名同时包含拉丁字母和西里尔字母,浏览器应该显示Punycode。
Chrome的实现最为严格。根据Chromium源码文档,Chrome禁止拉丁文、西里尔文和希腊文之间的任何混合。如果域名"аррӏе.com"同时使用了西里尔字母和拉丁字母(混合),Chrome会显示Punycode。
但这里存在一个致命的漏洞:全脚本同形字(Whole-script Confusable)。如果攻击者把域名中的所有拉丁字母都替换为对应的西里尔字母,就不会触发混合脚本检测——因为域名中只有一种脚本。
2017年,Xudong Zheng正是利用这个漏洞,注册了完全由西里尔字母组成的"аррӏе.com"。由于没有脚本混合,Chrome将其显示为Unicode形式,视觉上与真正的"apple.com"完全相同。这个漏洞后来在Chrome 58中修复。
骨架匹配算法
Chrome引入了另一种防御机制:骨架匹配(Skeleton Matching)。浏览器维护一个包含5001个热门域名的列表,当用户访问一个IDN域名时,Chrome会计算其"骨架"——将所有字符替换为其对应的ASCII原型,然后与热门域名列表进行比较。
Unicode技术标准UTS #39定义了"同形字检测"和"骨架映射"算法:
flowchart TD
A[输入字符串] --> B[NFD规范化]
B --> C[大小写折叠]
C --> D[同形字映射]
D --> E[再次NFD规范化]
E --> F[输出骨架]
如果IDN域名的骨架与某个热门域名匹配,Chrome会显示Punycode,并可能展示警告页面。例如,“gооglе.com”(使用西里尔字母)的骨架是"google.com",会触发保护机制。
但骨架匹配也有局限:它只覆盖5001个热门域名。针对不在列表中的域名(如某些政府网站.edu、.gov、.mil域名,或小众但敏感的网站),攻击者仍然可以成功实施同形字攻击。
浏览器差异:一场不对称战争
USENIX Security 2021的研究揭示了各大浏览器防御能力的巨大差异。研究人员使用9,519个测试用例对Chrome、Firefox、Safari、Edge等浏览器进行了系统性的黑盒测试:
| 浏览器 | 测试用例数 | 显示Unicode数量 | 失败率 |
|---|---|---|---|
| Chrome 81.0 | 9,519 | 1,963 | 20.62% |
| Firefox 75.0 | 9,519 | 4,233 | 44.46% |
| Safari 13.0 | 9,519 | 4,085 | 42.91% |
| Edge 81.0 | 9,519 | 1,963 | 20.62% |
Chrome的防御最为严格,但仍存在漏洞。研究发现了多种绕过Chrome防御的方法:
-
扩展同形字表攻击:使用UTS #39标准同形字表之外的同形字。Chrome使用的同形字表相对保守,攻击者可以使用更全面的同形字数据库来创建未被识别的钓鱼域名。
-
非热门域名攻击:针对不在Chrome热门域名列表中的网站。研究显示,针对.edu、.gov、.mil等域名的同形字攻击,Chrome的检测失败率高达40%。
-
拉丁扩展块攻击:使用拉丁字母扩展块中的字符。研究发现,当使用Latin Extended-A块中的字符构造钓鱼域名时,Chrome的失败率达到100%。
更令人担忧的是,研究发现Chrome在某些情况下甚至放宽了防御规则。2019年底,Chrome开始允许某些之前被阻止的同形字域名显示为Unicode,涉及Latin Extended-A、Latin Extended-B和Latin-1 Supplement等字符块。这一变化的官方原因不明,但研究人员推测可能是为了避免误伤合法的国际化域名。
Firefox的情况更为严峻。由于没有实现骨架匹配算法,Firefox对同形字攻击的防御完全依赖于混合脚本检测。对于全脚本同形字攻击,Firefox几乎没有防御能力。Mozilla的立场是:这个问题应该由域名注册商在注册阶段解决,而不是浏览器。
零宽字符:隐形攻击
同形字攻击还有一种更加隐蔽的变体:使用零宽字符(Zero-Width Characters)。Unicode定义了多个零宽字符,它们在屏幕上不可见,但在技术上会影响字符串的比较和存储。
常见的零宽字符包括:
- U+200B:零宽空格(Zero Width Space, ZWSP)
- U+200C:零宽非连接符(Zero Width Non-Joiner, ZWNJ)
- U+200D:零宽连接符(Zero Width Joiner, ZWJ)
- U+FEFF:字节顺序标记(Byte Order Mark, BOM)
攻击者可以在合法域名中插入零宽字符,创建一个视觉上完全相同但在技术上不同的域名。例如,“apple.com"和"app\x200ble.com”(中间插入零宽空格)看起来完全一样,但指向不同的服务器。
零宽字符攻击还可以与同形字攻击结合,绕过浏览器的防御机制。某些检测算法在处理零宽字符时会出现漏洞,导致恶意域名被误判为安全。
2026年1月,安全研究人员披露了一种利用IDN同形字攻击绕过多因素认证(MFA)的方法。攻击者通过注册一个与目标公司邮箱域名视觉相同的域名,然后在该域名的邮箱账户中使用与受害者相同的用户名,诱骗系统发送密码重置邮件到攻击者控制的邮箱。由于邮箱域名看起来完全一样,用户很难察觉自己正在与攻击者交互。
中文域名的特殊挑战
中文域名面临着独特的安全挑战。与西里尔字母和拉丁字母之间的一一对应不同,中文字符的同形问题更为复杂:
简繁体差异:同一个汉字的简体和繁体形式通常是不同的Unicode码点。例如,“中国”(简体)和"中國"(繁体)看起来非常相似,但在Unicode中是完全不同的字符。
异体字:某些汉字存在多个异体字形式,字形略有差异但意义相同。这些异体字可能是不同的Unicode码点,也可能是同一个码点的不同变体。
中日韩统一表意文字:CJK统一表意文字块将中文、日文、韩文中形状相同或相似的汉字映射到同一个码点。但某些汉字在不同语言中的标准写法存在细微差异,导致视觉混淆。
2025年8月发表的研究指出,攻击者可以利用中日韩字符之间的同形特性创建钓鱼域名。例如,日文汉字的某些写法与简体中文或繁体中文存在视觉差异,但可能指向相同的码点或极其相似的不同码点。
中文域名的另一个问题是输入法差异。用户通过不同输入法输入的同一个"字",可能在内部编码上存在差异,这为钓鱼攻击提供了额外的攻击面。
防御:多层次的安全策略
防御同形字攻击需要在多个层面建立防线。
域名注册层面的防御
ICANN早在2005年就发布了关于IDN同形字攻击的声明,承认随着IDN的普及,同形字域名欺骗的风险可能加剧。域名注册商是第一道防线。
许多顶级域名注册商实施了IDN表格(IDN Table)策略,明确规定哪些Unicode字符可以被用于注册。例如,某些注册商禁止在同一域名中混合使用拉丁字母和西里尔字母。
更先进的注册商实施了变体捆绑(Variant Bundling)机制:当某人注册一个域名时,所有视觉上相似的变体域名会被自动保留或捆绑在一起,防止其他人注册。例如,如果注册了"example.com",系统会自动阻止注册使用西里尔字母的变体。
Verisign在2020年获得了IDN同形字检测专利,该技术利用机器学习模型自动检测和预防恶意域名的注册。这代表了行业领先的安全实践。
企业品牌保护
对于企业和组织,主动的品牌保护至关重要:
防御性注册:主动注册品牌域名的常见同形字变体。虽然无法覆盖所有可能的变体,但可以阻止最常见的攻击向量。优先注册使用西里尔字母、希腊字母替换的变体。
域名监控服务:使用专业的品牌保护服务持续监控新域名注册。这些服务会应用骨架映射算法,当有人注册与你品牌同形的域名时发出警报。
证书透明性监控:监控证书透明性(Certificate Transparency, CT)日志。当攻击者为同形字域名申请SSL证书时,CT日志会记录这一事件,提供早期预警。值得注意的是,域名验证(DV)证书只验证申请者对域名的控制权,不会检查域名是否为同形字。这意味着攻击者可以轻松为钓鱼域名获取有效的SSL证书,浏览器地址栏会显示安全锁标志。
WHOIS监控:定期查询可能被攻击的同形字域名的WHOIS信息,监控其注册状态变化。
浏览器用户配置
浏览器用户可以采取主动措施增强防护:
Firefox用户:在地址栏输入about:config,将network.IDN_show_punycode设置为true。这会强制Firefox始终以Punycode形式显示IDN域名,虽然牺牲了可读性,但可以完全防御同形字攻击。
Chrome用户:Chrome 58及以后的版本对IDN显示进行了改进,但用户仍应保持浏览器更新以获得最新的防御规则。
安装安全扩展:某些浏览器扩展可以实时检测同形字域名并在链接上高亮显示可疑字符。
用户行为建议
无论技术防御多么完善,用户行为仍然是最后一道防线:
检查SSL证书:点击地址栏的锁图标,查看证书颁发给的域名是否正确。EV(扩展验证)证书会显示组织名称,提供更强的身份保证。
使用密码管理器:密码管理器会检查当前域名是否与保存的凭据匹配。如果域名是同形字,密码管理器不会自动填充密码,这可以作为额外的防御层。
谨慎处理链接:不要直接点击邮件或社交媒体中的链接,特别是涉及敏感账户时。手动输入网址或使用书签访问重要网站。
注意URL的完整显示:在移动设备上,地址栏可能只显示部分URL。点击地址栏查看完整的域名。
标准与规范的演进
Unicode联盟在UTS #39中定义了防御同形字攻击的技术基础。该标准定义了:
同形字检测(Confusable Detection):维护一个字符到其原型映射的表格,用于检测两个字符串是否视觉上相似。
混合脚本检测(Mixed-Script Detection):识别字符串中不恰当的脚本混合。
限制级别(Restriction Levels):定义了从ASCII-Only到Unrestricted的五个安全级别,不同应用场景可以应用不同的限制策略。
UTS #39的同形字表格是动态更新的,随着新发现的同形字对被添加到表格中。然而,浏览器和应用的实现往往滞后于标准的更新。
IDNA2008协议(RFC 5890-5894)为国际化域名定义了注册和查找的规则。与IDNA2003不同,IDNA2008不再使用Nameprep映射,而是定义了字符有效性类别(PVALID、DISALLOWED等),给予注册商更大的灵活性来实施本地策略。
未来展望:AI时代的攻防博弈
同形字攻击与防御的博弈正在进入新阶段。
攻击方的进化:人工智能可以自动生成最优的同形字组合,针对特定的检测算法进行优化。机器学习模型可以预测哪些同形字变体最有可能绕过特定浏览器的防御。
防御方的进化:同样的AI技术可以用于构建更智能的检测系统。基于机器学习的同形字检测模型可以识别传统规则无法覆盖的攻击模式。
新兴威胁向量:随着语音助手和QR码的普及,新的攻击面正在出现。QR码隐藏了实际的URL,用户无法在扫码前检查域名。语音输入域名时,同形字和正字听起来完全相同。
Unicode安全工作组持续更新UTS #39和相关标准,但标准的演进速度往往落后于威胁的演变。浏览器厂商、注册商、企业用户和个人用户需要协同努力,在多个层面构建纵深防御体系。
同形字攻击揭示了一个深刻的矛盾:互联网的国际化与安全性之间存在内在的张力。支持全球语言的代价是失去了ASCII时代的确定性——当"a"可以同时代表十几个不同脚本的字符时,我们再也无法通过简单的视觉检查来验证身份。
这不是一个可以通过单一技术方案解决的问题。它需要注册商在源头过滤可疑域名,浏览器在客户端实现智能检测,企业主动保护品牌资产,用户保持必要的警惕。只有当所有层面都发挥作用时,我们才能在享受互联网国际化便利的同时,抵御那些潜伏在字符编码深处的陷阱。
参考文献
-
Gabrilovich, E., & Gontmakher, A. (2002). The Homograph Attack. Communications of the ACM, 45(2), 128-129.
-
Unicode Consortium. (2024). UTS #39: Unicode Security Mechanisms (Version 16.0.0).
-
Hu, H., Jan, S. T. K., Wang, Y., & Wang, G. (2021). Assessing Browser-level Defense against IDN-based Phishing. USENIX Security Symposium.
-
Zheng, X. (2017). Phishing with Unicode Domains. https://www.xudongz.com/blog/2017/idn-phishing/
-
Klensin, J. (2010). RFC 5890: Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework. IETF.
-
Liu, B., et al. (2018). A Re-examination of Internationalized Domain Names: The Good, the Bad and the Ugly. IEEE DSN.
-
Suzuki, H., et al. (2019). ShamFinder: An Automated Framework for Detecting IDN Homographs. ACM IMC.
-
ICANN. (2005). ICANN Statement on IDN Homograph Attacks and Request for Public Comment.
-
Chiba, D., et al. (2019). DomainScouter: Understanding the Risks of Deceptive IDNs. RAID.
-
Costello, A. (2003). RFC 3492: Punycode: A Bootstring Encoding of Unicode for Internationalized Domain Names in Applications (IDNA). IETF.