学生教材网 >电脑教程 > 建站教程 > CMS教程 > 浏览文章

WordPress SQL注入漏洞与提权分析[页4]

来源:网络编辑:佚名时间:2015-08-27人气:

相宜本草怎么样,印度神曲东北玩泥巴,免费发布分类信息

public function has_cap( $cap ) {
        if ( is_numeric( $cap ) ) {
            _deprecated_argument( __FUNCTION__, '2.0', 
__('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') );
            $cap = $this->translate_level_to_cap( $cap );
        }
 
        $args = array_slice( func_get_args(), 1 );
        $args = array_merge( array( $cap, $this->ID ), $args );
        $caps = call_user_func_array( 'map_meta_cap', $args );
 
        // Multisite super admin has all caps by definition, Unless specifically denied.
        if ( is_multisite() && is_super_admin( $this->ID ) ) {
            if ( in_array('do_not_allow', $caps) )
                return false;
            return true;
        }
 
        $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args, $this );
        $capabilities['exist'] = true; // Everyone is allowed to exist
        foreach ( (array) $caps as $cap ) {
            if ( empty( $capabilities[ $cap ] ) )
                return false;
        }
 
        return true;
    }

看最后那个foreach,它检测$caps中的各个元素在$capabilities中是否有不存在的,如果有那么就return false,但是$caps是个空数组,这样很容易我们就获得了一个true,权限校验成功绕过。那么这样我们可以得到的一个信息就是,我们可以通过这个缺陷去尝试update一个并不存在的文章。

那么现在问题来了,直接update一个不存在的文章是没有意义的,因为数据库执行SQL是肯定会报错,我们要怎么才能成功创建一篇文章呢?

在校验权限之后,数据库执行操作之前,post.php中有这样一段代码:

if ( isset( $post_data['tax_input'] ) ) {
        foreach ( (array) $post_data['tax_input'] as $taxonomy => $terms ) {
            // Hierarchical taxonomy data is already sent as term IDs, so no conversion is necessary.
            if ( is_taxonomy_hierarchical( $taxonomy ) ) {
                continue;
            }
 
            if ( ! is_array( $terms ) ) {
                $comma = _x( ',', 'tag delimiter' );
                if ( ',' !== $comma ) {
                    $terms = str_replace( $comma, ',', $terms );
                }
                $terms = explode( ',', trim( $terms, " \n\t\r\x0B," ) );
            }
 
            $clean_terms = array();
            foreach ( $terms as $term ) {
                // Empty terms are invalid input.
                if ( empty( $term ) ) {
                    continue;
                }
 
                $_term = get_terms( $taxonomy, array(
                    'name' => $term,
                    'fields' => 'ids',
                    'hide_empty' => false,
                ) );

如果在POST的数据中存在名为tax_input的数组参数,那么就对参数中的值使用逗号进行切割,然后对分割出来的每个内容进行一次select查询。那么这里我们可以想象一下,如果我们post_ID中填写的是对当前最新文章ID+1的数值,并且在tax_input这个参数添加特别多的内容,导致它不停地select查询,我们是不是在这个停滞的时间当中插入一篇文章(这篇文章的ID刚好是最新文章ID+1),那么后面的update是不是就有意义了?

下面最后一个问题,我们如何插入一篇文章呢?

还记得post-quickdraft-save功能吗?它的作用就是快速的保存一篇草稿!

这里可耻的盗一张phithon文章中的一幅图,来让各位加深条件竞争的流程:

小结

在调试过程中,感触最深的的就是条件竞争,要很好的把握插入文章和update的时间差。如果查得太早则无法通过权限检验,如果太晚了又失去了意 义。我获得的经验是,**插入文章的进程尽量等待时间长一些,tax_input中的内容尽可能的多,这样能够比较稳定的在校验之后,update之前插 入文章。

当然这里面还有每个用户只可以保存一个草稿的限制,漏洞发现者提供的建议是等一周的时间,草稿会自动删除,而_wpnonce则会多保留一天。phithon的建议更好一些,使用两个账户,一个账户插入文章,一个账户update。

一个越权漏洞由信息泄露、逻辑漏洞导致的权限绕过以及程序执行时间可操控三个小漏洞组合而成,环环相扣,脑洞实在是大。

0x02 SQL注入漏洞

revision trick

漏洞发现者的文章最开始提到了一个revision的trick,用于承接越权写文章之后如何继续进行深入攻击。但是由于这个老外隐藏了部分技巧, 导致按照他文章所说的内容无法复现订阅者账号触发SQL注入漏洞,所以phithon在文章中没有提到这个trick。我在这里本着还原作者思路的目的, 向大家介绍一下关于这个trick的原理。

下面是原文关于这个trick部分的翻译:

revisions字段用于记录草稿或者更新的发布,Wordpress中用revisions记录对于完成的提交和存储都会在posts数据库表 中将post_type设置成revision,每个revision都会有一个’post_parent’字段,指明这个revision所基于的原版 提交。

当尝试编辑一个revision时,会通过post_parent来进行校验,而不是revision本身。这样,如果我们基于一个post创建一 个revision,那么我们可以任意设置它的状态为“trash”之外的任何状态,即使原始的post的状态是“trash”

如何利用robots协议优化你的WordPress博客站

很多新手建站朋友对robots协议文件的重要性不是很清楚,本篇文章由昆明SEO博主普及一下WordPress站点robots协议文件编写知识。robots协议(也称为爬虫协议、机器人协议等)的全称是网络爬虫排除标准(RobotsExclusionProtocol),网站通过robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。

如何利用织梦cms做多语言的网站

有很多网友都问过我,用dedecms织梦程序如何做中英文网站,今天就给大家来一个详细的图文教程,希望能帮助到大家。

热门推荐