Loading

DVWA(四):Command Injection 全等级命令注入

Command Injection :

  命令注入(Command Injection),对一些函数的参数没有做好过滤而导致用户可以控制输入的参数,使其恶意执行系统命令或这cmd、bash指令的一种注入攻击手段。php命令注入攻击漏洞是一种php应用程序常见的脚本漏洞。

  流程:

  1.判断是否可调用系统命令(权限问题)

  2.函数或函数的参数是否可控

  3.是否能拼接注入命令

  下面解释关于4个命令连接符(&&,&,||,|)

  1. &&:先执行command1,执行command1成功后可执行command2,否则不执行command2

   例如:command1 && command2

  2. &:先执行command1,不管是否成功都执行command2

   例如:command1 & command2

  3. ||:先执行command1,执行失败后执行command2

   例如:command1 || command2

  4. |:将command1的输出作为command2的输入,只打印command2执行结果

   例如:command1 | command2

  

Low等级:

  观察low级别源码:

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

?> 

这里解释几个php函数:

1.isset()

isset函数是检测变量是否设置。

格式:bool isset( mixed var [, mixed var [, ...]] )

返回值:

若变量不存在则返回FALSE

若变量存在且其值为NULL,也返回FALSE

若变量存在且值不为NULL,则返回TURE

同时检查多个变量时,每个单项都符号上一条要求时才返回TRUE,否则结果为FALSE

如果已经使用unset()释放了一个变量之后,它将不再是isset()。若使用isset()测试一个被设置成NULL的变量,将返回FALSE。同时要注意的是一个NULL字节("\0")并不等同于PHP的NULL常数。

 

2.stristr(string,search,before_search)

(1):string参数,必需,规定被搜索的字符串

(2):search参数,必需,规定要搜索的字符串,如果是数字则会匹配该数字在ascii码表中对应的字符

(3):before_search参数,可选,默认值为false,如果设置为true则返回search参数第一次出现之前的部分

返回值:返回从匹配点开始字符串的剩余部分,如果没有搜索到字符串,则返回false

  例如:返回值为 o world!,这里111对应的ascii字符为o,因为before_search为false所以返回的是匹配点开始之后的字符。

<?php
echo stristr("Hello world!",111);
?>

  例如:这次返回的就是hello,这里此函数不区分大小写。

<?php
echo stristr("Hello world!","WORLD",true);
?>

3.php_uname()函数

  string php_uname ([ string $mode = "a" ])

该函数会返回运行php的操作系统的相关描述,mode是单个字符,用于定义要返回什么信息。

'a':此为默认,包含s(操作系统名),n(主机名),r(版本名),v(版本信息),m(机器类型)里的所有模式

 

这里服务器通过判断操作系统执行不同的ping命令,但没对用户使用的参数做任何的过滤,严重的注入漏洞

例如输入:127.0.0.1 && net user  实现注入。

这里net user可以换成其他的命令,比如ipconfig(windows下)只要是在权限范围内的命令都可以使用

如果是Linux可以:127.0.0.1 && cat /etc/shadow

 

 

 

 

Medium等级:

 观察源代码:

  这里服务器对ip参数进行了过滤,即把&&和;删除,本质上采用的是黑名单机制,但依旧可以注入

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

?>

因为被过滤的只有&&和;所以可以使用&和|

 例如:127.0.0.1 & net user

或者用&;&代替&& 即:

 例如:127.0.0.1 &;& net user

Linux下可用cat /etc/shadow等等...

 

 

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

?>

相比Medium,进一步完善了黑名单,但依然可以绕过。

这里是把'| '转换为' ' (这里注意|后有空格),所以我们用|即可

输入:127.0.0.1|net user

 

posted @ 2020-03-08 23:58  Zh1z3ven  阅读(310)  评论(0编辑  收藏  举报