《Wordpress4.2.3提权与SQL注入漏洞(CVE-2015-5623)分析》要点:
本文介绍了Wordpress4.2.3提权与SQL注入漏洞(CVE-2015-5623)分析,希望对您有用。如果有疑问,可以联系我们。
DEDECMS教程Check point也很快发出了分析,我也来分析与复现一下最新的这个漏洞.
DEDECMS教程0x01 GP混用造成的越权漏洞
首先,说明一下配景.wordpress中用户权限分为订阅者、投稿者、作者、编辑和管理员.DEDECMS教程权限最低的是订阅者,订阅者只有订阅文章的权限,wordpress开启注册后默认注册的用户就是订阅者.国内很多知名网站,如Freebuf,用户注册后身份即为“订阅者”.
DEDECMS教程我们先看到一个提权漏洞,通过这个提权漏洞,我们作为一个订阅者,可以越权在数据库里插入一篇文章.
DEDECMS教程Wordpress检查用户权限是调用current_user_can函数,我们看到这个函数:
DEDECMS教程
DEDECMS教程调用的has_cap办法,跟进
DEDECMS教程
DEDECMS教程再次跟进map_meta_cap函数:
DEDECMS教程
DEDECMS教程可以见到,这个函数是真正检查权限的.出错误的代码在检查’edit_post’和’edit_page’的部分:
DEDECMS教程
DEDECMS教程可见,这里当$post不存在的时候,直接break出switch逻辑了,后面所有检查的代码都没有执行.
DEDECMS教程$post是要编辑的文章的ID,也就是说,如果我要编辑一篇不存在的文章,这里不检查权限直接返回.
DEDECMS教程正常情况下是没有问题的,因为不存在的文章也没有编辑一说了.
DEDECMS教程我们再看到后台编辑文章的部分:/wp-admin/post.php
DEDECMS教程
DEDECMS教程这里首先获取$_GET[‘post’],找不到才获取$_POST[‘post_ID’],也就是可以说此时的$post_ID是来自GET的.
DEDECMS教程但我们后面调用current_user_can函数时传入的post_ID却是来自POST的:
DEDECMS教程
DEDECMS教程这里就是一个逻辑问题,当我们在GET参数中传入正确的postid(这样在get_post的时候不会产生错误),而在POST参数中传入一个不存在的postid,那么就能够绕过检查edit_post权限的步骤.
DEDECMS教程但是这个逻辑错误暂时不能造成严重的危害,因为实际上编辑文章的代码在edit_post函数中,而这个函数取的post_ID来自$_POST.
DEDECMS教程0x02获取_wpnonce绕过CSRF防御
DEDECMS教程wordpress对于CSRF漏洞的防御措施是使用_wpnonce(也就是token),而且它的token很严格,不同的操作有不同的token.
DEDECMS教程好比我们这里,如果想调用edit_post函数,需要经过以下逻辑:
DEDECMS教程
DEDECMS教程check_admin_referer就是检查_wpnonce的函数,当$post_type==’postajaxpost’的时候,此时_wpnonce的名字就是“add-postajaxpost”.
DEDECMS教程那么怎么获取名字为”add-postajaxpost”的_wpnonce呢?
DEDECMS教程看到上面一点的位置:
DEDECMS教程有个post-quickdraft-save操作.这个操作是用来临时储存草稿的,只要用户拜访这个操作,就会在数据库post表中插入一个status为auto-draft的新文章.
DEDECMS教程如上图画出来的步骤,因为我们不知道名字为”add-post”的_wpnonce,所以进入到wp_dashboard_quick_press函数,跟进:
DEDECMS教程
DEDECMS教程见上图,很幸运的是,在这个函数中wordpress居然本身把此时的_wpnonce输出在表单里了.
DEDECMS教程所以,只要我们拜访一次post-quickdraft-save,就可以获得add-post的_wpnonce,从而绕过check_admin_referer函数.
DEDECMS教程0x03 竞争漏洞导致的逻辑漏洞
DEDECMS教程这一节实际上是这个提权洞的真正核心,在我们拿到_wpnonce后,进入edit_post函数.
DEDECMS教程我们目的是去update一篇文章,但刚才0x01中说到,如果要绕过权限检查的函数,必要传入一个“不存在”的文章id.那么即使可以执行update,我们也不可能修改已经存在的文章呀?
DEDECMS教程这里实际上涉及到一个由竞争造成的逻辑漏洞.看到edit_post函数代码:
DEDECMS教程
DEDECMS教程
DEDECMS教程上面两个图应该很直观了.在0x01中说到的current_user_can被绕过以后,到最终执行update语句中间,这一段代码的执行时间是真空的.
DEDECMS教程比如我们传入的tax_input=1,2,3,4…10000,那么实际上那条查询语句就要执行10000次,这是需要执行很长时间的.(在我本身的虚拟机上测试,执行10000次这条语句,大概需要5~10秒左右)
DEDECMS教程那么假设在这段时间内,有新插入的文章,那么我们之前那个“不存在”的id,不就可能可以存在了吗(只必要把id设置为最新一篇文章id+1)?
DEDECMS教程但有个问题是,我们怎么在这段时间内插入一篇新的文章?因为在0x02中为了获取_wpnonce,已经执行过post-quickdraft-save了.执行post-quickdraft-save可以在数据库插入一篇status为auto-draft的文章,但每个用户最多只会插入一篇文章.
DEDECMS教程在check-point的原文中,它提到的办法是,等待一个星期,wordpress会自动将这篇文章删除,而_wpnonce会多保留一天,这样在这天我们再次执行post-quickdraft-save又可以插入一篇文章了.
DEDECMS教程我本身想了一下,其实没必要这么麻烦.如果我们能够再注册一个身份为订阅者的账号,就可以再插入一篇文章了,所以我的POC是不需要等待一个礼拜的.
DEDECMS教程这三个漏洞组合起来,造成了一个提权漏洞.针对第一篇文章描述的提权漏洞,我写了一个EXP,执行后订阅者就可以在垃圾桶内插入一篇文章:
DEDECMS教程
DEDECMS教程拜访文章编辑页面可以看到这篇文章:
DEDECMS教程
DEDECMS教程0x04 untrash文章时造成的SQL注入漏洞
DEDECMS教程那么,仅仅是一个这样的提权漏洞,实际上没有太大意义.Check-point第二篇文章里提到了一个因为这个提权漏洞导致的SQL注入.
DEDECMS教程先说这个注入的原理.
DEDECMS教程/wp-includes/post.php
DEDECMS教程
DEDECMS教程如上图.Wordpress很多地方执行SQL语句使用的预编译,但仅限于直接接受用户输入的地方.而上图中明显是一个二次操作,先用get_post_meta函数从数据库中取出meta,之后以字符串拼接的方式插入SQL语句.
DEDECMS教程这个地方造成一个二次注入.
DEDECMS教程我们来看看第一次是如何入库的.首先wp_trash_post是将文章删除的办法,其中删除文章后又调用wp_trash_post_comments将文章下的评论也删除了:
DEDECMS教程
DEDECMS教程跟进wp_trash_post_comments函数:
DEDECMS教程
DEDECMS教程如上图,可以看到这个“comment_approved”其实也是从数据库中取出来的.所以这个注入我称之为“三次注入”.
DEDECMS教程那么我再继续跟进,看看最早的comment_approved是从哪来的.
DEDECMS教程实际上看到图中的SQL语句就大概知道了,这个comment_approved是comments(评论)表的一个字段,我分别看了新增评论、修改评论两个函数,发现修改评论的函数(edit_comment)中,有涉及到这个字段:
DEDECMS教程所以,这一连串操作最后造成的结果就是一个SQL注入漏洞.
DEDECMS教程总结一下1234,整个利用过程如下:
DEDECMS教程利用快速草稿插入文章->越权编辑文章->插入评论->修改评论(恶意数据入库)->删除文章(恶意数据进入另一个库)->反删除文章(恶意数据被取出,直接插入SQL语句导致注入)
DEDECMS教程0x05 原文暗藏的部分与真实利用过程的研究
DEDECMS教程这里不得不提到check-point的原文,原文的第二篇全文只字未提wordpress的token也就是_wpnonce,但wordpress后台几乎所有操作都必要特定的_wpnonce.在第一步中我们通过一处泄露点获取了“add-postajaxpost”的_wpnonce,但实际上后面的每一步(增加、编辑评论、trash文章、untrash文章)都必要不同的_wpnonce,那么这些_wpnonce我们怎么获得?
维易PHP培训学院每天发布《Wordpress4.2.3提权与SQL注入漏洞(CVE-2015-5623)分析》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。