YzmCMS代码审计
YzmCMS代码审计
代码审计 #CMS
0x01 通读
index.php
里面有很多的define,用这个代码运行下
foreach(get_defined_constants(true)['user'] as $k=>$v){
echo $k.'---'.$v."\r\n";
}
APP_DEBUG---
URL_MODEL---3
YZMPHP_PATH---x:\cms\yzmcms-master\
IN_YZMPHP---1
YP_PATH---x:\cms\yzmcms-master\yzmphp\
YZMPHP_VERSION---2.7
APP_PATH---x:\cms\yzmcms-master\application\
SYS_START_TIME---1652515504.1375
SYS_TIME---1652515504
SERVER_PORT---http://
HTTP_HOST---xhcms.cc
HTTP_REFERER---
EXT---.class.php
IS_CGI---1
PHP_FILE---/index.php
SITE_PATH---/
SITE_URL---http://xhcms.cc/
STATIC_URL---http://xhcms.cc/common/static/
MAGIC_QUOTES_GPC---
YZMCMS_VERSION---V6.3
YZMCMS_UPDATE---20220110
YZMCMS_SOFTNAME---YzmCMS内容管理系统
ROUTE_M---index
ROUTE_C---index
ROUTE_A---init
21行有个require
,require==x:\cms\yzmcms-master\
,实际上是包含了当前目录下的/yzmphp/yzmphp.php
文件
跟进文件
yzmphp.php
33行调用了yzm_base
下的load_sys_func()
方法,跟进这个类,PHPstorm
中按住ctrl+鼠标左键
进行跟踪
这里进行了文件包含操作,实际上包含的是yzmphp/core/function/global.func.php
整体上看一下,只是定义了方法。回到yzmphp.php
这里是判断是否开启GPC
,开启则定义MAGIC_QUOTES_GPC
为True
,否则为False,上面输出的常量中也写出为1。
70-72行中调用了load_common方法,跟进下
这里也是文件包含,看一下传入的三个不同的参数文件内都是什么
version.php
文件只是定义了常量,extention.func.php
文件什么也没做,system.func.php
中定义了一些方法。继续跟进yzmphp.php
,yzmphp.php在后面定义完类之后就没有任何操作
回到index.php
,
这里有个创建应用的方法,跟进下
传值进入load_sys_class
静态方法中,然后再传入_load_class
静态方法中,在load_sys_class
方法中设置$initialize
的值为1
,跟进下该方法
因为起初传递的$path
为空,进入104行,此时$path
为x/cms/yzmphp/core/class
,然后115行进行了文件包含,EXT
为.class.php
,即包含了/yzmphp/core/class/application.class.php
,然后进入到117行,实例化了applocation
类并且赋值给$classes
静态变量中,121行将application
返回
application.class.php
跟进application.class.php
因为实例化了application类,会自动调用__construct构造方法
,主要看第20行,前面是debug
的,这里给load_sys_class
传入了param
参数,在上面已经跟进过load_sys_class
静态方法了,实际上这里是包含的/yzmphp/core/class/param.class.php
。OK,跟进下,在这里打个断点
param.class.php
这里标记了个C方法,跟进下,跟读遇到没见过的就跟进
/yzmphp/core/function/global.func.php
这里有个$path
,此时的值为/common/config/config.php
,跟进下
这里都是配置信息
回到param.class.php
这里有个路由设置,default在/common/config/config.php
出现过,这部分是定义路由。第19行C
为false
,看到20行有个pathinfo_url()
,跟进
这里主要是做网站伪静态的,同时增加了个路由指定方法-$_GET['s']
回到application.class.php
,继续通读
跟进下调用的三个方法,在param.class.php
中
每个方法中都带有$ = $this->safe_deal($);
,跟进下这个方法。
这里进行了addslashes()过滤。
每个方法中这部分
是判断$_GET['a']
是否存在,不存在则返回默认路由
回到application.class.php
上面调用了init(),32行又调用了load_controller()
,跟进下
59行实际上是application/$_GET[m]/controller/$_GET[c].class.php
,然后62行对其包含,然后64行是实例化包含进来的类,回到上一步
这里有个call_user_func方法,来调用$_GET[a]方法。
框架总结
http://www.xxx.com/模块名/控制器/方法
- 所对应的文件路径为
./application/模块名/controller/控制器.php
- 所对应的方法则是传递过来的方法。
- 所对应的文件路径为
http://www.xxx.com/?s=模块名/控制器名/方法名
- 所对应的文件路径为
./application/模块名/controller/控制器.php
- 所对应的方法则是传递过来的方法。
- 所对应的文件路径为
http://www.xxx.com/?m=模块名&c=控制器名&a=方法名
- 所对应的文件路径为
./application/模块名/controller/控制器.php
- 所对应的方法则是传递过来的方法
- 所对应的文件路径为