阅读:3654回复:0
WordPress 3.5.1远程代码执行EXP
from:Remote Code Execution exploit in WordPress 3.5.1
(ps:老外也有几分标题党的意思,虽然是wordpress本身留下的坑,但是目前的利用还是需要安装的插件踩到了这个坑,才会被利用成功,并且要进入后台……感谢horseluke帮忙测试并翻译EXP与总结部分。) ◆0 背景 之前,在http://vagosec.org/2013/09/wordpress-php-object-injection/发表了WordPress中php对象注入的漏洞,那时候考虑到影响,没有讲解如何利用该漏洞,现在已经过去了三个月的时间,网站管理员应该都已经更新的WordPress,现在觉得可以公开了。 之前对这个漏洞不太了解的可以先看一下drops之前翻译的文章: WordPress < 3.6.1 PHP 对象注入漏洞 ◆1 如何寻找 看完以前的那个文章之后,会发现有三种方法可能被利用 __destruct()__wakeup()__toString()但是在WordPress本身的类当中没有找到可以成功利用的点。 但这是否意味着该漏洞不可利用呢,当然不是,WordPress最流行的功能就是允许安装插件和模板。这个是有第三方开发的,在写这篇文章时,WordPress列出了28358个插件,有超过5.6亿次的下载,这些插件有着各式各样的功能。包括有2155个主题,下载量超过八千六百万。 然后我就开始在最流行的插件当中寻找那些可以成功利用该漏洞的。 在寻找了几个插件之后,我终于找到一个插件的类中,在__toString()方法中是可利用的了。 这个插件就是Lightbox plus ColorBox。 ◆2 分析详情 Lightbox plus ColorBox插件的/classes/shd.class.php文件中的simple_html_dom_node类,其中代码如下: #!phpclass simple_html_dom_node { private $dom = null; function __toString() { return $this->outertext(); } function outertext() { // … if ($this->dom && $this->dom->callback!==null) { call_user_func_array($this->dom->callback, array($this)); } // … }}熟悉PHP的朋友一看到call_user_func_array函数,就知道这是一个可能存在问题的点。 不熟悉PHP的可以来看下PHP手册http://www.php.net/function.call-user-func-array 为什么会对这个类的定义感兴趣呢?因为我们可以控制simple_html_dom_node对象的所有属性,我们可以设置dom属性为任意值,如果传入一个callback属性的话,有意思的事情就发生了。 利用call_user_func_array函数,我们可以调用任何函数,并且可以传递第一个参数进去。我不是PHP专家,没有发现利用办法,我又回过头看WordPress本身的代码,发现在/wp-admin/includes/screen.php文件中,这个文件定义了一个WP_Screen的类,当用user-meta数据被反序列化时,是被包含的,类的代码如下: #!phpfinal class WP_Screen { private $_help_tabs = array(); public function get_help_tabs() { return $this->_help_tabs; } public function render_screen_meta() { // … foreach ( $this->get_help_tabs() as $tab ): if ( ! empty( $tab['callback'] ) ) call_user_func_array( $tab['callback'], array( $this, $tab ) ); endforeach; // … }}就像我之前提到过的,我们能够调用任意的函数,这包括类当中的方法,能够调用WP_Screen对象中的render_screen_meta()方法,并且不需要传递任何参数,这个方法将会循环遍历_help_tabs属性中的所有元素,如果元素中的callback属性不为空,那么将会调用callback属性中的函数,传入的两个参数为:WP_Screen对象和$tab(_help_tabs属性的其中一个元素)。 这样我们有了更多的控制,可以选择那些函数被调用,并且可以控制,但是我们可能需要更加努力些,因为我们没有完全控制参数,看一下WordPress中的核心代码位于/wp-includes/category-template.php文件中: #!phpfunction wp_generate_tag_cloud( $tags, $args = '' ) { // … $args = wp_parse_args( $args, $defaults ); extract( $args ); // … foreach ( (array) $tags as $key => $tag ) { $real_counts[ $key ] = $tag->count; $counts[ $key ] = $topic_count_scale_callback($tag->count); } // …}关于extract函数的手册说明:http://www.php.net/function.extract wp_generate_tag_cloud()函数接受两个参数$tags和$args,$args经过wp_parse_args函数的处理,该函数的作用是把$args数组与默认的一组$deafults合并,之后经过extract函数生产一些变量,其中一个是$topic_count_scale_callback变量。之后,该变量被调用传入一个参数,好消息就是我们能够完全控制这个变量。第一个参数,WP_Screen对象被转化为数组,当一个对象被强制转化为数组的时候,其中的属性最为关键: #!php输出结果为: array(1) { ["yolo"]=> string(4) "yolo"}现在我们需要的就是WP_Screen对象中的一个属性有一个count属性。 这是个很容易解决的问题,因为我们可以让所有的属性反序列化一遍。 这就意味着我们能够调用任何不带参数的函数,并完全控制它。 ◆3 EXP 根据以上分析,你应该可以构造一个属于自己的完美exploit了。不过先展示一下我的做法: #!php |
|