IT学习网 - 爱学习 - 最具影响力综合资讯网站 -- 中国IT界的领航者!
热门关键字:      88888  as  xxx
站外
广告
站外
广告

PHP7.0.0格式化字符串漏洞与EIP劫持分析

发布时间:2016-10-15 08:20文章来源:互联网文章作者: 佚名点击次数:
PHP7.0.0的这个格式化字符串漏洞是15年12月在exploit-db上发现的。当初发现时,笔者还在北京东北方向的某信息安全公司上班,那时比较忙,并未能深入探究。最近几天无意间又看到了这个漏洞,发现该漏洞多了一个CVE编号:CVE-2015-8617,于是深入地看了看这个

PHP7.0.0的这个格式化字符串漏洞是15年12月在exploit-db上发现的。当初发现时,笔者还在北京东北方向的某信息安全公司上班,那时比较忙,并未能深入探究。最近几天无意间又看到了这个漏洞,发现该漏洞多了一个CVE编号:CVE-2015-8617,于是深入地看了看这个漏洞,在这里对该格式化字符串漏洞进行一些简要分析,并讨论一下利用该漏洞劫持EIP的潜在方法,供各位读者参考。

1.引言

在PHP中有两个常见的格式化字符串函数,分别是sppintf()和vsppintf(),它们分别对应sprintf()函数和vsprintf()函数,这两个函数的声明为:

PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...);

PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap);

通过其函数声明可以看到,spprintf()接收可变数量的参数,而vspprintf()仅接收4个参数。

虽然这两个函数的内部实现原理是类似的,但笔者不打算就此点进行深入讨论,如有感兴趣读者,可以看一看《程序员的自我修养》一书。关于格式化字符串漏洞的分析文章普遍集中于sprintf()函数,而在本文中则需要重点讨论一下vsprintf()函数,即着重讨论下PHP中的vspprintf()函数。

2.漏洞分析

本文所研究的vspprintf()函数在zend_throw_error()函数中,当触发漏洞时,zend_throw_error()函数由zend_throw_or_error()函数调用。zend_throw_or_error()函数不是很长,所以复制其代码如下:

static void zend_throw_or_error(int fetch_type, zend_class_entry *exception_ce, const char *format, ...)

{ va_list va; char *message = NULL; va_start(va, format); zend_vspprintf(&message, 0, format, va); if (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) { zend_throw_error(exception_ce, message); //vul_func //zend_throw_error(exception_ce, "%s", message); patched in the subsequent version } else { zend_error(E_ERROR, "%s", message); } efree(message); va_end(va); }

在上述代码段中,触发漏洞的函数调用已用红色笔标明出,由于调用时少了一个参数导致触发了格式化字符串漏洞。该漏洞的补丁也用红色笔在代码中标明了。

关于该格式化字符串漏洞,并没有很多需要分析说明的地方,下面开始分别从windows和linux两个环境中讨论利用该漏洞劫持EIP的方法。

3.windows环境下分析

为了减少在win7环境下的分析难度,笔者暂且把ASLR关掉。若计划实现稳定的EIP劫持,可能还需要通过其他手段获取一些模块基址,当然这PHP7.0.0格式化字符串漏洞本身也可以泄露一部分有用的内存数据。

在windows版本的PHP中,其漏洞函数位于php7ts.dll动态链接库中,构造php页面如下:

$name="%n%n"; $name::doSomething(); ?>

通过调试器启动PHP解析该php页面,执行到程序崩溃时,通过栈回溯,可以找到vspprintf()函数调用(该函数是导出函数,也可以直接在导出表中找到此函数),在该函数的函数头下断点,重新执行,找到即将触发漏洞的某次调用。此时,观察栈中的数据:

\

上图中,栈顶是函数返回地址,即返回到zend_throw_error()函数中,接下来的是vspprintf()函数的四个参数。其中,0441E890即为va_list类型的参数。

这里需要指出的是,如果是传统的spprintf()函数的格式化字符串溢出,则只需要不断地利用%x递增栈上参数数量,最后利用%n实现覆盖函数返回地址即可有效地实现劫持EIP。但是此处是vspprintf()函数的,只接受4个参数,所以如果打算继续劫持EIP,则需要研究一下va_list,va_list在不同环境下的定义略有不同,这里我们可以粗略地定义va_list类型如下:
PHP7.0.0格式化字符串漏洞与EIP劫持分析
本文由 IT学习网 整理,转载请注明“转自IT学习网”,并附上链接。
原文链接:http://www.ourlove520.com/Article/diannao/wangluo/510961.html

标签分类:

上一篇:上一篇:Kali-linux下创建wifi热点(wifi绵羊墙搭建)
下一篇: 下一篇:NSA后门可让攻击者轻松解密HTTPS、VPN加密流量
无觅关联推荐,快速提升流量