ImageMagick CLAHE 漏洞:无符号整数下溢与除零导致OOB内存访问与服务崩溃(DoS)

此安全公告详细披露了ImageMagick图像处理库中CLAHE功能的一个高危漏洞。该漏洞源于对瓦片宽度/高度为零的情况缺乏验证,可引发无符号整数下溢和除零错误,导致指针越界算术运算,进而可能造成内存损坏、进程崩溃和拒绝服务攻击。

ImageMagick CLAHE : 无符号整数下溢和除零导致指针越界算术运算与进程崩溃 (DoS)

漏洞概述

ImageMagick的CLAHE实现中存在一个根本原因——瓦片宽度或高度变为零——这导致了两种不同但相关的非安全行为。 漏洞存在于ImageMagick的MagickCore/enhance.c文件的CLAHEImage()函数中。

漏洞详情

无符号整数下溢 → 指针越界 (OOB)

  • 位置: MagickCore/enhance.c,大约第609行附近
  • 受测版本: 7.1.2-8 (本地ASan(undefined)/UBSan构建)
  • 漏洞代码 (enhance.c: 609):
    1
    
    p += (ptrdiff_t) clahe_info->width * (tile.height - 1);
    
  • 根本原因: 如果tile.height == 0,那么(tile.height - 1)会下溢至UINT_MAX。 与clahe_info->width相乘会产生一个接近SIZE_MAX的巨大数值。 将此值加到指针p上会导致指针算术运算下溢。

除零错误

  • 文件/位置: MagickCore/enhance.c,大约第669行附近
  • 受测版本: 7.1.2-8 (本地ASan(undefined)/UBSan构建)
  • 漏洞代码 (enhance.c: 669-673):
    1
    2
    3
    4
    5
    
     if ((image->columns % tile_info.width) != 0)
        tile_info.x=(ssize_t) (tile_info.width-(image->columns % tile_info.width));
      tile_info.y=0;
      if ((image->rows % tile_info.height) != 0)
        tile_info.y=(ssize_t) (tile_info.height-(image->rows % tile_info.height));
    
  • 根本原因: 在计算默认瓦片尺寸后缺少输入验证/边界检查: 如果tile_info.widthtile_info.height为0,就会触发除零错误。 零值可以通过以下途径到达此点:
    1. 精确瓦片设置: CLI参数-clahe 0x0! (!强制直接使用零值)。
    2. 小图像上的自动瓦片计算: 当请求的瓦片尺寸为0(没有!)时,代码会从图像尺寸推导出一个默认值(例如,dim >> 3)。对于尺寸小于8的图像,除非进行钳制,否则结果就是0。

复现步骤

无符号整数下溢

  • 环境: 启用了AddressSanitizer和UndefinedBehaviorSanitizer的构建。
    1
    2
    
    export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
    export ASAN_OPTIONS=abort_on_error=1:allocator_may_return_null=1:detect_leaks=0
    
  • 命令: ./magick xc:black -clahe 0x0 null:
  • 输出: 报告未定义行为错误,可能伴随内存区域损坏、进程内存消耗显著增加,最终可能导致崩溃(DoS)。

除零错误

  • 环境: ASan/UBSan启用的构建。
    1
    2
    
    export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
    export ASAN_OPTIONS=abort_on_error=1:allocator_may_return_null=1:detect_leaks=0
    
  • 命令: ./magick -size 16x2 gradient: -type TrueColor -depth 8 -clahe 0x0! null:
  • 输出: 触发除零错误,进程可能因未定义行为而终止(“Aborted”),造成拒绝服务。

影响

  • 主要影响: 拒绝服务——当通过CLI或API处理特制参数或极小的图像时,会导致进程崩溃或持续的资源耗尽(内存/缓存抖动)。攻击者可以通过-clahe 0x0!或向使用ImageMagick的服务上传极小图像来轻易触发。
  • 次要影响 (理论上的): 越界内存访问和内存损坏可能与其他漏洞结合导致更严重的后果;然而,仅凭这些PoC无法证明存在可靠的代码执行路径。

建议的补丁代码片段

CLAHEImage()函数中,计算tile_info之后,但在任何除法、取模或指针算术运算之前应用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
if (exact_tiles_requested && (tile_info.width == 0 || tile_info.height == 0)) {
  ThrowMagickException(exception, GetMagickModule(), OptionError,
                       "CLAHEInvalidTile", "%lux%lu",
                       (unsigned long) tile_info.width,
                       (unsigned long) tile_info.height);
  return (Image *) NULL;
}

if (!exact_tiles_requested) {
  tile_info.width  = (tile_info.width  == 0) ? MagickMax((size_t)1, image->columns >> 3) : tile_info.width;
  tile_info.height = (tile_info.height == 0) ? MagickMax((size_t)1, image->rows    >> 3) : tile_info.height;
}

if (tile_info.width == 0 || tile_info.height == 0) {
  ThrowMagickException(exception, GetMagickModule(), OptionError,
                       "CLAHEInvalidTile", "%lux%lu",
                       (unsigned long) tile_info.width,
                       (unsigned long) tile_info.height);
  return (Image *) NULL;
}

ssize_t tile_h_minus1 = (ssize_t)tile_info.height - 1;
if (tile_h_minus1 < 0) {
  ThrowMagickException(exception, GetMagickModule(), OptionError,
                       "CLAHEInvalidTile", "%lux%lu",
                       (unsigned long) tile_info.width,
                       (unsigned long) tile_info.height);
  return (Image *) NULL;
}
p += (ptrdiff_t) clahe_info->width * tile_h_minus1;

关于exact_tiles_requested的说明:如果CLI/Wand解析器已经暴露了!是否存在的标志,则使用它。如果没有,则添加一个解析时标志,以便CLAHEImage能够知道0是字面值还是自动计算值。

致谢

参考链接

受影响版本与包

此漏洞影响多个NuGet包,版本号小于等于14.9.0,目前暂无已修复版本。受影响的包包括但不限于:

  • Magick.NET-Q16-HDRI-OpenMP-arm64
  • Magick.NET-Q16-HDRI-OpenMP-x64
  • Magick.NET-Q16-HDRI-arm64
  • Magick.NET-Q16-HDRI-x64
  • …(及其他列出的Q16、Q8系列变体)

安全评分与弱点

  • CVSS 总体评分: 4.7 (中危)
  • CVSS v3 向量: CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:N/I:N/A:H
  • 相关弱点:
    • CWE-119: 内存缓冲区边界操作限制不当
    • CWE-191: 整数下溢(回绕)
    • CWE-369: 除零错误
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计