如何获取谷歌新闻API密钥(分步指南)
.NET命令注入:示例及预防
这篇文章将以一些基础知识开头:您将了解什么是命令注入、它的工作原理以及它为什么很危险。然后我们将进入文章中与 .NET 相关的部分。您将看到 .NET 命令注入攻击的示例以及您作为开发人员可以采取哪些措施来防止这些攻击。
让我们开始吧。
要求
如果你想跟着本教程一起学习,你需要
- 安装 .NET SDK(我推荐 6.0 版本),
- 至少熟悉 C# 和 .NET,并且
- 代码编辑器或 IDE。
我将使用Visual Studio Code,如果您也使用相同的代码,那么跟随操作将会稍微容易一些。
此外,请记住,当我撰写本指南时,我是在 Windows 上撰写的。如果您使用的是 OS X 或 Linux,请对我将展示的命令进行必要的调整。
.NET 命令注入:基础知识
正如承诺的那样,让我们从命令注入的最基础的部分开始。
什么是命令注入?
命令注入,顾名思义,是一种代码注入攻击。一般来说,注入攻击是利用应用程序中的某些漏洞注入一些恶意代码,这些代码会干扰应用程序的正常行为。最著名的注入攻击类型可以说是SQL 注入。
命令注入也称为操作系统命令注入。在这种攻击中,恶意行为者能够在服务器运行的操作系统上注入并执行命令。
为什么命令注入很危险?
成功的命令注入可能会带来灾难性的后果。能够在您的服务器上运行任意命令的攻击者可能会执行以下操作:
- 访问、更改或删除文件和目录;
- 读取敏感的客户信息;
- 提取敏感信息并将其发送到外部服务器;
- 访问当前正在执行的进程列表并终止其中一个或多个进程;
- 从而导致重要的服务和应用程序瘫痪。
命令注入如何工作?
与其他类型的注入攻击一样,操作系统命令注入利用了无法正确处理用户输入的应用程序。一般来说,这种攻击的工作原理是“诱骗”应用程序接受看似无害的字符串,然后将该文本字符串连接到要运行的命令。
连接的结果是一个恶意命令,它会根据攻击者的设计改变应用程序的原始行为。
.NET 命令注入:来看一个例子
让我们看一个实际中命令注入的简单例子。
创建示例应用程序
我们将首先创建一个新的 .NET MVC 应用程序:
dotnet new mvc -o injection-demo
然后,让我们使用 VS Code 打开项目:
cd injection-demo
code .
打开项目后,转到Controllers文件夹并在其中添加一个新文件:
将新文件命名为ReportController。将以下代码粘贴到其中:
using Microsoft.AspNetCore.Mvc;
namespace injection_demo.Controllers;
public class ReportController : Controller
{
private readonly ILogger<ReportController> _logger;
private readonly IWebHostEnvironment _environment;
public ReportController(
ILogger<ReportController> logger,
IWebHostEnvironment environment)
{
_logger = logger;
_environment = environment;
}
public IActionResult Generate(string? id)
{
ViewData["Client"] = id;
var process = new System.Diagnostics.Process();
var startInfo = new System.Diagnostics.ProcessStartInfo();
var contentPath = _environment.ContentRootPath;
var filePath = System.IO.Path.Combine(contentPath, id);
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/C echo teste > {filePath}";
process.StartInfo = startInfo;
process.Start();
if (process == null)
{
return StatusCode(500);
}
else
{
process.WaitForExit();
return View();
}
}
}
接下来,转到“Views”并添加一个新文件夹:
将文件夹命名为Report并在其中创建一个名为Generate.cshtml的文件。在其中添加以下文本:
@{
ViewData["Title"] = "Report";
}
<div class="text-center">
<h1 class="display-4">Report for the client @ViewData["Client"]</h1>
</div>
运行示例应用程序
现在我们可以运行此应用程序了。如果您已将VS Code 配置为调试,只需按 F5。否则,请转到您的终端并执行dotnet run。
无论你如何操作,你都应该能够访问https://localhost:7168/并实时查看应用程序:
要测试该应用,请转到地址栏并将/report/generate/<SOME-NAME>附加到地址。当然,将<SOME-NAME>替换为实际名称。例如,您的名称。然后按 Enter。这是我使用我的名字执行此操作后看到的内容:
完成此操作后,转到项目文件夹,您将看到一个带有您名称的文件:
这证明命令执行成功。但是命令注入呢?
利用应用程序
此示例应用程序处理用户输入的方式相当简单。它只是接受任何输入并将其连接到由底层操作系统执行的命令。
一般来说,你不应该盲目相信来自应用外部的任何信息。这包括
- 来自网络表单的数据,
- URL 参数,以及
- 从 POST/PUT/PATCH 请求到 API 端点的数据。
为了演示此应用程序的可利用性,你只需执行一个非常简单的测试。在应用程序运行时,将以下内容附加到地址栏内容:
&& dir > out.txt
然后再次运行该应用程序。这是我在浏览器中看到的内容:
这可能看起来像是一个无害的结果。不过,不要自欺欺人。转到项目的文件夹,您将在那里看到一个名为out.txt的文件:
没错!您刚刚添加的额外文本导致执行了第二条命令。更具体地说,执行了dir命令,然后将其输出传输到新文件中。打开该文件,其内容应如下所示:
如何防止 .NET 命令注入
正如您所见,我们创建的愚蠢示例应用程序根本无法防范命令注入。我们执行的“攻击”相当温和,但在现实世界中,此类事件可能会造成严重后果。
那么,您可以做些什么来防止此类攻击?最好的方法就是不要从您的 Web 应用程序运行操作系统命令。通常有比直接运行命令更好的替代方案(例如,作业调度)。
如果您确实需要运行命令,请不要盲目信任用户输入。使用正则表达式或允许列表验证收到的数据,以仅允许合法值。
另外,不要忘记利用您可能拥有的任何工具。例如,.NET 提供了许多有用的静态安全分析规则。其中之一 — CA3006 — 是关于命令注入的。不要停用这些规则。更好的方法是配置您的项目,使其发出编译器错误而不是仅仅发出警告。
.NET 命令注入:了解它们并保护你的应用程序免受其侵害
流行文化将黑客的典型形象刻画在我们所有人的脑海中。事实证明,现实世界中的漏洞利用要平常得多,而且通常是由于开发人员在保护其应用程序时不够勤勉而发生的。在众多漏洞利用中,代码注入攻击是最著名的攻击之一。在其子类型中,我们可以列举 SQL 注入和命令注入。这篇文章是关于前者的。
在这篇文章中,我们为您提供了 .NET 命令注入的入门指南。您已经了解了操作系统命令注入、它们对应用程序造成的危险以及如何应对它们。