Module: Msf::Exploit::Remote::HTTP::ManageEngineAdauditPlus::Login
- Includes:
- StatusCodes, TargetInfo, URIs, Msf::Exploit::Remote::HttpClient
- Included in:
- Msf::Exploit::Remote::HTTP::ManageEngineAdauditPlus
- Defined in:
- lib/msf/core/exploit/remote/http/manage_engine_adaudit_plus/login.rb
Constant Summary
Constants included from StatusCodes
StatusCodes::CONNECTION_FAILED, StatusCodes::NO_ACCESS, StatusCodes::NO_BUILD_NUMBER, StatusCodes::NO_DOMAINS, StatusCodes::SUCCESS, StatusCodes::UNEXPECTED_REPLY
Instance Attribute Summary
Attributes included from Msf::Exploit::Remote::HttpClient
Instance Method Summary collapse
-
#adaudit_plus_login(auth_domain, user = '', pass = '', only_get_cookie = false) ⇒ Hash
Performs a ManageEngine ADAudit Plus login.
Methods included from URIs
#adaudit_api_alertprofiles_save_uri, #adaudit_api_js_message_uri, #adaudit_plus_configured_domains_uri, #adaudit_plus_gpo_watcher_data_uri, #adaudit_plus_jump_to_js_uri, #adaudit_plus_license_details_uri, #adaudit_plus_login_uri
Methods included from Msf::Exploit::Remote::HttpClient
#basic_auth, #cleanup, #configure_http_login_scanner, #connect, #connect_ws, #deregister_http_client_options, #disconnect, #download, #full_uri, #handler, #http_fingerprint, #initialize, #lookup_http_fingerprints, #normalize_uri, #path_from_uri, #peer, #proxies, #reconfig_redirect_opts!, #request_opts_from_url, #request_url, #rhost, #rport, #send_request_cgi, #send_request_cgi!, #send_request_raw, #service_details, #setup, #ssl, #ssl_version, #strip_tags, #target_uri, #validate_fingerprint, #vhost
Methods included from Auxiliary::Report
#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot
Methods included from Metasploit::Framework::Require
optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines
Methods included from TargetInfo
#adaudit_plus_grab_build, #adaudit_plus_grab_configured_domains, #adaudit_plus_grab_domain_aliases, #adaudit_plus_target_check, #gpo_watcher_data_check
Methods included from StatusCodes
Instance Method Details
#adaudit_plus_login(auth_domain, user = '', pass = '', only_get_cookie = false) ⇒ Hash
Performs a ManageEngine ADAudit Plus login.
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/msf/core/exploit/remote/http/manage_engine_adaudit_plus/login.rb', line 24 def adaudit_plus_login(auth_domain, user = '', pass = '', = false) .clear # let's start fresh # Visit the default homepage to retrieve some of the baseline cookies needed to authenticate. = send_request_cgi({ 'uri' => normalize_uri(target_uri.path), 'method' => 'GET', 'keep_cookies' => true }) unless return { 'status' => adaudit_plus_status::CONNECTION_FAILED, 'message' => 'Connection failed.' } end # Make sure the target is actually ManageEngine ADAudit Plus unless .code == 200 && .body =~ /<title>ADAudit Plus/ return { 'status' => adaudit_plus_status::UNEXPECTED_REPLY, 'message' => 'Target does not seem to be ADAudit Plus.' } end # Check if we have an initial adapcsrf cookie with the expected format unless .headers.include?('Set-Cookie') && . =~ /adapcsrf=[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/ return { 'status' => adaudit_plus_status::UNEXPECTED_REPLY, 'message' => 'Failed to obtain the baseline cookies needed to proceed with authentication.' } end # Visit the adaudit_plus_jump_to_js_uri page to grab more cookies needed for authentication. vprint_status('Attempting to obtain the required cookies for authentication') = send_request_cgi({ 'uri' => adaudit_plus_jump_to_js_uri, 'method' => 'GET', 'keep_cookies' => true }) unless return { 'status' => adaudit_plus_status::CONNECTION_FAILED, 'message' => 'Connection failed.' } end # check if we have a new adapcsrf cookie with the expected format, which is different # from the initial adapcsrf cookie format that we got before visiting the adaudit_plus_jump_to_js_uri URI. unless .code == 200 && .headers.include?('Set-Cookie') && . =~ /adapcsrf=[a-f0-9]{128}/ return { 'status' => adaudit_plus_status::UNEXPECTED_REPLY, 'message' => 'Failed to obtain the jump_to_js cookies required for authentication.' } end vprint_status('Trying to authenticate...') post_vars = { 'forChecking' => '', 'j_username' => user.to_s, 'j_password' => pass.to_s, 'domainName' => auth_domain.to_s, 'AUTHRULE_NAME' => 'Authenticator' } res_login = send_request_cgi({ 'uri' => adaudit_plus_login_uri, 'method' => 'POST', 'keep_cookies' => true, 'vars_post' => post_vars }) # Check to see if the connection succeeded. return { 'status' => adaudit_plus_status::CONNECTION_FAILED, 'message' => 'Connection failed' } unless res_login # Check to see if we got the right response code and the expected cookies. unless res_login.code == 303 && res_login.headers.include?('Set-Cookie') # Matches something like JSESSIONIDADAP=50E42FBF96E820A6099A1F38FA5A4854; JSESSIONIDADAPSSO=7EB091F6BB9A7A4C4476419DFC11E2A1; # Or this JSESSIONIDADAP=50E42FBF96E820A6099A1F38FA5A4854; JSESSIONIDSSO=7EB091F6BB9A7A4C4476419DFC11E2A1; # Or even this JSESSIONIDADAP=50E42FBF96E820A6099A1F38FA5A4854; JSESSIONIDSSO=7EB091F6BB9A7A4C4476419DFC11E2A1 unless res_login. =~ /(?:JSESSIONID[A-Z].*?=[0-9A-Z]{32};{0,1} {0,1}){2}/ return { 'status' => adaudit_plus_status::NO_ACCESS, 'message' => 'Failed to authenticate.' } end end # Check if we are actually logged in by visiting the home page. res_post_auth = send_request_cgi({ 'uri' => normalize_uri(target_uri.path), 'method' => 'GET', 'keep_cookies' => true }) return { 'status' => adaudit_plus_status::CONNECTION_FAILED, 'message' => 'Connection failed' } unless res_post_auth unless res_post_auth.code == 200 && res_post_auth.body.include?('ManageEngine ADAudit Plus web client is initializing') return { 'status' => adaudit_plus_status::NO_ACCESS, 'message' => 'The web app failed to load after authenticating' } end # Return the value of the adapcsrf cookie, which will be required for later actions. = ..select { |k| k.name == 'adapcsrf' }&.first if .blank? || .value.blank? return { 'status' => adaudit_plus_status::NO_ACCESS, 'message' => 'Failed to obtain the required adapcsrf cookie' } end # In order to get a cookie we can actually use, we need to obtain the configured domains via the API, # so we will call adaudit_plus_grab_configured_domains to retrieve this information for us. # Note that adaudit_plus_obtain_configured_domains uses the same return format as this method. adaudit_plus_grab_configured_domains(.value, ) end |