什么是命令注入?  
  #  什么是命令注入? 
命令注入就是在需要输入数据的地方输入了恶意代码,而且系统并没有对其进行过滤或者其他处理导致恶意代码也被执行,最终导致数据泄露或者正常数据被破坏。
#  常用到的命令 
(总结来说就是系统操作命令 DOS 命令都可以在此执行试试)
 
ipconfig,net user(查看系统用户),dir(查看当前目录),find(查找包含指定字符的行),whoami(查看系统当前有效用户名)A&B(简单的拼接,AB 之间无制约关系),A&&B(A 执行成功才会执行 B),A|B(A 的输出作为 B 的输入),A||B(A 执行失败,然后才会执行 B)
#  Low 
#  分析 
根据提示,我们先随便输入一个 IP 提交下试试。
下面出现了 PING 的过程 
如果你熟悉 linux 的操作的话你一定知道有些语法可以让你在一行内运行多条命令:
;  
 分号,没有任何逻辑关系的连接符。当多个命令用分号连接时,各命令之间的执行成功与否彼此没有任何影响,都会一条一条执行下去。 
||  
 逻辑或,当用此连接符连接多个命令时,前面的命令执行成功,则后面的命令不会执行。前面的命令执行失败,后面的命令才会执行。 
&&  
 逻辑与,当用此连接符连接多个命令时,前面的命令执行成功,才会执行后面的命令,前面的命令执行失败,后面的命令不会执行,与 || 正好相反。 
|  
 管道符,当用此连接符连接多个命令时,前面命令执行的正确输出,会交给后面的命令继续处理。若前面的命令执行失败,则会报错,若后面的命令无法处理前面命令的输出,也会报错。 
 
我们使用任意一条构建 payload:
 
发现已经注入成功了..
#  查看源代码 
点我展开 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php if ( isset ( $_POST [ 'Submit'  ]  ) ) {         $target  = $_REQUEST [ 'ip'  ];          if ( stristr ( php_uname ( 's'  ), 'Windows NT'  ) ) {                  $cmd  = shell_exec ( 'ping  '  . $target  );     }     else  {                  $cmd  = shell_exec ( 'ping  -c 4 '  . $target  );     }          echo  "<pre>{$cmd} </pre>" ; } ?> 
 
我们可以发现初级并没有使用任何字符过滤,这也就导致了命令注入的成功执行。。。
#  Medium 
我们直接使用刚才的 payload 试试:
竟然直接成功了。。。 
我们看看源代码
点我展开 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 <?php if ( isset ( $_POST [ 'Submit'  ]  ) ) {         $target  = $_REQUEST [ 'ip'  ];          $substitutions  = array (         '&&'  => '' ,         ';'   => '' ,     );          $target  = str_replace ( array_keys ( $substitutions  ), $substitutions , $target  );          if ( stristr ( php_uname ( 's'  ), 'Windows NT'  ) ) {                  $cmd  = shell_exec ( 'ping  '  . $target  );     }     else  {                  $cmd  = shell_exec ( 'ping  -c 4 '  . $target  );     }          echo  "<pre>{$cmd} </pre>" ; } ?> 
 
他只是单纯的加了 &&  和 ;  的过滤。。。
#  High 
按照惯例,我们继续使用老的 payload 试试:
并没有输出。。
我们直接看看源代码
点我展开 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 34 35 36 37 <?php if ( isset ( $_POST [ 'Submit'  ]  ) ) {         $target  = trim ($_REQUEST [ 'ip'  ]);          $substitutions  = array (         '&'   => '' ,         ';'   => '' ,         '| '  => '' ,         '-'   => '' ,         '$'   => '' ,         '('   => '' ,         ')'   => '' ,         '`'   => '' ,         '||'  => '' ,     );          $target  = str_replace ( array_keys ( $substitutions  ), $substitutions , $target  );          if ( stristr ( php_uname ( 's'  ), 'Windows NT'  ) ) {                  $cmd  = shell_exec ( 'ping  '  . $target  );     }     else  {                  $cmd  = shell_exec ( 'ping  -c 4 '  . $target  );     }          echo  "<pre>{$cmd} </pre>" ; } ?> 
 
发现好多都被匹配到了,我们别慌
构造 payload
 
发现已经可以了。
为什么可以成功执行呢?
我们看看他匹配的部分,前后都没有空格,而我们构造的有空格,所以就没有匹配上。。。
#  impossible 
最后一关了,每每到这一关是不是心情大好,因为这一关就是告诉你怎么防御这些漏洞的。
点我展开 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 34 35 36 37 38 39 40 41 <?php if ( isset ( $_POST [ 'Submit'  ]  ) ) {         checkToken ( $_REQUEST [ 'user_token'  ], $_SESSION [ 'session_token'  ], 'index.php'  );          $target  = $_REQUEST [ 'ip'  ];     $target  = stripslashes ( $target  );          $octet  = explode ( "." , $target  );          if ( ( is_numeric ( $octet [0 ] ) ) && ( is_numeric ( $octet [1 ] ) ) && ( is_numeric ( $octet [2 ] ) ) && ( is_numeric ( $octet [3 ] ) ) && ( sizeof ( $octet  ) == 4  ) ) {                  $target  = $octet [0 ] . '.'  . $octet [1 ] . '.'  . $octet [2 ] . '.'  . $octet [3 ];                  if ( stristr ( php_uname ( 's'  ), 'Windows NT'  ) ) {                          $cmd  = shell_exec ( 'ping  '  . $target  );         }         else  {                          $cmd  = shell_exec ( 'ping  -c 4 '  . $target  );         }                  echo  "<pre>{$cmd} </pre>" ;     }     else  {                  echo  '<pre>ERROR: You have entered an invalid IP.</pre>' ;     } } generateSessionToken ();?> 
 
查看源代码我们发现了问题
程序使用了正则匹配的方式来禁止输入其他字符,这样我们就没法使用 linux 命令的特性来攻击了。
同时也设置了 token,这个是用来防止 CSRF 的,后面我会提到。
至此,关于命令注入的就全部结束了,DVWA 上面确实很简单。