
CVE-2024-32830을 이용한 파일 다운로드 PoC 코드
CVE-2024-32830로 파일을 다운로드하는 PoC 코드
getimagesize 우회getimagesize 제한을 우회하려면 PHP용 간단한 image/vnd.wap.wbmp 이미지를 만들 수 있습니다.
파일 유형에 대한 검사는 매우 간단합니다:
// https://github.com/php/php-src/blob/0029d2b08bbd3cb3aa293d9c8d55bf31faa9e203/ext/standard/image.c#L917
static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check)
{
int i, width = 0, height = 0;
if (php_stream_rewind(stream)) {
return 0;
}
/* get type */
if (php_stream_getc(stream) != 0) {
return 0;
}
/* skip header */
do {
i = php_stream_getc(stream);
if (i < 0) {
return 0;
}
} while (i & 0x80);
/* get width */
do {
i = php_stream_getc(stream);
if (i < 0) {
return 0;
}
width = (width << 7) | (i & 0x7f);
/* maximum valid width for wbmp (although 127 may be a more accurate one) */
if (width > 2048) {
return 0;
}
} while (i & 0x80);
/* get height */
do {
i = php_stream_getc(stream);
if (i < 0) {
return 0;
}
height = (height << 7) | (i & 0x7f);
/* maximum valid height for wbmp (although 127 may be a more accurate one) */
if (height > 2048) {
return 0;
}
} while (i & 0x80);
if (!height || !width) {
return 0;
}
if (!check) {
(*result)->width = width;
(*result)->height = height;
}
return IMAGE_FILETYPE_WBMP;
}
유효한 이미지를 구성하는 가장 간단한 방법은 두 개의 NUL 바이트 다음에 너비와 높이를 나타내는 두 개의 < 0x80 바이트를 붙이는 것입니다.
php://filter를 사용하면 모든 파일에 대해 이 작업을 수행할 수 있습니다.
첫 번째 레이어는 base64 인코딩을 적용하여 모든 데이터가 ASCII가 되도록 해야 하며, 이로써 < 0x80 제약 조건을 충족합니다.
두 번째 필터는 처음 두 개의 NUL 바이트를 추가해야 합니다. 이는 UTF-16BE에서 UTF-32BE로의 변환을 강제하여 가능합니다. 이렇게 하면 iconv가 2바이트 청크를 각각 유효한 UTF-16BE 문자로 해석하고, 그 앞에 두 개의 NUL 바이트를 추가하여 UTF-32BE로 만듭니다. 실제로 사용할 필터는 convert.iconv.utf-16be.utf-32be입니다.
최종 페이로드는 php://filter/convert.base64-encode/convert.iconv.utf-16be.utf-32be/resource=<file here>입니다.