上一篇文章中,对命令注入进行了简单的分析,有兴趣的能够去看一看,文章地址 http://www.javashuo.com/article/p-sjhzgzod-dw.html,今天这篇文章以DVWA的Command Injection(命令注入)模块为例进行演示与分析,本地搭建DVWA程序能够看这篇文章 https://www.cnblogs.com/lxfweb/p/12678463.html,经过对DVWA不一样等级的代码分析,看看它是如何作的防护。php
首先查看low级别的核心代码html
<?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>"; } ?>
能够发现上面的代码,用了stristr(),php_uname(),函数,这是用来判断当前的系统是不是Windows,由于Windows和Linux下的ping命令执行参数是不一样的。接下来是用shell_exec函数来执行ping命令,并将结果输出。咱们发现low级别的代码,对用户的输入没有作任何的过滤。存在很大的安全隐患。例如使用管道符“|”查看当前端口,输入下列内容前端
127.0.0.1|netstat -ano
结果以下图web
这里不止可使用“|”,在DOS下容许同时执行多条命令的符号主要有如下几个shell
能够用链接符直接接net user zhangsan 123/add 建立用户 接着链接提权命令 net localgroup administrators zhangsan /add 拿下整个服务器安全
如今看一下,中级别的核心代码,看一看增长了哪些防护服务器
<?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>"; } ?>
咱们发现,中级的代码,对参数作了一点过滤,把&&和;删除,至关于黑名单的形式,在Linux中;也能够起链接做用,依次执行多个命令。咱们能够尝试| || & &;& ,这里以||举例,||前面报错,后面执行我们构造的命令,结果以下图session
如今查看高级别的核心代码函数
<?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>"; } ?>
高级别的代码对黑名单进行了进一步完善,好像过滤了全部危险字符,仔细观察黑名单里“|”管道符,后面有一个空格“| ” 这样能够尝试“ |” 发现成功绕过,结果以下图spa
查看核心代码
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(); ?>
经过查看Impossible级别的代码加入了Anti-CSRF token,而且采用白名单的方式,对参数ip进行了严格的限制,只接受X.X.X.X(X只能为数字),所以不存在命令执行漏洞。