php对于渗透测试的代码审计 (php渗透审计)

目录

0x01 框架结构
0x02 Admin.php
  任意修改管理员用户名及密码
  SQL注入
0x03 Index.php 用户留言处存储型XSS
0x04 Controller.php
  任意增删改查数据表内容
  任意文件上传
0x05 一些XSS
 结语

0x01 框架结构

php渗透审计,php对于渗透测试的代码审计

php渗透审计,php对于渗透测试的代码审计

采用thinkphp5作为框架,版本为5.0.2,默认开启debug模式,数据库默认使用PDO连接

打了补丁,修复了RCE通用漏洞

php渗透审计,php对于渗透测试的代码审计

如图,增加了白名单,不能任意调用其他方法进行利用

0x02 Admin.php

任意修改管理员用户名及密码

漏洞点:admin/controller/Admin.php

php渗透审计,php对于渗透测试的代码审计

_initialize()方法:在任何方法执行之前,都要执行此方法,包括_construct构造函数。

跟进一下父类的_initialize()方法

php渗透审计,php对于渗透测试的代码审计

方法为空,无语住了

所以该方法相当于只获取了Session而没有进行判断,可以未授权调用管理员方法

接下来跟进一下doUpdate方法

php渗透审计,php对于渗透测试的代码审计

可以看到 $user_id$data['username']都是通过用户输入获取而没有使用Session,字段都可控,并且存在sql注入

POC:

php渗透审计,php对于渗透测试的代码审计

SQL注入

还是doUpdate方法

php渗透审计,php对于渗透测试的代码审计

重点看这一条:

$is_have = Db::name('admin')->where("id != $user_id AND username = '".$data['username']."'")->value('id');

该sql语句直接将字符串进行拼接而没有使用PDO绑定,并且 $user_id也没有用引号包裹

看下input方法

php渗透审计,php对于渗透测试的代码审计

作用是从某个指定的来源中获取数据,但默认过滤器为空

php渗透审计,php对于渗透测试的代码审计

回到之前, $user_id$data['username']获取数据时都没有使用过滤器,所以两个字段都是注入点

POC:懒得手注了,直接sqlmap一把梭

php渗透审计,php对于渗透测试的代码审计

0x03 Index.php 用户留言处存储型XSS

漏洞点:api/Index.php

php渗透审计,php对于渗透测试的代码审计

可以看到 $data没有进行过滤,也没有限制列名,但下面会将一些特定字段进行覆盖

php渗透审计,php对于渗透测试的代码审计

可控的有 idusernametelephoneacreage字段,但真正可利用的只有usernameacreage

POC:

php渗透审计,php对于渗透测试的代码审计

php渗透审计,php对于渗透测试的代码审计

0x04 Controller.php

任意增删改查数据表内容

漏洞点:admin/controller/Admin.phpadmin/traits/controller/Controller.php

php渗透审计,php对于渗透测试的代码审计

根据上文已经了解到Admin.php未进行鉴权,并且引入了一个公共控制器 Controller.php,我们来跟进一下

先看下index方法

php渗透审计,php对于渗透测试的代码审计

首先用 $controller = $this->request->controller()获取当前请求的控制器名称,然后通过$m = model($controller)返回模型对象。后续的数据库操作是以模型对象来进行的,而数据库的表名默认是模型名,所以这两行代码可以理解为由哪个控制器调用就操作与哪个控制器同名的表。

跟进下search方法

php渗透审计,php对于渗透测试的代码审计

作用相当于将 $param里的数组添加到where['map'];所以get请求不要添加参数,让$param置空,返回全部数据

php渗透审计,php对于渗透测试的代码审计

接下来看edit方法

php渗透审计,php对于渗透测试的代码审计

同样的没有任何限制,跟进下isAjax方法

php渗透审计,php对于渗透测试的代码审计

可以看到只要var_ajax的伪装变量在参数中存在,就返回true

var_ajax的默认伪装名为 _ajax

php渗透审计,php对于渗透测试的代码审计

所以只要在POST请求中添加参数 _ajax=1就能进入判断

继续

php渗透审计,php对于渗透测试的代码审计

allowField用于检验请求的列名是否存在

php渗透审计,php对于渗透测试的代码审计

如果不是Ajax请求,则将id作为筛选条件,返回查询数据

配合上文的index方法获取的id,即可进行修改和查询

POC:查询:

php渗透审计,php对于渗透测试的代码审计

修改:

php渗透审计,php对于渗透测试的代码审计

增加和删除的代码和上面的几乎一样,所以就不分析了

增加:

php渗透审计,php对于渗透测试的代码审计

删除:

php渗透审计,php对于渗透测试的代码审计

任意文件上传

php渗透审计,php对于渗透测试的代码审计

可以看到什么过滤都没,还贴心的返回路径给你

POC:

php渗透审计,php对于渗透测试的代码审计

php渗透审计,php对于渗透测试的代码审计

0x05 一些XSS

上文已知只要控制器没做好鉴权,就可以调用Controller.php里的方法;我们可以利用这点,添加带有XSS的文本到数据库里

首先看下Base控制器

php渗透审计,php对于渗透测试的代码审计

代码很简单,但也能做到基本的鉴权

接下来看 Page.php控制器

php渗透审计,php对于渗透测试的代码审计

把父类继承的鉴权方法重写置空,不知道作者为什么要这样写,跟故意留个后门一样

其他控制器如 Product.phpService.phpXcxaccount.php都像Page.php一样无效鉴权,这里只挑两个进行演示

POC:

php渗透审计,php对于渗透测试的代码审计

php渗透审计,php对于渗透测试的代码审计

php渗透审计,php对于渗透测试的代码审计

php渗透审计,php对于渗透测试的代码审计

结语

这个cms审起来比较轻松,漏洞都比较简单且典型,属于有手就行系列。