系统命令注入是常见的一类漏洞,攻击者可以绕过业务本身,在服务器上执行一个或多个系统命令。
在详细介绍命令注入之前,有一点需要注意:命令注入与远程代码执行不同。他们的区别在于,远程代码执行实际上是调用服务器网站代码进行执行,而命令注入则是调用操作系统命令进行执行。 虽然最终效果都会在目标机器执行操,但是他们还是有区别的,基于这个区别,我们如何找到并利用方式也是有所不同的。
DVWA中命令注入分四个等级, 分别是low、middle、high、impossible
Low:
正常输入ip地址结果如下
首先查看源代码: 可以看出代码中没有对输入做校验: 也就是说可以使用一些特殊字符执行命令注入(&、&&、|、||、 ; )
1 <?php 2 3 if( isset( $_POST[ ‘Submit‘ ] ) ) { 4 // Get input 5 // 根据请求获取ip值, 但没有对输入做任何校验 6 $target = $_REQUEST[ ‘ip‘ ]; 7 8 // Determine OS and execute the ping command. 9 // 区分windows系统和linux或unix 10 if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) { 11 // Windows 12 $cmd = shell_exec( ‘ping ‘ . $target ); 13 } 14 else { 15 // *nix 16 $cmd = shell_exec( ‘ping -c 4 ‘ . $target ); 17 } 18 19 // Feedback for the end user 20 // 前端显示返回值 21 echo "<pre>{$cmd}</pre>"; 22 } 23 ?>
例如输入:fsdfas || net user(前一个命令执行失败就会执行后一个)
Middle:
首先查看源码有什么变动: 添加了字符串替换,将&&和;替换为空。 但是没有完全过滤,黑名单校验
1 <?php 2 3 if( isset( $_POST[ ‘Submit‘ ] ) ) { 4 // Get input 5 // 根据请求获取ip值, 6 $target = $_REQUEST[ ‘ip‘ ]; 7 8 // Set blacklist 9 // 指定需要过滤的字符串, 过滤&&和; 10 $substitutions = array( 11 ‘&&‘ => ‘‘, 12 ‘;‘ => ‘‘, 13 ); 14 15 // Remove any of the charactars in the array (blacklist). 16 // 替换字符串-->将输入字符中&&和;替换为空 17 $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 18 19 // Determine OS and execute the ping command. 20 if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) { 21 // Windows 22 $cmd = shell_exec( ‘ping ‘ . $target ); 23 } 24 else { 25 // *nix 26 $cmd = shell_exec( ‘ping -c 4 ‘ . $target ); 27 } 28 29 // Feedback for the end user 30 echo "<pre>{$cmd}</pre>"; 31 } 32 33 ?>
使用其他字符串同样可以完成 命令注入: 例如 127.0.0.1&net user
High:
首先查看源码有什么变动: 源码中对进行过滤,但|后过滤存在问题,多了一个空格。黑名单校验。
1 <?php 2 3 if( isset( $_POST[ ‘Submit‘ ] ) ) { 4 // Get input 5 // 根据请求获取ip值, 但没有对输入做任何校验 6 $target = $_REQUEST[ ‘ip‘ ]; 7 8 // Determine OS and execute the ping command. 9 // 区分windows系统和linux或unix 10 if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) { 11 // Windows 12 $cmd = shell_exec( ‘ping ‘ . $target ); 13 } 14 else { 15 // *nix 16 $cmd = shell_exec( ‘ping -c 4 ‘ . $target ); 17 } 18 19 // Feedback for the end user 20 // 前端显示返回值 21 echo "<pre>{$cmd}</pre>"; 22 } 23 24 ?> 25 26 27 28 <?php 29 30 if( isset( $_POST[ ‘Submit‘ ] ) ) { 31 // Get input 32 // 根据请求获取ip值, 33 $target = $_REQUEST[ ‘ip‘ ]; 34 35 // Set blacklist 36 // 指定需要过滤的字符串, 过滤&&和; 37 $substitutions = array( 38 ‘&&‘ => ‘‘, 39 ‘;‘ => ‘‘, 40 ); 41 42 // Remove any of the charactars in the array (blacklist). 43 // 替换字符串-->将输入字符中&&和;替换为空 44 $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 45 46 // Determine OS and execute the ping command. 47 if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) { 48 // Windows 49 $cmd = shell_exec( ‘ping ‘ . $target ); 50 } 51 else { 52 // *nix 53 $cmd = shell_exec( ‘ping -c 4 ‘ . $target ); 54 } 55 56 // Feedback for the end user 57 echo "<pre>{$cmd}</pre>"; 58 } 59 60 ?> 61 62 63 <?php 64 65 if( isset( $_POST[ ‘Submit‘ ] ) ) { 66 // Get input 67 $target = trim($_REQUEST[ ‘ip‘ ]); 68 69 // Set blacklist 70 // 源码中对进行过滤,但|后过滤存在问题,多了一个空格 71 $substitutions = array( 72 ‘&‘ => ‘‘, 73 ‘;‘ => ‘‘, 74 ‘| ‘ => ‘‘, 75 ‘-‘ => ‘‘, 76 ‘$‘ => ‘‘, 77 ‘(‘ => ‘‘, 78 ‘)‘ => ‘‘, 79 ‘`‘ => ‘‘, 80 ‘||‘ => ‘‘, 81 ); 82 83 // Remove any of the charactars in the array (blacklist). 84 // 字符替换为空 85 $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 86 87 // Determine OS and execute the ping command. 88 if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) { 89 // Windows 90 $cmd = shell_exec( ‘ping ‘ . $target ); 91 } 92 else { 93 // *nix 94 $cmd = shell_exec( ‘ping -c 4 ‘ . $target ); 95 } 96 97 // Feedback for the end user 98 echo "<pre>{$cmd}</pre>"; 99 } 100 101 ?>
使用|可以完成命令注入(后不能带空格): 例如 fsdfas|type c:\aaa.txt,查看c盘文件内容
Impossible:
对输入内容做了 1、token校验; 2、严格校验ip格式,保证ip一定范围合法(没有校验单个数字字符大小(0-255)),其他输入将被视为不合法,也就是做了白名单校验。
1 <?php 2 3 if( isset( $_POST[ ‘Submit‘ ] ) ) { 4 // Check Anti-CSRF token 5 // 校验了token值 6 checkToken( $_REQUEST[ ‘user_token‘ ], $_SESSION[ ‘session_token‘ ], ‘index.php‘ ); 7 8 // Get input 9 $target = $_REQUEST[ ‘ip‘ ]; 10 $target = stripslashes( $target ); 11 12 // Split the IP into 4 octects 13 // ip以点做字符分割 14 $octet = explode( ".", $target ); 15 16 // Check IF each octet is an integer 17 // 校验每个字符是数字类型 18 if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) { 19 // If all 4 octets are int‘s put the IP back together. 20 // 在将4个数字字符组合成ip地址 21 $target = $octet[0] . ‘.‘ . $octet[1] . ‘.‘ . $octet[2] . ‘.‘ . $octet[3]; 22 23 // Determine OS and execute the ping command. 24 if( stristr( php_uname( ‘s‘ ), ‘Windows NT‘ ) ) { 25 // Windows 26 $cmd = shell_exec( ‘ping ‘ . $target ); 27 } 28 else { 29 // *nix 30 $cmd = shell_exec( ‘ping -c 4 ‘ . $target ); 31 } 32 33 // Feedback for the end user 34 echo "<pre>{$cmd}</pre>"; 35 } 36 else { 37 // Ops. Let the user name theres a mistake 38 echo ‘<pre>ERROR: You have entered an invalid IP.</pre>‘; 39 } 40 } 41 42 // Generate Anti-CSRF token 生成token值 43 generateSessionToken(); 44 45 ?>
原文:https://www.cnblogs.com/perilong16/p/12906813.html