Class: Metasploit::Framework::LoginScanner::ManageEngineDesktopCentral

Inherits:
HTTP
  • Object
show all
Defined in:
lib/metasploit/framework/login_scanner/manageengine_desktop_central.rb

Constant Summary collapse

DEFAULT_PORT =
8020
PRIVATE_TYPES =
[ :password ]
LOGIN_STATUS =

Shorter name

Metasploit::Model::Login::Status

Constants inherited from HTTP

HTTP::AUTHORIZATION_HEADER, HTTP::DEFAULT_HTTP_NOT_AUTHED_CODES, HTTP::DEFAULT_HTTP_SUCCESS_CODES, HTTP::DEFAULT_REALM, HTTP::DEFAULT_SSL_PORT, HTTP::LIKELY_PORTS, HTTP::LIKELY_SERVICE_NAMES, HTTP::REALM_KEY

Instance Attribute Summary

Attributes inherited from HTTP

#digest_auth_iis, #evade_header_folding, #evade_method_random_case, #evade_method_random_invalid, #evade_method_random_valid, #evade_pad_fake_headers, #evade_pad_fake_headers_count, #evade_pad_get_params, #evade_pad_get_params_count, #evade_pad_method_uri_count, #evade_pad_method_uri_type, #evade_pad_post_params, #evade_pad_post_params_count, #evade_pad_uri_version_count, #evade_pad_uri_version_type, #evade_shuffle_get_params, #evade_shuffle_post_params, #evade_uri_dir_fake_relative, #evade_uri_dir_self_reference, #evade_uri_encode_mode, #evade_uri_fake_end, #evade_uri_fake_params_start, #evade_uri_full_url, #evade_uri_use_backslashes, #evade_version_random_invalid, #evade_version_random_valid, #http_password, #http_success_codes, #http_username, #keep_connection_alive, #kerberos_authenticator_factory, #method, #ntlm_domain, #ntlm_send_lm, #ntlm_send_ntlm, #ntlm_send_spn, #ntlm_use_lm_key, #ntlm_use_ntlmv2, #ntlm_use_ntlmv2_session, #uri, #user_agent, #vhost

Instance Method Summary collapse

Methods inherited from HTTP

#authentication_required?, #send_request

Instance Method Details

#attempt_login(credential) ⇒ Result

Attempts to login to MSP.

Parameters:

Returns:

  • (Result)

    A Result object indicating success or failure

[View source] [View on GitHub]

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/metasploit/framework/login_scanner/manageengine_desktop_central.rb', line 111

def (credential)
  result_opts = {
    credential: credential,
    status: LOGIN_STATUS::INCORRECT,
    proof: nil,
    host: host,
    port: port,
    protocol: 'tcp',
    service_name: ssl ? 'https' : 'http',
  }

  begin
    result_opts.merge!((credential.public, credential.private))
  rescue ::Rex::ConnectionError => e
    # Something went wrong during login. 'e' knows what's up.
    result_opts.merge!(status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: e.message)
  end

  Result.new(result_opts)
end

#check_setupBoolean

Checks if the target is ManageEngine Desktop Central.

Returns:

  • (Boolean)

    TrueClass if target is MSP, otherwise FalseClass

[View source] [View on GitHub]

18
19
20
21
22
23
24
25
26
27
# File 'lib/metasploit/framework/login_scanner/manageengine_desktop_central.rb', line 18

def check_setup
   = normalize_uri("#{uri}/configurations.do")
  res = send_request({'uri' => })

  if res && res.body.include?('ManageEngine Desktop Central')
    return true
  end

  false
end

#get_hidden_inputs(res) ⇒ Hash

Returns the hidden inputs

Parameters:

Returns:

  • (Hash)

    Input fields

[View source] [View on GitHub]

46
47
48
49
50
51
52
53
54
# File 'lib/metasploit/framework/login_scanner/manageengine_desktop_central.rb', line 46

def get_hidden_inputs(res)
  found_inputs = {}
  res.body.scan(/(<input type="hidden" .+>)/).flatten.each do |input|
    name  = input.scan(/name="(\w+)"/).flatten[0] || ''
    value = input.scan(/value="([\w\.\-]+)"/).flatten[0] || ''
    found_inputs[name] = value
  end
  found_inputs
end

#get_login_state(username, password) ⇒ Hash

Actually doing the login. Called by #attempt_login

Parameters:

  • username (String)

    The username to try

  • password (String)

    The password to try

Returns:

  • (Hash)
    • :status [Metasploit::Model::Login::Status]

    • :proof [String] the HTTP response body

[View source] [View on GitHub]

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/metasploit/framework/login_scanner/manageengine_desktop_central.rb', line 78

def (username, password)
   = normalize_uri("#{uri}/j_security_check")
   = 

  res = send_request({
    'uri' => ,
    'method' => 'POST',
    'cookie' => ['sid'],
    'vars_post' => {
      'j_username' => username,
      'j_password' => password,
      'Button' => 'Sign+in',
      'buildNum' => ['buildNum'],
      'clearCacheBuildNum' => ['clearCacheBuildNum']
    }
  })

  unless res
    return {:status => LOGIN_STATUS::UNABLE_TO_CONNECT, :proof => res.to_s}
  end

  if res.code == 302
    return {:status => LOGIN_STATUS::SUCCESSFUL, :proof => res.to_s}
  end

  {:status => LOGIN_STATUS::INCORRECT, :proof => res.to_s}
end

#get_required_login_itemsHash

Returns all the items needed to login

Returns:

  • (Hash)

    Login items

[View source] [View on GitHub]

60
61
62
63
64
65
66
67
68
# File 'lib/metasploit/framework/login_scanner/manageengine_desktop_central.rb', line 60

def 
  items = {}
   = normalize_uri("#{uri}/configurations.do")
  res = send_request({'uri' => })
  return items unless res
  items.merge!({'sid' => get_sid(res)})
  items.merge!(get_hidden_inputs(res))
  items
end

#get_sid(res) ⇒ String

Returns the latest sid from MSP

Parameters:

Returns:

  • (String)

    The session ID for MSP

[View source] [View on GitHub]

34
35
36
37
38
# File 'lib/metasploit/framework/login_scanner/manageengine_desktop_central.rb', line 34

def get_sid(res)
  cookies = res.get_cookies
  sid = cookies.scan(/(DCJSESSIONID=\w+);*/).flatten[0] || ''
  sid
end