php代审2——Taocms
taocms代码审计
1、环境准备
phpstudy8.1.1.3
apache2.4.39+mysql5.7.26+php5.6.9
2、环境搭建
先创建一个database,create database taocms;
直接访问站点install.php,数据库类型选择mysql,构建数据库配置|127.0.0.1:3306|root|root|taocms
直接安装即可
登录,再设定一下网站地址即可
3、路由审计
1、大概看一下目录结构
主要涉及到以下目录
1 |
|
2、看看站点的url,并结合网站目录,分析路由
单纯看该cms的后台管理,发现无论点击左栏的任意项目,url都是http://taocms/admin/admin.php?action=frame&ctrl=iframes
,这明显不太对,怎么可能一点都不改变,于是我直接尝试执行一个功能点,抓个包看看情况(代码功底比较差,还是集合功能点理解),以”sql执行”为例
执行语句,并抓包
关注一下post传入的参数
目前查看ctrl有iframes、display值;action有frame、sql等值
依次全局搜索一下值,找一下共同点
发现ctrl参数都对应了一个方法
而action参数则是应该对应类名
所以我们差不都就明白了路由,再后台管理界面,action对应了类名、ctrl对应类中的方法名,而每一个类都以文件名的形式,放在include/model目录下
上述就是我们根据url和目录结构分析的,这个方法比较好理解,现在我们直接看路由与页面跳转相关的代码,保存在admin.php中
4、漏洞审计
漏洞1:任意文件读取
全局函数file_get_contents(),这个函数主要是获取文件内容,但是不能输出,所以我也要看是否有输出,于是选定了下面这个文件
我进一步查看,发现是在一个download函数里面
看了看,读取的变量为realpath,跟随其变量
该变量是在construct魔术方法中,我们只需要直接传入path变量,再在上述download方法中发现,对path使用pathinfo方法,对我们的文件路径没有做任何限制和过滤,同时SYS_ROOT为网站根目录
所以我们只需要直接传入path参数,就可以实现任意文件读取了
漏洞1验证
创建一个test.txt文件用于验证
构建payload:
1 |
|
发现报错,refer error应该是要求refer请求头
翻翻代码,发现要ReferHost(referer请求头)要和Host请求头一样,否则会发生跳转,所以我们直接添加referer请求头
成功读取
当然也可以读取配置文件等
漏洞2:任意文件上传getshell
我们全局检索upload(
关键词
发现一个upload函数,但是是采用白名单过滤的,就放弃了
然后我们再检索一下move_uploaded_file函数
然后我们根据tmpfile变量,但是没有我们可以传参的地地方,索性直接下一个。找了一阵代码没有什么比较好的突破口,我们直接回归功能点,根据web界面的功能点,去查看相关文件上传操作,并回归代码。
很明显的文件管理,直接新建一个1.php文件,并抓包
根据路由找到相关代码:file类中的create函数,fopenhan’shu
没有做任何过滤,直接上传成功,直接编辑,写入php代码
在网站根目录下,直接访问,成功getshell
漏洞3:mysql日志写入getshell(失败)
其实这个不怎么需要代码审计,我们直接黑盒思路,因为这个cms的后台管理确实也太明目张胆了,真的就纯纯根据功能点来进行审计。
我们直接在”执行sql”处执行sql语句select @@version;
,查看版本为5.7.26
mysql版本5.6.34之后secure_file_priv值,默认为NULL,无法进行文件写入。于是我们使用日志写入shell,我们先查看
1 |
|
1 |
|
原本以为万无一失,但是奈何此处不能执行多条sql语句,就失败了。
漏洞4:修改配置文件getshell
翻阅网站功能点,在网站设置
栏,更新功能点有个数据库的配置,同时猜想,可能在这个功能点会把相关配置写入配置文件中,于是审计以下代码,有没有可乘之机
可见该函数会先判断是否config.php是否可写,然后先销毁POST变量,然后重新传入POST参数,进行重新配置,其中POST的内容会被safeword函数进行过滤,我们进一步跟进safeword函数。
默认level=8,然后就走默认的level,如下
1 |
|
不是Sqlite,于是直接使用_addslashs()方法,进一步跟进
1 |
|
addslashes函数主要对一些特殊符号(通过在字符串中的单引号、双引号、反斜杠和 NULL 字符前加上反斜杠)来转义这些字符,所以就是会对我们POST传入的参数,进行简单转义
然会会将我们传入的内容直接写入config.php中,我们就可尝试直接在config.php中写入一句话木马,构造payload尝试绕过
但是迫于addslashes函数,还是失败了
但是我们可以通过上一个if判断(数据库为Sqlite)来写入,这样以来,只会有一个字符替换
1 |
|
于是我们重新构造payload
1 |
|
记得选择sqlite数据库!
成功修改配置
成功getshell
还可以通过install.php,安装的时候也根据上面选择sqlite,然后再构建payload
1 |
|
即可再次写入config.php文件getshell
漏洞5:任意文件删除
检索unlink(,检索到下述代码
没有什么过滤,直接构造payload,开删
sql注入
整个cms还有很多sql注入
其中一个为例,我们通过翻阅函数,发现一个delist函数,该函数没有对sql语句及其参数使用过滤
然后向上查找,找到cms类中有del方法调用delist方法,但是根据原delist函数发现没有回显,所以要采用盲注等方法
此处id就是我们的注入点,那我们该如何传入这个参数?于是我们尝试追踪id参数,找到了Article类中的id变量,为什么会定位到Article类,因为Cms类其实是继承了Article类的(如下)
然后我们通过查看Article类中的属性、方法,发现创建该类时就会调用魔术方法,__construct,然后使id=0,这难道就不能传参了?肯定不会止步于此
回看之前admin.php中的路由与参数
我们创建类的时候,是可以自己通过传参传入id参数的,从而突破了魔术方法的限制。而且PHP 中的子类可以使用父类的传参来创建子类对象。于是乎我们直接开始构造poc
可以加一个echo查看调试语句
1 |
|
没有成功
尝试时间盲注,时间盲注poc如下
1 |
|
成功了!
当然里面还有很多未做好过滤的,需要检索sql语句关键字,耐心查看
总结
这个cms表面易挖掘的漏洞点,可以通过功能点很快挖掘到。
而且它主要是通过类加载来实现功能点,也是它比较特殊的点。然后过滤函数也写得比较水,其实还是很好挖掘的,最重要的自我感觉还是一定要弄清楚,一开始只是对路由有个大概的理解,还是没有深度去看代码,导致了我之后对sql注入的传参、挖掘还懵了一下,所以路由很重要!!!不要局限在表面
多了解了一个路由方式。还有就是深度挖掘经典漏洞可以从函数入手,但是权限方面的漏洞,自我感觉要结合黑盒的思路,通过功能、权限参数的对比,然后去深究代码挖掘。