@TOC
概念
当应用需要调用一些外部程序时会用到一些系统命令的函数。应用在调用这些函数执行系统命令的时候,如果将用户的输入作为系统命令的参数拼接到命令行中,在没有过滤用户的输入情况下,会造成命令执行漏洞。
DVWA
low
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?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>"; }
?>
|
没有任何防御,直接127.0.0.1&&net user
medium
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>"; }
?>
|
对&&和;进行了过滤,可以使用&
这里要注意&&与&的区别:
Command 1&&Command 2,先执行Command 1,执行成功后执行Command 2,否则不执行Command 2而Command 1&Command 2
先执行Command 1,不管是否成功,都会执行Command 2
high
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>"; }
?>
|
high过滤比较全面,可以使用|,“|”是管道符,表示将Command 1的输出作为Command 2的输入,并且只打印Command 2执行的结果
127.0.0.1|net user
相关函数
1、system():能够将字符串作为OS命令执行,自带输出功能。(这是解释下OS:os是operating system的缩写,表示操作系统,它是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理与配置内存、决定系统资源工序的优先次序、控制输入设备与输出设备、操作网络与管理文件系统等基本事务。)
2、exec():能够将字符串作为OS命令执行,需要输出执行结果。返回结果是有限的,shell_exec()比较常用。
3、stristr(string,search,before_search)
)stristr函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回 FALSE。
防御方法
1、尽量减少命令执行函数的使用,并在disable_functions 中禁用
2、在进入命令执行的函数或方法之前,对参数进行过滤
3、值尽量使用引号包裹,并在拼接之前调用add slashes 进行转义