轻量级国产PHP开发框架任意文件包含简介(第一弹)
温馨提示:这篇文章已超过559天没有更新,请注意相关的内容是否还可用!
第一弹|.x/5.x框架任意文件包括简介
是一个迅速、兼容并且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年年底陆续并入为,遵循开源协议公布,从构架移植过来并做了优化和加强,同时也借鉴了美国众多优秀的框架和方式,使用面向对象的研发结构和MVC范式,融合了的观念和(标签库)、RoR的ORM映射和路径。
漏洞简述
在加载模版解析函数时存在数组覆盖的弊端,且没有对$进行相应的消毒处理,导致模板文件的模式可以被覆盖,从而造成任意文件包括漏洞的出现。
环境准备
下载框架在“\\think\.php”文件中读取如下代码:
在“\index\view\index”目录下创建一个index.html文件,不建立会发生模板文件不存在错误。
至于其它配置数据库连接文件或者框架结构,可参考文章:代码审计|.0.x框架SQL注⼊
漏洞分析
攻击者可以借助POST方法访问链接:
,
POST的数据为:=../.php,这个函数就是可以被攻击者覆盖的变量。
程序在一开始会调用“\\think\.php”文件中的方式,并传入POST数组数据,方法代码如下:
方式又调用了视图类中的方式,方法在“\\think\View.php”文件中。可以发现该办法用方式将POST数组数据合并到$this->data中,代码如下:
我们再来看fetch方法,该办法用于输出模板内容,代码定义在“\\think\.php”文件中php框架源码分析,该办法同样调用的是视图类中的fetch方法,代码如下:
查看“\\think\View.php”文件中的fetch方法,这里注代码$this->->$($,$vars,$);
在默认情况下$的值为fetch,也就是说调用了视图引擎中的fetch方法,该方式在“\\think\view\\Think.php”文件中,代码如下:
视图引擎的fetch方法又读取了模版类的fetch方法,继续跟进。我们注意到“\\think\.php”文件中短语:$this->->read($,$this->data);这是用于写入编译存储,此时$的值类似于\temp\md5(×××).php
我们跟进该read方法,在“\\think\\\File.php”文件中,我们发现程序使用方式,并用了参数,该参数的作用是:如果有冲突,则覆盖已有的数组。方法将$vars数组中的数据元素注册成函数,而$vars数组又包括了POST数组数据,这也就是造成变量覆盖的诱因。然后程序在最终包括了$文件,最终造成了任意文件包括。具体代码如下:
如果目标站点开启了,攻击者或者可以执行任意代码,攻击方式如下:
第二弹|.2.x框架SQL注入漏洞简述
虽然3.2.x使用了I方法来过滤参数,但是还是过滤不严谨,导致SQL注入发生。
基础知识
在进行漏洞分析之前,我们必须知道一下.2基础知识,这里仅介绍对本次漏洞分析有帮助的个别。
.2的目录结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
├─ThinkPHP 框架系统目录(可以部署在非web目录下面)
│ ├─Common 核心公共函数目录
│ ├─Conf 核心配置目录
│ ├─Lang 核心语言包目录
│ ├─Library 框架类库目录
│ │ ├─Think 核心Think类库包目录
│ │ ├─Behavior 行为类库目录
│ │ ├─Org Org类库包目录
│ │ ├─Vendor 第三方类库目录
│ │ ├─ ... 更多类库目录
│ ├─Mode 框架应用模式目录
│ ├─Tpl 系统模板目录
│ ├─LICENSE.txt 框架授权协议文件
│ ├─logo.png 框架LOGO文件
│ ├─README.txt 框架README文件
│ └─ThinkPHP.php 框架入口文件
我们本次的为:[0]=bind&[1]=0and(1,(0x7,user(),0x7e),1)
环境搭建
此处我们使用.2.3完整版来进行实验,下载地址:
我们先安装好,然后将下载好的.2.3完整版解压,将上面的拷贝至的网页根目录下的文件夹下,php版本这里用5.6。在目录下新建一个index.php文件,内容如下:
1
2
3
4
5
define("APP_PATH","./Application/");
define('APP_DEBUG',True);
include "ThinkPHP/ThinkPHP.php";
浏览器访问,会在目录下生成一个文件夹,目录结构如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Application
├─Common 应用公共模块
│ ├─Common 应用公共函数目录
│ └─Conf 应用公共配置文件目录
├─Home 默认生成的Home模块
│ ├─Conf 模块配置文件目录
│ ├─Common 模块函数公共目录
│ ├─Controller 模块控制器目录
│ ├─Model 模块模型目录
│ └─View 模块视图文件目录
├─Runtime 运行时目录
│ ├─Cache 模版缓存目录
│ ├─Data 数据目录
│ ├─Logs 日志目录
│ └─Temp 缓存目录
修改\\Home\\.class.php文件代码,内容如下:
1
2
3
4
5
6
7
8
9
10
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function index(){
$condition["name"] = I("name");
$data["pass"] = "1998";
$result = M("users")->where($condition)->save($data);
}
}
配置连接数据库的文件\\Conf\.php,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
return array(
'DB_TYPE' => 'mysql', // 数据库类型
'DB_HOST' => 'localhost', // 服务器地址
'DB_NAME' => 'thinkphp', // 数据库名
'DB_USER' => 'root', // 用户名
'DB_PWD' => 'root', // 密码
'DB_PORT' => 3306, // 端口
'DB_PREFIX' => '', // 数据库表前缀
'DB_CHARSET'=> 'utf8', // 字符集
'DB_DEBUG' => TRUE, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增
);
漏洞分析
现在,我们还是按照,使用反向审计的方法来进行本次审计工作。首先我们来看一下我们创建的\\Home\\.class.php文件代码,程序使用I方法来安全获得变量,如下图:
我们跟进I方法看看,I方法位于\\\.php文件中,可以提到$input变量的值等于超全局数据$_GET的值。如下图:
接着主要是对获得到的变量,使用()进行过滤,如下图:
可以发现函数尾部使用了自定义的过滤该原则,如下图:
该方式也在这个文件中定义,代码如下。可以知道的看见并没有过滤bind,如下图:
1
2
3
4
5
6
7
function think_filter(&$value){
// TODO 其他安全过滤
// 过滤查询特殊字符
if(preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i',$value)){
$value .= ' ';
}
}
再回到\\Home\\.class.php文件,看语句$=M("users")->where($)->save($data);我们跟进M方法,M方法的话就是新建了一个Think\Model类,如下图:
然后调用了Think\Model类的where方法,该原则位于\\\Think\Model.class.php文件中,这里实际上就是做了添加$[‘where’]的操作,如下图:
我们再次看save方法,在程序末尾有个操作,继续跟进
方法位于\\\Think\Db\.class.php文件中,方法主要做了set[0]==:0,我们主要关注方法。
我们跟进方法,发现其中拼接了经过方式处理的语句,如下图:
我们跟进方法,会看到当$val[0]等于bind的之后,直接将参数进行拼接,如右图:
最后,执行攻击者构造的SQL语句,效果如下:
总结
笔者也是第一次审计.2框架,在审计这套框架前还找了网络上的视频迅速入门了下,再结合.2手册,完成这次漏洞的审计。当然,文章有不当之处,还希望你们斧正。
第三弹|.0.x框架SQL注入漏洞简述
虽然5.0.x框架引入了参数化查询方法,来操作数据库,但是在和技巧中,传入的参数可控,且无严密过滤,最终造成本次SQL注入漏洞出现。
基础知识
在进行漏洞分析之前,我们必须知道一下基础知识,这里仅介绍对本次漏洞分析有帮助的个别。
.0的目录结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
thinkphp 应用部署目录
├─application 应用目录(可设置)
│ ├─common 公共模块目录(可更改)
│ ├─index 模块目录(可更改)
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录
│ │ ├─view 视图目录
│ │ └─ ... 更多类库目录
│ ├─command.php 命令行工具配置文件
│ ├─common.php 应用公共(函数)文件
│ ├─config.php 应用(公共)配置文件
│ ├─database.php 数据库配置文件
│ ├─tags.php 应用行为扩展定义文件
│ └─route.php 路由配置文件
├─extend 扩展类库目录(可定义)
├─public WEB 部署目录(对外访问目录)
│ ├─static 静态资源存放目录(css,js,image)
│ ├─index.php 应用入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于 apache 的重写
├─runtime 应用的运行时目录(可写,可设置)
├─vendor 第三方类库目录(Composer)
├─thinkphp 框架系统目录
│ ├─lang 语言包目录
│ ├─library 框架核心类库目录
│ │ ├─think Think 类库包目录
│ │ └─traits 系统 Traits 目录
│ ├─tpl 系统模板目录
│ ├─.htaccess 用于 apache 的重写
│ ├─.travis.yml CI 定义文件
│ ├─base.php 基础定义文件
│ ├─composer.json composer 定义文件
│ ├─console.php 控制台入口文件
│ ├─convention.php 惯例配置文件
│ ├─helper.php 助手函数文件(可选)
│ ├─LICENSE.txt 授权说明文件
│ ├─phpunit.xml 单元测试配置文件
│ ├─README.md README 文件
│ └─start.php 框架引导文件
├─build.php 自动生成定义文件(参考)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
我们本次的为:[0]=inc&name[1]=(1,(0x7,user(),0x7e),1)&name[2]=1,解释如下:
1
2
http://localhost/thinkphp/ public/ index.php/ index/ index/ index
域名 网站目录 对外访问目录 入口文件 前台 控制器 方法名
变量获取
1
2
$name = input("get.name/a");
input()为TP框架的助手函数,get.name/a 表示获取get传入的name变量,并将其强制转换为数组类型
数据库查询
1
2
Db::table("users")->where(["id"=>1])->insert(["username"=>$name]);
TP框架采用的是PDO方式对数据库进行查询
环境搭建
在知道了基本知识后,我们可以开始建立环境。这里我们使用5.0.14版本来进行实验,下载地址:
我们先安装好,然后将下载好的5.0.14解压至的网站根目录下,安装5.0.14需要、PDO、Curl三个软件,php版本这里用5.6。
接着我们必须配置连接数据库的文件,并进入的调试功能。在此之前,你必须先在数据库中建立用于检测的数据,例如这里我用成为数据库名,那么就在mysql命令行下执行;但是在制定一个users表,列名有id,,,执行tableusers(idintkey,(20),(30));即可,最后我们往表中插入测试数据,命令行执行intousers(id,,)(1,"test","");这种虽然测试数据建立成功了。
配置连接数据库的文件,并进入的安装功能,如下图:
最后修改文件\index\\Index.php的内容,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace app\index\controller;
use think\Db;
class Index
{
public function index()
{
$name = input("get.name/a");
Db::table("users")->where(["id"=>1])->insert(["username"=>$name]);
return "ThinkPHP SQL Test.";
}
}
修改好后,访问我们的就可以触发漏洞了。
漏洞分析
首先,我们了解方式存在漏洞,那就查看方式的详细实现。该原则位于\\think\db\.php文件中,我们可以看见在变量开头调用了方式,并将$data作为参数传入,$data的值是我们借助get方式传入的一个变量种类的数据,如下图:
我们跟进方法,该原则也在\\think\db\.php文件中。可以看见,在结尾处有个段落,而且处于该词语后,会跳到case'inc'的地方,这里关键就是说说$this->是否有对$val[1]数组进行过滤了,因为$val[1]数组就是我们中的(1,(0x7,user(),0x7e),1),如下图:
继续跟进方法,会看到直接将传入的$key返回了,没有进行任何过滤。
我们再重回最起初的方式,加上调试语句,看看此时的sql语句成为了哪些样子,如下图:
另一处函数的注入与这个是类似的,这里就不在赘述。
总结
笔者也是第一次审计框架,在审计这套框架前还找了网络上的视频迅速入门了下,再结合.0手册,完成这次漏洞的审计。当然,文章有不当之处php框架源码分析,还希望你们斧正。
本文来自网络,如有侵权请联系网站客服进行删除
还没有评论,来说两句吧...