前言
我们今天来从零开始审计一款CMS:天目CMS
本文章由二农戏猪编辑
MVC架构的了解
MVC架构一般包括三个部分:M是指业务模型,V是指用户界面,C则是控制器。具体情况大家可以百度查看。
根据我们对于MVC的了解。我一般有两种审计模式:
直接审计控制器
也就C的内容,再追踪一些函数。全局搜索一下**filt__**,因为 filt 的英文意思为过滤,可以通过全局搜索这样式的函数来查看一下过滤规则。这种一般是比较快速审计。
但是这种情况一般建立在你可以清晰明白该款CMS的路由规则,适合老鸟,方便根据审计出来的漏洞的点去回溯验证
从index页面通读审计
这种审计方式是我认为像我这样的菜鸡比较合适的。也不容易忽略一些漏洞。该篇文章就是以这种方式审计的!
开始审计
准备
在审计开始时,我一般习惯于观察一下目录列表,从而可以对整个CMS有一个大概的了解:
1 | app ----------------------------------- 主程序目录 |
index.php
我们可以看到的是index.php就是定义了一些常量,并且包含了 ‘temmoku’.DS.’run.php’ 这个文件。
对于这些常量,我看到过一个表哥有一种方法,就是在index.php末尾去添加,将常量打印出来,保存到一个.txt中查找
记得点赞收藏哦!
1 | foreach(get_defined_constants(true)['user'] as $k=>$v){ |
所以我们可以发现,DS就是\ ,它其实是包含了 temmoku\run.php
这个文件
run.php
然后我们进行跟进 ==>
好的,又是一堆常量和包含了 C:\phpstudy_pro\WWW\temmoku\temmoku\functions.php
C:\phpstudy_pro\WWW\temmoku\temmoku\app.php
这两个php文件,并且实例化app这个类中的run方法。
functions.php
跟入functions.php
,发现里面定义的一脸的各种方法,先放着,等审计控制器中的某些地方具体调用时,再具体审计。
app.php
跟入app.php
,开头看到namespace
和use
这两个东西,不明白,好的,百度一下我们了解到: use
从同一个 namespace
中导入类、函数和常量。然后发现再run.php
中调用了app这个类中的run方法,我们找一下。
spl_autoload_register
函数其实简单来讲就是自动实例化类。
Load_Class
,就是将传进来的$class
里面含有的\\
转为/
,判断存在就包含
再跟进str_caps_look
这个函数,前面我们传进来的$caps=1
,将$class:xxx/xx,先分为xxx、xx转换为小写以后合并
回到app.php
,接下来就是调用setReporting()
方法,简单看一下,不怎么重要,大概就是一些错误报告等级之类的东西。
default_config()
方法,判断了caching.php这个文件是否存在,并且包含,看了一下就是去加载一个高速缓存的东西,这里我们注意一下,看看后面$setting['caching']
会不会可控。
冒险继续,这里定义了一个配置信息和一个路由信息,并且放入了Load_conf
进行处理,我们跟进
这里将末尾的conf 和 route单独拿了出来,并且将目录读取,将文件也读取,大概就是这么一个意思,也就是加载了conf配置和路由信息
然后我们回到app.php中继续审计,在124行我们看到一个C方法,跟进,冲!!!!!!发现C方法其实就是加载了一些程序变量,对于这个东西,我还是采用看到的一篇文章中提到的方法,就是给C方法添加一个形式参数,然后去index.php末尾调用,然后将得到的程序变量保存在一个txt中,需要的时候去搜索。
后面就是去加载了一下版本信息
欸~~~,发现了个getRealIP这个方法,盲猜就是获取真实IP,啊哈哈哈哈哈
嘿!好家伙,果然是这样的。我们发现,如果对CLIENT-IP进行伪造是不会成功的,但是是可以对X-FORWARDED-FOR
参数进行伪造,这…..看不懂这个操作,这个就可以先记录,等完事儿看看会不会getRealIP
给我们带来惊喜。审计就是这样,你永远不知道后面会发生什么。
到这里基本default_config方法就看完了,后面就是对一些常量的定义了。
接着我们回到app.php
中继续继续,20行实例化了一个route,我们回想起前面use temmoku\route
,去文件夹里找一下,当看到对类进行实例化时候,我们一般是需要关注魔术方法,看到它先是对C:\phpstudy_pro\WWW\temmoku\app\module_route.php
判断是否存在该文件,然后传入Load_file
处理,就是在加载一些静态数组,并且定义了两个常量。
接着是调用Route()
这个方法,然后对这个方法里面往下看,前面以get方式获取到的PATH_INFO进行分割,遍历
在接下来这个if分支,我们发现ROUTE
这个数组默认为空,所以先放下不看
这个就是定义了伪静态的方式
如果给$_SERVER['PATH_INFO']
传入了值,会以/
分割,变成包含两个元素的数组,例如xxx/xx,变为xxx、xx,$test_module
也就是传入的再第一个/
以前的内容,然后就是将xxx转换为小写,之后判断是否安装,也就是$lock
是否存在,存在则为已安装
紧接着就是如果判断是否有 $test_module
,如果没有,则定义MODULE为home
接着我看到了熟悉的m、c、a,if条件语句里前面C(‘URL_RULES’)晓得是啥,后面'admin'!==MODULE
,我们尝试一下用这种方式访问一下,看到是可以的,但是admin模块是不可以用这种方式访问。
139行就是如果没有定义模块,则默认为home模块,141-142行说的是admin模块是进行特殊的一个路由,就是Admin_Route()这个方法,这个一会儿再看。
接着是加载插件和各个模块下的私有函数
在159-174行,将$_SERVER['PATH_INFO']
以/
分割,定义路由,例如home/index/index,指的就是home模块下,index控制器下,index方法。
然后我们回过头来看Admin_Route()
,也就是admin模块下的路由规则,同样也是将$_SERVER['PATH_INFO']
以/
分割,然后去遍历,并且分别判断控制器是否为modular或plugin
然后我紧接着发现了个大宝贝。这。。。。这就是过滤?
我们追一下filtering这个函数,在functions.php这里面定义了过滤规则。将'id','aid','cid','uid','mid','cmid','iid','nid','cityid','proviceid','countyid','townid','upcid','state','reply_id','lid','iddb'
都强制转换为int类型,然后放入htmlspecialchars
进行实体化编码。
EMMMMM…….这里好像是杜绝了XSS的攻击,如果SQL注入的话,必须参数不能为上述,且为数字类型。又或者是同时查询两个参数,用\
去绕过。不急。先继续看app.php
self::log();
这个函数发现是记录日志的个东西,先放着。
然后跟一下self::Load_Controller()
,在app.php 63-75行,$home这个变量是否等为admin、user、install、home,如果是:$home为空,如果不是:$home=’\home’。
然后判断是否为插件。
判断控制器是否存在。如果存在,对这个controller进行实例化。
跟进class controller,里面就是去验证了下会员状态
返回上面跟入app.php 71行的函数,发现它是判断了一下是否存在方法
==> 通过上面的审计,我们发现了有三种路由规则。
路由规则
127.0.0.1/模块名/控制器/方法
所对应的文件路径为 ./app/模块名/controller/控制器.php所对应的方法则是传递过来的方法。127.0.0.1/?temmoku_dirs=模块名/控制器名/方法名
所对应的文件路径为 ./app/模块名/controller/控制器.php
==> 所对应的方法则是传递过来的方法。
127.0.0.1/?m=模块名&c=控制器名&a=方法名
所对应的文件路径为 ./app/模块名/controller/控制器.php
所对应的方法则是传递过来的方法。该种规则不能用于admin模块
尝试一下,好的 ,没问题,就是这样的路由规则,接下来我们开始正式审计控制器。
XRSec has the right to modify and interpret this article. If you want to reprint or disseminate this article, you must ensure the integrity of this article, including all contents such as copyright notice. Without the permission of the author, the content of this article shall not be modified or increased or decreased arbitrarily, and it shall not be used for commercial purposes in any way