1.low
查看后端代码
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);
}
// Feedbackforthe end user
echo"
{$cmd}
";
}
?>
相关函数介绍:
stristr(string,search,before_search)
stristr
函数搜索字符串(string)在另一字符串(search)第一次出现,返回字符串的剩余部分(从匹配点),如果未搜索字符串,则返回FALSE。参数string是搜索的子符串,search是参数(如果该参数是数字,则搜索该数字对应的ASCLL只的字符)
php_unname(mode)
返回运行php的操作系统的相关描述,参数mode可取值"a"(此为默认,包含序列“s,n,r,v,m"里的所有模式),"s" (返回操作系统的名称),"n" (返回主机名),"r"(返回版本名称),”r"(返回版本信息),"m"(返回机器类型)
漏洞利用
未对输入ip做处理
windows下输入 127.0.0.1&&net user
&&来执行多条命令
2.Medium
if( isset( $_POST['Submit'] ) ) {
//Get input
$target = $_REQUEST['ip'];
//Set blacklist
$substitutions = array(
'&&'=>'',
';'=>'',
);
//Remove any of the charactarsinthe array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
//Determine OSandexecute 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 "
{$cmd}
";
}
过滤了“&&”和“;",所以"&"不会受影响
(1)输入127.0.0.1&net user
这里说明一下"&&"和"&"的区别:
command 1&&command 2
先执行command 1,执行成功后执行command 2,否则不执行command 2.
command 1&command 2
先执行command 1,不管是否成功,都会执行command 2
3.High
if( isset( $_POST['Submit'] ) ) {
//Get input
$target = trim($_REQUEST['ip']);
//Set blacklist
$substitutions = array(
'&'=>'',
';'=>'',
'| '=>'', //注意这里
'-'=>'',
'$'=>'',
'('=>'',
')'=>'',
'`'=>'',
'||'=>'',
);
//Remove any of the charactarsinthe array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
//Determine OSandexecute 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 "
{$cmd}";
}
?>
基本上过滤了所有的非法字符,但发现"| "(注意这里有空格)替换为空字符,所有没有过滤"|"
输入127.0.0.1|net user
command 1 | command 2
"|" 是管道符,表示将command 1 的输出作为command2 的输入,并且只打印command2执行的结果
4.impossible
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 into4octects
$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 all4octets 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 -c4' . $target );
}
// Feedback for the end user
echo "
{$cmd}";
}
else {
// Ops. Let the user name theres a mistake
echo '
ERROR:You have entered an invalid IP.';
}
}
// Generate Anti-CSRF token
stripslashes(string)
stripslashes函数会删除字符串string中的反斜杠,返回以剥离反斜杠的字符串。
explode(separator,string,limit)
把字符串打散为数组,返回字符串的数组。以separator为元素进行分离,string为分离的字符串,可选参数limit规定所返回的数组元素的数目。
is_numeric(string)
检测string是否为数字字符串,如果是返回TRUE,否则返回FALSE。
impossible级别的代码加入了Anti-CSRF token,同时对参数IP进行了严格的限制,只允许"数字.数字.数字."的输入才会被接收执行,因此不存在命令注入漏洞