GreenCMS 2.3.0603代码审计
环境搭建
下载地址:https://github.com/GreenCMS/GreenCMS
环境:
- php5.6.9
- Apache2.4.39
- MySQL5.7.26
访问http://127.0.0.1/install.php直接安装:
框架分析
先看目录结构:
1 | / |
这是一个thinkphp框架,所以我们重心肯定是在Application文件夹下做文章
路由分析
对于thinkphp框架,其路由一般有几种形式:普通模式、PATHINFO模式、REWRITE模式、兼容模式
普通模式:
1 | http://localhost/?m=home&c=user&a=login&var1=value1&var2=value2 |
其中m指模块,c指控制器,a指操作
pathinfo模式:
1 | http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...] |
REWRITE模式:
1 | 在PATHINFO的基础上去掉入口文件 |
兼容模式:
1 | http://servername/index.php?s=/index/Index/index |
这里我们可以通过url来看路由,比如进入后台:
可以看到是普通模式:
m对应模块->目录
m=admin告诉框架要去Application目录下寻找名为Admin的模块目录。即/Application/adminc对应控制器->文件
c=index告诉框架要去上述模块目录下的Controller目录里,寻找名为index的控制器文件。a对应操作->方法
a=index告诉框架要去上述控制器文件中,寻找名为index的 公共方法(public function)来执行。
路由清楚后就可以直接找漏洞了。
敏感信息泄露
在/Data/Log目录下存放着日志文件,而这里并没有对访问作任何过滤,所以我们可通过对Data/Log/year_month_day.log文件发送直接请求利用该漏洞获取敏感信息。
甚至可以下载网站全部日志。
XSS
第一处
找了一圈,由于默认配置的原因,基本上很多XSS注入的地方都存在着htmlspecialchars函数进行转义:
这就导致很多地方都注入不了,但依然存在一些漏网之鱼或者可以绕过的地方。
第一处http://127.0.0.1/install.php?m=install&c=index&a=step3
这里的功能主要是连接数据库并设置用户名密码等信息。
定位到Install/Install\Controller\IndexController.class.php:
这里读取了用户名、密码、邮箱等信息且没有经过任何的过滤就直接存入数据库,而后面读取其信息时也没经过任何检验,所以直接在邮箱注入XSS即可。
注意用户名和密码注入后在登录时会对我们的输入进行转义导致用户名或密码错误登录不了,所以对邮箱注入即可
只要能显示邮箱的地方都有xss:
第二处
由于其他很多地方都有htmlspecialchars转义,但通过不断的尝试功能点还是找到了几处并没有进行htmlspecialchars转义的地方
分别是添加角色功能和添加节点功能http://127.0.0.1/index.php?m=admin&c=access&a=addnode两个功能点中并没有过滤,所以能直接注入:
先看添加角色功能:
功能点在http://127.0.0.1/index.php?m=admin&c=access&a=addrole
其源码定位到:Admin\Controller\AccessController.class.php
这里判断是否为POST请求,如果是POST请求:返回JSON格式的角色添加结果,没有进行任何的过滤,所以直接注入:
再看另一个添加节点功能:
功能点在:http://127.0.0.1/index.php?m=admin&c=access&a=addnode
其源码同样位于:Admin\Controller\AccessController.class.php
逻辑一样的,直接注入即可:
第三处
这一处就比较有意思了,功能点是是在编辑菜单处位于:http://127.0.0.1/index.php?m=admin&c=custom&a=menuedit
一开始我看着这里可以写东西,本来想试着看是否有存储型XSS的,我先试着直接注入:
1 | <script>alert(1)</script> |
可当我查看菜单管理时发现被转义了,这是由于ThinkPHP配置了全局输出过滤可以理解
但htmlspecialchars函数有个缺陷就是它并不会对单引号进行转义,所以对于那种单引号闭合的标签就可以绕过,这不,刚好我在编辑菜单时发现一个惊喜:
在参数链接这一栏是通过单引号闭合的,所以我们可以直接构造:
1 | ' onmouseover='alert(1) |
这样闭合后就是:
1 | <input class="form-control large" name="menu_url" |
从而直接绕过:
任意文件删除
功能点在插件管理:
这里的插件删除是可以实现任意文件删除的
源码位于Admin\Controller\CustomController.class.php:
可以看到它并没有对我们的路径进行验证,可以直接路径穿越
抓包:
将目录改成我们的测试目录:
将参数改成../B1uel0n3:
文件上传
在文件管理处可以直接上传文件:
然后直接访问即可:





































