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

CVE-2021-22652

Disclosure Date: February 11, 2021
Add MITRE ATT&CK tactics and techniques that apply to this CVE.

Description

Access to the Advantech iView versions prior to v5.7.03.6112 configuration are missing authentication, which may allow an unauthorized attacker to change the configuration and obtain code execution.

Add Assessment

3
Ratings
Technical Analysis

The patch adds authentication to updateSystemSettings(), exportInventoryTable(), and a number of other methods.

   private boolean updateSystemSettings(HttpServletRequest request, HttpServletResponse response) {
     boolean bReturn = false;
     boolean bDataOk = false;
     StringBuffer strResults = new StringBuffer();
     String strPROMFilePath = new String();
     String strExportFilePath = new String();
     String strImportFilePath = new String();
     String strConfigFilePath = new String();
     String strDbBackupFilePath = new String();
     String strZTPTemplatesPath = new String();
     String strSSHPort = new String();
     String strTFTPPort = new String();
     String strMaxBackupFiles = new String();
     String strNetworkScanTimeout = new String();
     String strUserSessionTimeout = new String();
     String strJSONObj = request.getParameter("json_obj");
     String strJSONNamingObj = request.getParameter("json_naming_obj");
     SystemTable tempSystemTable = new SystemTable();
     int nUseCustomNaming = 0;
     JSONObject objJSON = null;
     DeviceTreeTable tempDeviceTreeTable = new DeviceTreeTable();
+    HttpSession session = request.getSession();
+    if (session == null || session.getAttribute("user_id") == null || session.getAttribute("user_name") == null || session.getAttribute("user_level") == null) {
+      strResults.append("Failed to update system settings: User Not Login");
+      System.out.println("Failed to update system settings: User Not Login");
+      response.setContentType("text/html");
+      try {
+        PrintWriter out = response.getWriter();
+        out.println(strResults);
+      } catch (Exception e) {
+        System.out.println("NetworkServlet-updateSystemSettings: " + e.toString());
+      }
+      return bReturn;
+    }
+    boolean bSecVuln = false;
     try {
       objJSON = new JSONObject(new JSONTokener(strJSONObj));
       strPROMFilePath = objJSON.getString("PROMPATH");
       strExportFilePath = objJSON.getString("EXPORTPATH");
       strImportFilePath = objJSON.getString("IMPORTPATH");
       strConfigFilePath = objJSON.getString("CONFIGPATH");
       strDbBackupFilePath = objJSON.getString("DBBACKUPPATH");
       strZTPTemplatesPath = objJSON.getString("ZTPTEMPLATESPATH");
       strSSHPort = objJSON.getString("SSHPORT");
       strTFTPPort = objJSON.getString("TFTPPORT");
       strMaxBackupFiles = objJSON.getString("MAXBACKUPFILES");
       strNetworkScanTimeout = objJSON.getString("NETWORKSCANTIMEOUT");
       strUserSessionTimeout = objJSON.getString("USERSESSIONTIMEOUT");
       nUseCustomNaming = objJSON.getInt("USECUSTOMNAMING");
       bDataOk = true;
-      boolean sqlInj = false;
+      boolean sqlInj1 = false, filepathDir1 = true;
+      boolean sqlInj2 = false, filepathDir2 = true;
+      boolean sqlInj3 = false, filepathDir3 = true;
+      boolean sqlInj4 = false, filepathDir4 = true;
+      boolean sqlInj5 = false, filepathDir5 = true;
+      boolean sqlInj6 = false, filepathDir6 = true;
       CUtils cutil = new CUtils();
-      if (strPROMFilePath != null && !strPROMFilePath.equals(""))
-        sqlInj = cutil.checkSQLInjection(strPROMFilePath);
-      if (sqlInj)
+      if (strPROMFilePath != null && !strPROMFilePath.equals("")) {
+        sqlInj1 = cutil.checkSQLInjection(strPROMFilePath);
+        filepathDir1 = cutil.checkDirectory(strPROMFilePath);
+      }
+      if (strExportFilePath != null && !strExportFilePath.equals("")) {
+        sqlInj2 = cutil.checkSQLInjection(strExportFilePath);
+        filepathDir2 = cutil.checkDirectory(strExportFilePath);
+      }
+      if (strImportFilePath != null && !strImportFilePath.equals("")) {
+        sqlInj3 = cutil.checkSQLInjection(strImportFilePath);
+        filepathDir3 = cutil.checkDirectory(strImportFilePath);
+      }
+      if (strConfigFilePath != null && !strConfigFilePath.equals("")) {
+        sqlInj4 = cutil.checkSQLInjection(strConfigFilePath);
+        filepathDir4 = cutil.checkDirectory(strConfigFilePath);
+      }
+      if (strDbBackupFilePath != null && !strDbBackupFilePath.equals("")) {
+        sqlInj5 = cutil.checkSQLInjection(strDbBackupFilePath);
+        filepathDir5 = cutil.checkDirectory(strDbBackupFilePath);
+      }
+      if (strZTPTemplatesPath != null && !strZTPTemplatesPath.equals("")) {
+        sqlInj6 = cutil.checkSQLInjection(strZTPTemplatesPath);
+        filepathDir6 = cutil.checkDirectory(strZTPTemplatesPath);
+      }
+      if (sqlInj1 || sqlInj2 || sqlInj3 || sqlInj4 || sqlInj5 || sqlInj6)
+        bDataOk = false;
+      if (!filepathDir1 || !filepathDir2 || !filepathDir3 || !filepathDir4 ||
+        !filepathDir5 || !filepathDir6) {
+        bSecVuln = true;
         bDataOk = false;
+      }
     } catch (Exception exception) {}
     if (bDataOk) {
       if (nUseCustomNaming == 1)
         bDataOk = tempDeviceTreeTable.saveNamingData(strJSONNamingObj);
       if (bDataOk) {
         if (tempSystemTable.updateSystemSettings(strJSONObj)) {
           strResults.append("[{\"PROMPATH\":\"");
           strResults.append(addBackslash(strPROMFilePath));
           strResults.append("\",\"EXPORTPATH\":\"");
           strResults.append(addBackslash(strExportFilePath));
           strResults.append("\",\"IMPORTPATH\":\"");
           strResults.append(addBackslash(strImportFilePath));
           strResults.append("\",\"CONFIGPATH\":\"");
           strResults.append(addBackslash(strConfigFilePath));
           strResults.append("\",\"DBBACKUPPATH\":\"");
           strResults.append(addBackslash(strDbBackupFilePath));
           strResults.append("\",\"ZTPTEMPLATESPATH\":\"");
           strResults.append(addBackslash(strZTPTemplatesPath));
           strResults.append("\",\"SSHPORT\":\"");
           strResults.append(addBackslash(strSSHPort));
           strResults.append("\",\"TFTPPORT\":\"");
           strResults.append(addBackslash(strTFTPPort));
           strResults.append("\",\"MAXBACKUPFILES\":\"");
           strResults.append(addBackslash(strMaxBackupFiles));
           strResults.append("\",\"NETWORKSCANTIMEOUT\":\"");
           strResults.append(addBackslash(strNetworkScanTimeout));
           strResults.append("\",\"USERSESSIONTIMEOUT\":\"");
           strResults.append(addBackslash(strUserSessionTimeout));
           strResults.append("\",\"USECUSTOMNAMING\":\"");
           strResults.append(Integer.toString(nUseCustomNaming));
           if (nUseCustomNaming == 1) {
             if (tempDeviceTreeTable.createCustomNaming()) {
               String strTempNaming = tempDeviceTreeTable.getCustomNaming();
               strResults.append("\",\"CUSTOMNAMETEMPLATE\":\"" + strTempNaming + "\"},");
             } else {
               strResults.append("\",\"CUSTOMNAMETEMPLATE\":\"\"},");
             }
             if (tempDeviceTreeTable.getNamingData()) {
               strResults.append(String.valueOf(tempDeviceTreeTable.getJSONObject()) + "]");
             } else {
               strResults.append("{\"IVIEW_NAMING\":\"\"}]");
             }
           } else {
             strResults.append("\",\"CUSTOMNAMETEMPLATE\":\"\"},{\"IVIEW_NAMING\":\"\"}]");
           }
         } else {
           strResults.append("Failed to save System Settings data.");
         }
       } else {
         strResults.append("Failed to save custom naming format data.");
       }
+    } else if (bSecVuln) {
+      strResults.append("Failed to updateSystemSettings: File Path Error.");
     } else {
       strResults.append("Failed to parse updateSystemSettings data.");
     }
     response.setContentType("text/html");
     try {
       PrintWriter out = response.getWriter();
       out.println(strResults.toString());
     } catch (Exception e) {
-      System.out.println("NetworkServlet-retrieveSystemSettings: " + e.toString());
+      System.out.println("NetworkServlet-updateSystemSettings: " + e.toString());
     }
     return bReturn;
   }
   private boolean exportInventoryTable(HttpServletRequest request, HttpServletResponse response) {
     boolean bReturn = false;
     String strResults = new String();
     String strColumnList = request.getParameter("col_list");
     String strSeperator = request.getParameter("sep_type");
     String strFilename = request.getParameter("filename");
     String strSearchTerm = request.getParameter("query");
     String strSearchCol = request.getParameter("qtype");
     String strSortCol = request.getParameter("sortname");
     String strSortOrder = request.getParameter("sortorder");
     DeviceTreeTable tempDeviceTreeTable = new DeviceTreeTable();
+    HttpSession session = request.getSession();
+    if (session == null || session.getAttribute("user_id") == null || session.getAttribute("user_name") == null || session.getAttribute("user_level") == null) {
+      strResults = "Failed to export inventory table: User Not Login";
+      System.out.println("Failed to export inventory table: User Not Login");
+      response.setContentType("text/html");
+      try {
+        PrintWriter out = response.getWriter();
+        out.println(strResults);
+      } catch (Exception e) {
+        System.out.println("NetworkServlet-exportInventoryTable: " + e.toString());
+      }
+      return bReturn;
+    }
     try {
       Thread.sleep(3000L);
     } catch (InterruptedException interruptedException) {}
-    boolean sqlInj1 = false, sqlInj2 = false, dtrl = false;
+    boolean sqlInj0 = false, sqlInj1 = false, sqlInj2 = false, dtrl = false;
     CUtils cutil = new CUtils();
+    if (strColumnList != null && !strColumnList.equals(""))
+      sqlInj0 = cutil.checkSQLInjection(strColumnList);
     if (strSearchTerm != null && !strSearchTerm.equals(""))
       sqlInj1 = cutil.checkSQLInjection(strSearchTerm);
     if (strSearchCol != null && !strSearchCol.equals(""))
       sqlInj2 = cutil.checkSQLInjection(strSearchCol);
     if (strFilename != null && !strFilename.equals(""))
-      dtrl = cutil.checkFileNameIncludePath(strFilename);
-    if (!sqlInj1 && !sqlInj2 && !dtrl) {
+      dtrl = cutil.checkFileNameIncludePath(strFilename, "csv");
+    if (!sqlInj0 && !sqlInj1 && !sqlInj2 && !dtrl) {
       if (tempDeviceTreeTable.exportInventoryTable(strColumnList, strSeperator, strFilename, strSearchTerm, strSearchCol, strSortCol, strSortOrder)) {
         strResults = "Export has completed.";
       } else {
         strResults = "Export failed.";
       }
     } else if (dtrl && !sqlInj1 && !sqlInj2) {
-      strResults = "Export failed: Directory Traversal Vulnerability";
+      strResults = "Export failed: Directory/Path Traversal Vulnerability";
     } else if (!dtrl && (sqlInj1 || sqlInj2)) {
       strResults = "Export failed: SQL Injection Vulnerability";
     } else {
       strResults = "Export failed: Security Vulnerability";
     }
     response.setContentType("text/html");
     try {
       PrintWriter out = response.getWriter();
       out.println(strResults);
     } catch (Exception e) {
       System.out.println("NetworkServlet.exportInventoryTable: " + e.toString());
     }
     return bReturn;
   }
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

Products

  • Advantech iView

Additional Info

Technical Analysis