别再复制粘贴 Stackoverflow 的内容了!🚨(+木马病毒源解决方案)
根据剑桥大学的 Nicholas Boucher 和 Ross Anderson最近的一项研究,有两个漏洞会影响大多数代码编译器。
这些类型的漏洞会对软件供应链产生影响;例如,如果攻击者通过欺骗人类审查者成功进行代码注入,则未来的软件可能会继承该漏洞。
但让我们看看这个技术:
-
扩展字符串:使字符串文字的各个部分看起来像代码,具有与注释相同的影响并导致字符串比较失败。
-
注释掉:强制注释以代码形式出现,然后被忽略。
-
提前返回:通过运行似乎位于注释内的返回语句来绕过函数。
接下来会发生什么?
编译器支持您看不到的这种独特代码,在编译您的应用程序时,它们会对其进行解释,并创建与您在 IDE 中看到的不同的编译应用程序。
木马源如何运作?
在这个例子中,我(Juan)将成为一名攻击者,想象一下我在 Devto 中发布了一个解决方案来教你如何做某事(例如:我教你如何检查用户是否是管理员)。
假设一个不同的场景,您或您的公司有一个开源项目。我帮助您开发其中的一些部分,并提交了一个拉取请求,其中包含我的贡献(我已设置了权限检查,确保某些操作只能由管理员执行,并且您已将我的代码添加到您的项目中)。
这里有一个例子:
string access_level = "user";
if (access_level != "user") //Check if admin
{
Console.WriteLine("You are an admin.");
}
漏洞在于此代码包含IDE 未显示的 Unicode 字符,让我们使用显示隐藏字符的文本编辑器来查看。
这些字符会改变你所看到的文本的位置、顺序、方向等等。所以,你所看到的并非它本来的样子。
您可以在此处阅读其工作原理。
好了,既然您已经接受或复制了我的代码,您的项目看起来如下所示:
显然一切都好,对吧?
让我们运行该应用程序:
但是...怎么办?
如果很access_level
明显"user"
我们正在比较它是否与So不同"user"
……
"user"
到底会有什么不同"user"
?
因为编译是在解释隐藏字符之后进行的。
让我们看看这个反编译的应用程序(IL代码):
正如我们在编译中看到的,代码表示如果:
"user" ≠ "user // check if admin"
管理员指令将被执行:
Console.WriteLine("You are an admin.");
显然这是可以实现的,并且会执行我们是管理员(尽管在源代码中我们看到的是相反的)。
我们来看看C#编译的结果:
与原版完全不同……(但你还没有意识到这一点,现在我要利用它来在你的应用程序上执行管理员的功能,尽管我没有)。
这个例子很简单,但我可以在生产中向你的应用程序注入一千条这样的指令,这是非常危险的。
如何解决?
幸运的是, Github等平台正在就此向用户发出警告:
我应该怎么办?
解释器、支持 unicode 的编译器和编译器管道必须针对字符串文字或注释中未终止的双向控制字符以及包含误导性混合脚本字符的标识符提供警告或错误。
语言要求应明确禁止注释和控制字符中未终止的双向字符串文字。
应在存储库界面和代码编辑器中使用视觉警告或符号突出显示混合脚本混淆字符和双向控制字符。
如何检查我是否受到此漏洞的影响?
Github开始通知我们这件事很好,但是……如果这件事已经发生在我们身上了怎么办?
思考我们团队可以采取什么解决方案时,我认为不是最好的,而是最简单的。
最后,漏洞是关于在我们的源代码中注入隐藏字符,对,让我们检查一下我们的源代码中是否有任何文件包含隐藏的内容。
由于您可能是一名 .NET 开发人员(您正在阅读 .NET 网络安全社区的文章),我们将在 .NET 中创建一个小工具,以在我们的项目中检查这个问题(猜猜是哪些?)是的! .NET。
出发啦🚀
✅解决方案
首先,让我们检查一下如何知道文件中是否有隐藏字符:
var nonRenderingCategories = new UnicodeCategory[] { UnicodeCategory.Control,
UnicodeCategory.OtherNotAssigned,
UnicodeCategory.Format,
UnicodeCategory.Surrogate };
我们在文件中使用了想要检测enum
的。Microsoft Docs 中提供了更多关于它们的信息。UnicodeCategory
我已经确定与此漏洞相关的 Unicode 字符类型为:
-
控制: Unicode 值为 U+007F,范围为 U+0000 到 U+001F 或 U+0080 到 U+009F。
-
OtherNotAssigned:未分配给任何 Unicode 类别的字符。
-
格式:影响文本布局或文本处理操作的格式字符,但通常不存在。
-
替代:低替代性或高替代性。
现在,我们唯一要做的就是读取一个 可以找到此漏洞的.cs
文件(C# 源代码文件):
var nonRenderingCategories = new UnicodeCategory[] {
UnicodeCategory.Control,
UnicodeCategory.OtherNotAssigned,
UnicodeCategory.Format,
UnicodeCategory.Surrogate };
using StreamReader sr = new StreamReader(dotnetFile);
while (sr.Peek() >= 0)
{
var c = (char)sr.Read();
var category = Char.GetUnicodeCategory(c);
var isPrintable = Char.IsWhiteSpace(c) ||
!nonRenderingCategories.Contains(category);
if (!isPrintable
{
alert(dotnetFile);
issuesCount++;
break;
}
}
sr.Close();
sr.Dispose();
如果文件包含其中一个字符,我们就会怀疑它。
由于我使用的字符类型范围不精确,因此如果文件包含以下内容,可能会产生误报:
-
其他字母表中的字符,例如阿拉伯语: ٣ففف 3 فففق
-
特殊字符,例如表情符号:🦄
这个解决方案并不完美,但它会警告您可能出现的问题,然后您可以评估文件是否存在漏洞。
该工具已完成并发布于:TrojanSourceDetector4Dotnet
该工具允许您扫描一个或多个 .NET 项目以查找此特定漏洞的问题。
由于我们 ByteHide 是开发人员,我们知道您的生活有多艰难,我们建议您通过控制台安装此工具,这样您无需执行任何事情,只需几秒钟即可检查所有项目。
只需打开CMD或Poweshell并输入:
dotnet tool install --global TrojanSourceDetector --version 1.0.1
现在,您可以随时扫描 .NET 项目所在的目录,为此使用:
TrojanSourceDetector
当它询问您目录时,请指明完整路径。
例如,将CMD放在存储库文件夹中并运行以下命令:
完成后,它会告诉您哪些文件可能包含可疑内容:
就是这样!
感谢https://www.trojansource.codes/
@article{boucher_trojansource_2021,
title = {Trojan {Source}: {Invisible} {Vulnerabilities}},
author = {Nicholas Boucher and Ross Anderson},
year = {2021},
journal = {Preprint},
eprint = {2111.00169},
archivePrefix = {arXiv},
primaryClass = {cs.CR},
url = {https://arxiv.org/abs/2111.00169}
}