Tongda Oa V11 6 Print Php Arbitrary File Deletion & Rce
Tongda OA v11.6 print.php arbitrary file deletion & RCE
Vulnerability Description
Delete the authentication file contained in the upload point through any file vulnerability, resulting in unauthorized access to achieve arbitrary file upload
Vulnerability Impact
Tongda OA v11.6
Environment construction
Tongda OA v11.6 download link: https://cdndown.tongda2000.com/oa/2019/TDOA11.6.exe
Vulnerability reappears
Use the decryption tool SeayDzend (zend decryption tool) to decrypt the encryption code of Tongda OA
After decryption is completed, check the wewebroot\general\data_center\utils\upload.php
file
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
include_once "inc/auth.inc.php";
include_once "./utils.func.php";
$HTML_PAGE_TITLE = _("上传文件");
include_once "inc/header.inc.php";
$error = "";
$msg = "";
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"]);
}
else if ($action == "unupload") {
if ($filetype == "xls") {
$uploaddir = MYOA_ATTACH_PATH . "data_center/attachment/" . trim($filename) . ".xls";
if (is_file($uploaddir)) {
unlink($uploaddir);
}
}
else if ($filetype == "img") {
$uploaddir = MYOA_ATTACH_PATH . "data_center/images/" . trim($filename);
if (is_file($uploaddir)) {
unlink($uploaddir);
}
}
else if ($filetype == "attach") {
$uploaddir = MYOA_ATTACH_PATH . "data_center/attachment/" . trim($filename);
if (is_file($uploaddir)) {
unlink($uploaddir);
}
}
}
echo "{";
echo "new_name:'$s_n',\n";
echo "error: '" . $error . "',\n";
echo "msg: '" . $msg . "'\n";
echo "}";
echo "<body>\r\n</body>\r\n</html>";
?>
Includes the file auth.inc.php
in the first line`
1
include_once "inc/auth.inc.php";
You can see that this file is used to check whether you are logged in. This vulnerability cannot be exploited if you are not logged in.
View the \webroot\module\appbuilder\assets\print.php
file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$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();
}
Here you can see the page to get the value of the guid parameter Use the file_exists function
to determine whether the file exists. If you have not checked, unlink will be executed and delete the file without verification.
1.txt files can be created locally in the \webroot\inc
directory
Then visit
1
/module/appbuilder/assets/print.php?guid=../../../webroot/inc/1.txt
This 1.txt file will be deleted, which also means that you can delete the auth.inc.php
login verification file
Go back to upload.php file for code audit
Determine whether the variable $action
is upload, then determine the file type. If it is not xls and img, enter the else branch
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
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"]);
}
In this code, if the $from_rep
variable does not exist, it will jump to the following code
1
2
3
4
5
6
7
8
9
10
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)) {
}
}
Here you directly splice the $repkid
variable, which means that malicious files can be uploaded to the specified directory through directory travel.