博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CVE-2016-3078 PHP zip module command excute
阅读量:6182 次
发布时间:2019-06-21

本文共 4889 字,大约阅读时间需要 16 分钟。

hot3.png

Description:------------An integer wrap may occur in PHP 7.x when reading zip files with thegetFromindex() and getFromName() methods of ZipArchive, resulting in aheap overflow.php-7.0.5/ext/zip/php_zip.c,----| 2679 static void php_zip_get_from(INTERNAL_FUNCTION_PARAMETERS, int type) /* {
{
{ */| 2680 {| ....| 2684 struct zip_stat sb;| ....| 2689 zend_long len = 0;| ....| 2692 zend_string *buffer;| ....| 2702 if (type == 1) {| 2703 if (zend_parse_parameters(ZEND_NUM_ARGS(), "P|ll", &filename, &len, &flags) == FAILURE) {| 2704 return;| 2705 }| 2706 PHP_ZIP_STAT_PATH(intern, ZSTR_VAL(filename), ZSTR_LEN(filename), flags, sb); // (1)| 2707 } else {| 2708 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|ll", &index, &len, &flags) == FAILURE) {| 2709 return;| 2710 }| 2711 PHP_ZIP_STAT_INDEX(intern, index, 0, sb); // (1)| 2712 }| ....| 2718 if (len < 1) {| 2719 len = sb.size;| 2720 }| ....| 2731 buffer = zend_string_alloc(len, 0); // (2)| 2732 n = zip_fread(zf, ZSTR_VAL(buffer), ZSTR_LEN(buffer)); // (3)| ....| 2742 }`----With `sb.size' from (1) being:php-7.0.5/ext/zip/lib/zip_stat_index.c,----| 038 ZIP_EXTERN int| 039 zip_stat_index(zip_t *za, zip_uint64_t index, zip_flags_t flags,| 040 zip_stat_t *st)| 041 {| ...| 043 zip_dirent_t *de;| 044| 045 if ((de=_zip_get_dirent(za, index, flags, NULL)) == NULL)| 046 return -1;| ...| 063 st->size = de->uncomp_size;| ...| 086 }`----Both `size' and `uncomp_size' are unsigned 64bit integers:php-7.0.5/ext/zip/lib/zipint.h,----| 339 struct zip_dirent {| ...| 351 zip_uint64_t uncomp_size; /* (cl) size of uncompressed data */| ...| 332 };`----php-7.0.5/ext/zip/lib/zip.h,----| 279 struct zip_stat {| ...| 283 zip_uint64_t size; /* size of file (uncompressed) */| ...| 290 };`----Whereas `len' is signed and has a platform-dependent size:php-7.0.5/Zend/zend_long.h,----| 028 #if defined(__x86_64__) || defined(__LP64__) || defined(_LP64) || defined(_WIN64)| 029 # define ZEND_ENABLE_ZVAL_LONG64 1| 030 #endif| ...| 033 #ifdef ZEND_ENABLE_ZVAL_LONG64| 034 typedef int64_t zend_long;| ...| 043 #else| 044 typedef int32_t zend_long;| ...| 053 #endif`----Uncompressed file sizes in zip-archives may be specified as either 32-or 64bit values; with the latter requiring that the size be specified inthe extra field in zip64 mode.Anyway, as for the invocation of `zend_string_alloc()' in (2):php-7.0.5/Zend/zend_string.h,----| 119 static zend_always_inline zend_string *zend_string_alloc(size_t len, int persistent)| 120 {| 121 zend_string *ret = (zend_string *)pemalloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(len)), persistent); // (4)| ...| 133 ZSTR_LEN(ret) = len; // (5)| 134 return ret;| 135 }`----The `size' argument to the `pemalloc' macro is aligned/adjusted in (4)whilst the *original* value of `len' is stored as the size of theallocated buffer in (5). No boundary checking is done in (4) and it maythus wrap, which would lead to a heap overflow during the invocation of`zip_fread()' in (3) as the `toread' argument is `ZSTR_LEN(buffer)':php-7.0.5/Zend/zend_string.h,----| 041 #define ZSTR_LEN(zstr) (zstr)->len`----On a 32bit system:,----| (gdb) p/x ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(0xfffffffe))| $1 = 0x10`----The wraparound may also occur on 64bit systems with `uncomp_size'specified in the extra field (Zip64 mode; ext/zip/lib/zip_dirent.c:463).However, it won't result in a buffer overflow because of `zip_fread()'bailing on a size that would have wrapped the allocation in (4):php-7.0.5/ext/zip/lib/zip_fread.c,----| 038 ZIP_EXTERN zip_int64_t| 039 zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread)| 040 {| ...| 049 if (toread > ZIP_INT64_MAX) {| 050 zip_error_set(&zf->error, ZIP_ER_INVAL, 0);| 051 return -1;| 052 }| ...| 063 }`----php-7.0.5/ext/zip/lib/zipconf.h,----| 130 #define ZIP_INT64_MAX 0x7fffffffffffffffLL`----,----| (gdb) p/x ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(0xffffffffffffffff))| $1 = 0x18| (gdb) p/x ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(0x7fffffffffffffff))| $2 = 0x8000000000000018`----Test script:---------------CVE-2016-3078.py: upload.php: Actual result:--------------On a 32bit machine running Arch Linux with php-fpm 7.0.5 behind nginx:,----| $ python CVE-2016-3078.py --bind-port 5555 | [*] this may take a while| [*] 103 of 4096 (0x67fd0)...| [+] connected to 1.2.3.4:5555| id| uid=33(http) gid=33(http) groups=33(http)| | uname -a| Linux tmparch 4.4.5-1-ARCH #1 SMP PREEMPT Thu Mar 10 07:54:30 CET| 2016 i686 GNU/Linux| | pacman -Qs php-fpm| local/php-fpm 7.0.5-1| FastCGI Process Manager for PHP`------ Hans Jerry Illikainen

 

poc link:

转载于:https://my.oschina.net/u/2393235/blog/676248

你可能感兴趣的文章
eclipse生成jar包
查看>>
今年全家福流行这样拍 华为手机的花式姿势上央视了
查看>>
从内到外无懈可击,努比亚Z17让你一见钟情!
查看>>
滴滴:按原计划恢复深夜出行服务 新版上线一键报警功能
查看>>
十年磨一剑 企业级互联网架构Aliware助力企业数字化转型
查看>>
一箱农村垃圾的“重生之旅”
查看>>
合江长江公路大桥飞燕式系杆拱桥首节主拱成功吊装
查看>>
【PWA学习与实践】(9)生产环境中PWA实践的问题与解决方案
查看>>
RecyclerView的复用机制
查看>>
机器学习之牛顿法
查看>>
在Ubuntu上使用MySQL设置远程数据库优化站点性能
查看>>
鹅厂优文|主播pk,如何实现无缝切换?
查看>>
编写基于PHP扩展库的后门
查看>>
TIOBE 6 月编程语言排行榜:Java 放缓,C 复兴了!
查看>>
Android Handler机制之Message及Message回收机制
查看>>
JSON vs Js
查看>>
css居中
查看>>
谈谈分享邀请奖励机制(附iOS实现代码)
查看>>
多隆:淘宝第一行代码撰写者的程序世界
查看>>
【刷算法】翻转单链表的递归和非递归方法
查看>>