命令执行漏洞(Commnd Execution)总结

前言:
   这周来学习下命令执行漏洞;命令执行漏洞是用户通过浏览器在远程服务器上执行任意系统命令,与代码执行漏洞没有太大的区别,不过我们在学习时还是要区分不同的概念。关于代码执行漏洞会在下篇博客中详述。


一、什么是命令执行漏洞

应用 有时需要调用一些执行系统命令的函数,如PHP中的systemexecshell_execpassthrupopenproc_popen等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。

二、命令执行漏洞产生原因

  • 开发人员没有对特殊函数入口做过滤,导致用户可以提交恶意代码并提交服务端执行。
  • Web服务器没有过滤危险函数导致命令执行漏洞攻击成功。

三、PHP中的危险函数

system:成功则返回命令输出的最后一行,失败则返回FALSE。
exec:命令执行结果的最后一行内容。
shell_exec:命令执行的输出。如果执行过程中发生错误或者进程不产生输出,则返回NULL。
passthru:执行外部程序并且显示原始输出。
eval:将输入的字符串参数当做PHP程序代码来执行。
assert
preg_replace
call_user_func

四、命令执行漏洞的危害

  • 任意执行系统命令
  • 恶意木马被种植
  • 挂马、钓鱼
  • 敏感信息泄露

常用的命令连接符

在windows和linux都支持,如果程序没有进行过滤,那么我们可以通过连接符来执行多条命令。

A&&B   先执行A,执行成功后执行B,否则不执行B
A|B    只执行B
A&B    先执行A,不管是否成功,都会执行B
A;B    先执行A,再执行B
A&B    简单拼接,A B之间无制约关系

了解了这些知识后,下面就在本地搭建的DVWA中练习下。

DVWA—Command Injection(命令注入)

在这里插入图片描述
先从Low级别开始:
查看源码:

<?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>";
}
?>

可以看到,low级别的代码接收了用户输入的ip,服务器通过判断操作系统执行不同ping命令。但是这里对用户输入的ip并没有进行任何的过滤,所以存在可利用的命令执行漏洞。

&&来执行多条命令,构造payload:127.0.0.1&&net user
在这里插入图片描述
执行成功;(如果存在乱码问题,把DVWA\dvwa\includes目录下的dvwaPage.inc.php文件中所有的”charset=utf-8”,全部替换修改为”charset=gb2312”即可)

Medium

源码:

<?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>";
}
?> 

可以看到,medium级别相较于low级别的代码 只增加了对 &&的过滤,绕过也很简单,不用 && ,直接用 &不就好起来了吗!

&&&的区别在于&&是执行完前面的命令然后执行后面的命令,&是不管前面的命令是否值执行,后面的都执行。

构造poyload:127.0.0.1&ipconfig

在这里插入图片描述
绕过执行成功!

High

源码:

<?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>";
}
?> 

相比于前面两个等级的,high等级的黑名单更完善了,但是由我们可以看出来他只是过滤掉了“| ”,如果用|后不跟空格就可以绕过过滤。
构造payload:127.0.0.1|dir
在这里插入图片描述
绕过成功。

Impossible

源码:

<?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();
?> 

了解下几个函数:
stripslashes(string) : 该函数会删除字符串string中的反斜杠,返回已剥离反斜杠的字符串。

explode(separator,string,limit): 该函数把字符串打散为数组,返回字符串的数组。参数separator规定在哪里分割字符串,参数string是要分割的字符串,可选参数limit规定所返回的数组元素的数目。

is_numeric(string): 该检测string是否为数字或数字字符串,如果是返回TRUE,否则返回FALSE。

可以看到 Impossible级别的代码加入了Anti-CSRF token,至于什么是Anti-CSRF token请点击 链接 查看;同时对参数ip进行了严格的限制,只有诸如“数字.数字.数字.数字”的输入才会被接收执行,因此不存在命令注入漏洞。
好了,关于命令执行漏洞这次就先总结到这,下篇会更代码执行漏洞的知识。(●’◡’●)

参考博客:
https://blog.csdn.net/qq_36119192/article/details/82917250
https://blog.csdn.net/jpygx123/article/details/83276533

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章