Attacker Value
High
(1 user assessed)
Exploitability
High
(1 user assessed)
User Interaction
None
Privileges Required
None
Attack Vector
Network
0

CVE-2020-2509

Disclosure Date: April 16, 2021
Exploited in the Wild
Add MITRE ATT&CK tactics and techniques that apply to this CVE.
Initial Access
Techniques
Validation
Validated

Description

A command injection vulnerability has been reported to affect QTS and QuTS hero. If exploited, this vulnerability allows attackers to execute arbitrary commands in a compromised application. We have already fixed this vulnerability in the following versions: QTS 4.5.2.1566 Build 20210202 and later QTS 4.5.1.1495 Build 20201123 and later QTS 4.3.6.1620 Build 20210322 and later QTS 4.3.4.1632 Build 20210324 and later QTS 4.3.3.1624 Build 20210416 and later QTS 4.2.6 Build 20210327 and later QuTS hero h4.5.1.1491 build 20201119 and later

Add Assessment

2
Ratings
  • Attacker Value
    High
  • Exploitability
    High
Technical Analysis

Not sure this is the vuln (and I can’t test it), but it stood out to me because the exec_mount() function no longer calls popen(3)… or much of anything else:

 int32_t exec_mount(int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5, int32_t a6) {
-    int32_t str3;
-    memset(&str3, 0, (int32_t)&g2);
-    int32_t str4;
-    memset(&str4, 0, (int32_t)&g1);
-    sprintf((char *)&str3, "mount.cifs -o \"username=%s,password=\"%s\",soft,iocharset=utf8,%s%s\" %s %s 2>&1", (char *)a3, (char *)a4, (char *)a5, (char *)a6, (char *)a1, (char *)a2);
-    struct _IO_FILE * stream = popen((char *)&str3, "r");
-    char * str = fgets((char *)&str4, (int32_t)&g265, stream);
-    int32_t result = 0;
-    if (str != NULL) {
-        while (strstr((char *)&str4, (char *)((int32_t)&g177 + 0x109d4)) == NULL) {
-            char * str2 = fgets((char *)&str4, (int32_t)&g265, stream);
-            result = -1;
-            if (str2 == NULL) {
-                goto lab_0x10a14;
-            }
-        }
-        char * found_char_pos = strchr((char *)&str4, 40);
-        result = -13;
-        if (found_char_pos != NULL) {
-            char * str5 = (char *)((int32_t)found_char_pos + 1);
-            *strchr(str5, 41) = 0;
-            sscanf(str5, "%d");
-            result = -1;
-        }
-    }
-  lab_0x10a14:
-    if (stream != NULL) {
-        pclose(stream);
-    }
-    return result;
+    int32_t str;
+    memset(&str, 0, (int32_t)&g2);
+    sprintf((char *)&str, "mount.cifs -o \"username=%s,password=\"%s\",soft,iocharset=utf8,%s%s\" %s %s 2>&1", (char *)a3, (char *)a4, (char *)a5, (char *)a6, (char *)a1, (char *)a2);
+    return 0;
 }

The CIFS_Mount_Speed() function no longer calls system(3) either:

 int32_t CIFS_Mount_Speed(int32_t a1, int32_t a2, int32_t a3, int32_t a4) {
     int32_t str;
     memset(&str, 0, (int32_t)&g1);
     int32_t str2;
-    memset(&str2, 0, (int32_t)&g83);
+    memset(&str2, 0, (int32_t)&g82);
     int32_t v1 = 0;
     int32_t v2;
-    memset(&v2, 0, (int32_t)&g80);
+    memset(&v2, 0, (int32_t)&g79);
     int32_t v3;
     memset(&v3, 0, 128);
     int32_t v4;
     function_3a18((int32_t)((char)v4 == 47) + a2, &v1);
     int32_t v5;
     function_3a18(a3, &v5);
     function_3a18(a4, &v3);
     char * v6 = (char *)a1;
     sprintf((char *)&str, "//%s/%s", v6, &v1);
     sprintf((char *)&str2, "%s/%s/%s/%s", "/mnt/RTRR_CIFS", v6, &v3, &v1);
     int32_t str3;
     sprintf((char *)&str3, "mkdir -p %s", &str2);
-    system((char *)&str3);
     int32_t v7;
-    memcpy(&v7, (int32_t *)((int32_t)&g169 + 0x10bb0), (int32_t)&g90);
+    memcpy(&v7, (int32_t *)((int32_t)&g158 + 0x10a7c), (int32_t)&g89);
     int32_t v8;
-    memcpy(&v8, (int32_t *)((int32_t)&g169 + 0x10df0), 128);
+    memcpy(&v8, (int32_t *)((int32_t)&g158 + 0x10cbc), 128);
     int32_t v9 = &v7;
     int32_t v10 = function_3e20(&str, &str2, a4, &v5, v9, &v8);
     int32_t result = 0;
     while (v10 != 0) {
         int32_t v11;
         int32_t v12 = function_3e20(&str, &str2, a4, &v5, v9, &v11);
         result = 0;
         if (v12 == 0) {
             break;
         }
         v9 += 64;
         if (v9 == (int32_t)&v5) {
             result = -v12;
             return result;
         }
         v10 = function_3e20(&str, &str2, a4, &v5, v9, &v8);
         result = 0;
     }
-  lab_0x10c7c:
+  lab_0x10b6c:
     return result;
 }

function_3e20() above is actually exec_mount(). Sorry about that.

CVSS V3 Severity and Metrics
Base Score:
9.8 Critical
Impact Score:
5.9
Exploitability Score:
3.9
Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector (AV):
Network
Attack Complexity (AC):
Low
Privileges Required (PR):
None
User Interaction (UI):
None
Scope (S):
Unchanged
Confidentiality (C):
High
Integrity (I):
High
Availability (A):
High

General Information

Vendors

  • QNAP Systems Inc.

Products

  • QTS,
  • QuTS hero

Exploited in the Wild

Reported by:

Additional Info

Technical Analysis