漏洞与攻击无处不在。最近,剑桥大学的两位研究人员发现了一个可以影响计算机代码编译器和软件开发环境的漏洞——Trojan Source(木马源) 。该漏洞几乎影响所有计算机语言,包括对 C、C++、C#、JavaScript、Java、Rust、Go 和 Python 。
此外,恶意代码可以将 Trojan Source 用于供应链攻击。
- 论文地址:https://trojansource.codes/trojan-source.pdf
- GitHub 地址:https://github.com/nickboucher/trojan-source
Trojan Source 攻击方法利用的是字符编码标准 Unicode ,有以下两种攻击方式:
- 第一种是通过 Unicode 的 Bidi 算法(CVE-2021-42574),该算法处理从左到右(如英语)和从右到左(如阿拉伯语和希伯来语)脚本显示顺序。该漏洞允许对字符进行视觉上的重新排序,使其呈现与编译器和解释器所不同的逻辑顺序;
- 第二种是同源攻击 (CVE-2021-42694),两个不同的字符具有相似的视觉表示,例如拉丁语 H 和西里尔字母Н。
研究人员表示如果攻击者通过逃过人类审阅成功地将目标漏洞提交到开源代码中,下游软件可能会继承该漏洞。在 GitHub 上的存储库中,他们提供了概念验证 (PoC) 脚本。
Trojan-Source 攻击
字符重新排序方式
Unicode 标准规定,内存表示顺序称为逻辑顺序,当文本在一行的时候,大多数脚本从左往右显示字符(例如英语)。然而,也有一些脚本(如阿拉伯语或希伯来语)显示文本的自然顺序是从右往左。当混合具有不同显示顺序的脚本时,必须有一种确定性的方法来解决方向冲突。对于 Unicode 来说,双向或 Bidi 算法可以实现。
某些场景下,Bidi 算法设置的默认排序可能不够。对于这些情况,Bidi 算法提供覆盖控制字符(override control characters)。Bidi 算法覆盖是不可见的字符,从而可以切换字符组的显示顺序。
例如,考虑以下 Unicode 字符序列:RLI a b c PDI,那么将显示为:c b a。
下表 I 提供了与此攻击相关的控制符列表:
隔离重新排序方式
在 Bidi 规范中,隔离(isolates)是被视为单个实体的字符组;也就是说,当显示顺序被重写时,整个一组字符将作为单个块移动,隔离可以嵌套。
假设 Unicode 字符为:RLI LRI 4 5 6 PDI LRI 1 2 3 PDI PDI,那么将显示为:1 2 3 4 5 6。
相互嵌入多层 LRI 和 RLI,可以近乎任意地重新排序字符串。那么攻击者就可以将杂乱的字符,经过这种方式,将自己想要的功能插入到当前的开源项目中,让用户下载后执行,从而在不知情的情况下来执行漏洞代码。
语法依从性
大多数设计良好的编程语言不允许在源代码中使用任意控制字符,因为它们被视为影响逻辑的 token。因此,在源代码中随机放置 Bidi 覆盖字符通常会导致编译器或解释器语法错误。为了避免这种错误,我们可以利用编程语言的以下两个原则:
- 注释:大多数编程语言都允许编译器和解释器忽略所有文本(包括控制符)注释;
- 字符串:许多编程语言允许字符串可以包含任意字符,同理也包括控制符。
虽然注释和字符串都具有指示其开始和结束的特定于语法的语义,但 Bidi 覆盖不遵守这些界限。因此,通过将 Bidi 覆盖字符专门放置在注释和字符串中,我们能够以大多数编译器可接受的方式将它们注入到源代码中。
示例展示
如下图所示,通过任意控制符改变了代码逻辑。下列代码中的 if 条件没有执行,而是被放置在注释部分,程序显示效果起到了欺骗用户的作用。
研究人员还展示了如何在 C++ 中执行同源文字攻击。他们使用了两个看起来相似但实际上不同的 H,蓝色的拉丁语 H 和红色的西里尔字母Н。当进行编译时,该程序输出文本「Goodbye, World!」。
加强防御
这样的攻击可能很难检测,因为经过渲染的源代码看起来非常完美。如果逻辑上的变化足够微小,以至于后续测试中未被发现,那么攻击者可能会在不被发现的情况下引入有针对性的漏洞。
同样令人担忧的是,Bidi 覆盖字符通过复制、粘贴操作,仍然存在于浏览器、编辑器和操作系统上。
「开发者将代码从不受信任的来源复制到受保护的代码库中,这种做法可能无意中引入了一个不可见漏洞,」剑桥大学计算机安全教授、该研究的合著者 Anderson 表示。「这种代码复制是现实世界安全漏洞的重要来源。」
约翰霍普金斯信息安全研究所的副教授 Matthew Green 表示,「剑桥研究清楚地表明,大多数编译器都可以被 Unicode 欺骗,以不同于研究者预期的方式处理代码。」
好消息是,研究人员进行了广泛的漏洞扫描,还没有人利用这一漏洞。坏消息是目前还没有防御措施,将来可能会有人利用该漏洞进行一些破坏。
Green 表示:希望编译器和代码编辑器开发人员能够快速修补这个漏洞!但由于有些人不定期更新他们的开发工具,至少在一段时间内会有一些风险。
图源:XKCD.com/2347/
加州大学伯克利分校计算机科学系的讲师 Nicholas Weaver 表示,剑桥提出了一组非常简单、优雅的攻击,可能会使供应链攻击变得更加严重。
人类已经很难从源代码中区分「this is OK、this is evil」,Weaver 表示。对于这种攻击,你可以使用改变方向来改变注释和字符串的呈现方式,例如「This is okay」只是一种呈现形式,但「This is」okay 才是它在代码中的存在方式。幸运的是,它有一个非常容易扫描的标记,因此编译器在将来遇到它时可以「检测」它。
研究人员表示,软件公司在最初披露期间,提供了 99 天的禁锢期,以允许通过软件更新修复受影响的产品。
研究人员写道:「我们收到了各种各样的回应,包括修补承诺、Bug 赏金计划、快速驳回等。在我们与之合作的 19 家软件供应商中,有 7 家使用外包平台接收漏洞披露,6 家拥有专门的漏洞披露门户网站,4 家通过 PGP 加密电子邮件接受披露,另外两家仅通过非 PGP 电子邮件接受披露。他们都确认收到了我们的披露,最终 9 家承诺发布补丁。」
此外,还有 11 家接受者有 Bug 赏金计划,为漏洞披露提供报酬。但研究人员报告说,只有 5 家支付赏金,平均支付 2,246 美元。
Anderson 表示,「到目前为止大约有一半的组织已经承诺提供补丁,而其他组织还在拖延。我们将接下来将监控他们的部署,还希望 GitHub、Gitlab 、 Atlassian 采取行动。」
参考链接:
https://krebsonsecurity.com/2021/11/trojan-source-bug-threatens-the-security-of-all-code/http://cn-sec.com/archives/609155.htmlhttp://cn-sec.com/archives/609155.html
【本文是51CTO专栏机构“机器之心”的原创译文,微信公众号“机器之心( id: almosthuman2014)”】