极致CMS 漏洞简单分析

环境搭建

极致CMS1.6.7

下载地址:https://www.jizhicms.cn/thread-95-1-1.html

目录框架

 404.html
 A		后台控制文件
 Conf	公共函数
 FrPHP框架
 Home	前台控制文件
 Public	公共静态文件
 README.md
 admin.php	后台入口
 backup	备份
 cache	缓存
 favicon.ico
 index.php	前台入口
 install
 readme.txt
 static	静态文件
 web.config


主要过滤函数

frparam()函数

位置:\FrPHP\lib\Controller.php

	public function frparam($str=null, $int=0,$default = FALSE, $method = null){
		
		$data = $this->_data;
		if($str===null) return $data;
		if(!array_key_exists($str,$data)){
			return ($default===FALSE)?false:$default;
		}
		
		if($method===null){
			$value = $data[$str];
		}else{
			$method = strtolower($method);
			switch($method){
				case 'get':
				$value = $_GET[$str];
				break;
				case 'post':
				$value = $_POST[$str];
				break;
				case 'cookie':
				$value = $_COOKIE[$str];
				break;
				
			} 
		}
		
		return format_param($value,$int);

继续 format_param() 函数:

位置FrPHP\common\Functions.php

function format_param($value=null,$int=0){
	if($value==null){ return '';}
	switch ($int){
		case 0://整数
			return (int)$value;
		case 1://字符串
			$value=htmlspecialchars(trim($value), ENT_QUOTES);
			if(!get_magic_quotes_gpc())$value = addslashes($value);
			return $value;
		case 2://数组
			if($value=='')return '';
			array_walk_recursive($value, "array_format");
			return $value;
		case 3://浮点
			return (float)$value;
		case 4:
			if(!get_magic_quotes_gpc())$value = addslashes($value);
			return trim($value);
	}
}

这两个参数对参数进行了简单的过滤。

存储型XSS

漏洞点:

发布文章 标题处
极致CMS 漏洞简单分析_第1张图片

插入恶意代码:

极致CMS 漏洞简单分析_第2张图片
提交,进入后台,内容列表处:
极致CMS 漏洞简单分析_第3张图片
代码分析:

release()函数:
极致CMS 漏洞简单分析_第4张图片
这里对所有值都进行了实体化。

所以进入数据库的信息是经过html实体化的。

但是在editarticle()函数中:
极致CMS 漏洞简单分析_第5张图片

这里调用函数时,并没有传递参数。

会直接返回数据。

抓包,进行查看:
极致CMS 漏洞简单分析_第6张图片
编码又变回了原来的样子,所以触发漏洞。

SQL注入一(网站首页)

网站首页

先看效果:
极致CMS 漏洞简单分析_第7张图片
报错注入。

代码分析

代码位置:\Home\c\HomeController.php

jizhi()函数,用来接收前台所有的请求:

对url进行 if 判断,进过一系列判断,(参数并未经过过滤) 总之会执行这样一条语句:

$res = M('classtype')->find(array('htmlurl'=>$html));

查看find()函数,位置:FrPHP\lib\Model.php

    public function find($where=null,$order=null,$fields=null,$limit=1)
    {
	   if( $record = $this->findAll($where, $order, $fields, 1) ){
			return array_pop($record);
		}else{
			return FALSE;
		}
    }

跟进findall()函数:

    // 查询所有
    public function findAll($conditions=null,$order=null,$fields=null,$limit=null)
    {
		$where = '';
		if(is_array($conditions)){
			$join = array();
			foreach( $conditions as $key => $value ){
				$value =  '\''.$value.'\'';
				$join[] = "{$key} = {$value}";
			}
			$where = "WHERE ".join(" AND ",$join);
		}else{
			if(null != $conditions)$where = "WHERE ".$conditions;
		}
      if(is_array($order)){
       		$where .= ' ORDER BY ';
            $where .= implode(',', $order);
      }else{
         if($order!=null)$where .= " ORDER BY  ".$order;
      }
		
		if(!empty($limit))$where .= " LIMIT {$limit}";
		$fields = empty($fields) ? "*" : $fields;
		$table = self::$table;
		$sql = "SELECT {$fields} FROM {$table} {$where}";
		
        return $this->db->getArray($sql);

    }

这一句话,进行了数据的查询:

$sql = "SELECT {$fields} FROM {$table} {$where}";

跟进getArray()函数:

位置:\FrPHP\db\DBholder.php

	//执行SQL语句返回数组
	public function getArray($sql){
		if(!$result = $this->query($sql))return array();
		if(!$this->Statement->rowCount())return array();
		$rows = array();
		while($rows[] = $this->Statement->fetch(PDO::FETCH_ASSOC)){}
		$this->Statement=null;
		array_pop($rows);
		return $rows;
	}

跟进query()函数:

	//执行 SQL 语句,返回PDOStatement对象,可以理解为结果集
	public function query($sql){
		$this->arrSql[] = $sql;
        $this->Statement = $this->pdo->query($sql);
        if ($this->Statement) {
			return $this;
        }else{
			$msg = $this->pdo->errorInfo();
			if($msg[2]){
				Error_msg('数据库错误:' . $msg[2] . end($this->arrSql));
			}
		}
	}

这里进行了报错。

然后报错信息通过\Home\c\ErrorController.php下进行一个输出:

class ErrorController extends Controller
{
	//错误处理示例
	function index($msg){
		echo '错误信息提示:
'
; echo $msg; } }

造成漏洞的原因:输入的数据并没有经过两个过滤函数的处理,而且过滤函数处理的参数是通过$_GET $_POST $_COOKIE 进行传输的,而造成漏洞的参数并没有通过这三个方式进行传输。

SQL注入二(留言页面)

留言页面:

先上测试结果:
极致CMS 漏洞简单分析_第8张图片
代码分析:

位置\Home\c\ MessageController.php 下的index()函数:
极致CMS 漏洞简单分析_第9张图片
这里调用了GetIP()函数,跟进一下:
极致CMS 漏洞简单分析_第10张图片
其中,$_SERVER['HTTP_CDN_SRC_IP']并没有经过过滤,所以通过IP进行payload。

index()函数中:

这个位置会与数据库进行交互:
极致CMS 漏洞简单分析_第11张图片
跟进add()函数:
极致CMS 漏洞简单分析_第12张图片
跟进exec()函数:
极致CMS 漏洞简单分析_第13张图片
会进行报错处理。

所以通过伪造CDN_SRC_IP头部信息可触发漏洞。

进一步查看后台:
极致CMS 漏洞简单分析_第14张图片
可以看到留言IP,尝试打入xss:
极致CMS 漏洞简单分析_第15张图片

成功触发:
极致CMS 漏洞简单分析_第16张图片

SQL注入三(发布文章)

发布文章处。

在这个位置进行了get_fields_data() 函数处理:
极致CMS 漏洞简单分析_第17张图片
跟进:
极致CMS 漏洞简单分析_第18张图片
首先,我们不是admin,所以执行else语句。

再往后:
极致CMS 漏洞简单分析_第19张图片这里进行了if判断,调试的时候发现这里的$v['field']的值为空,所以会直接return

再回到release函数:
极致CMS 漏洞简单分析_第20张图片
这里$sql由两个变量tidmolds组成,执行findll

再往下:
极致CMS 漏洞简单分析_第21张图片
会执行update或者add,总之参数没有进行过滤,所以必然会触发漏洞。

所以,函数一开始对tid进行的过滤,到了中间,直到最后却没有过滤。

这里很多参数都存在漏洞。

极致CMS 漏洞简单分析_第22张图片

所以说XSS跟这个是一个道理。

SQL注入四(修改个人资料)

在修改个人资料处:
userinfo()函数:
极致CMS 漏洞简单分析_第23张图片
这里对这些个参数进行了处理,进行抓包:
极致CMS 漏洞简单分析_第24张图片
也只抓到了这几个参数。

但是在后台:
极致CMS 漏洞简单分析_第25张图片
这里除了前台的可以修改的信息,还存在其他信息,查看后台代码:
极致CMS 漏洞简单分析_第26张图片
也对参数进行了处理。

但是通过在前台数据包添加后台参数时,前台的代码并没有对这几个参数进行过滤,触发漏洞:
极致CMS 漏洞简单分析_第27张图片
这都可以??算半个越权吧?

逻辑漏洞

跟第四个SQL注入道理相同,通过前台数据包执行后台修改:

抓取前台数据包,添加积分参数,提交:

当前积分:
极致CMS 漏洞简单分析_第28张图片
抓包修改:
极致CMS 漏洞简单分析_第29张图片
再次查看:
极致CMS 漏洞简单分析_第30张图片
都是前台打后台数据。

你可能感兴趣的:(代码审计,安全)