Class: Metasploit::Framework::LoginScanner::BavisionCameras
- Defined in:
- lib/metasploit/framework/login_scanner/bavision_cameras.rb
Constant Summary collapse
- DEFAULT_PORT =
80
- 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
-
#attempt_login(credential) ⇒ Result
Attempts to login to the camera.
-
#check_setup ⇒ String
Checks if the target is BAVision Camera’s web server.
-
#digest_auth(user, password, response) ⇒ Object
The Rex HTTP Digest auth is making the camera server to refuse to respond for some reason.
-
#try_digest_auth(cred) ⇒ Object
Auth to the server using digest auth.
Methods inherited from HTTP
#authentication_required?, #send_request
Instance Method Details
#attempt_login(credential) ⇒ Result
Attempts to login to the camera. This is called first.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/metasploit/framework/login_scanner/bavision_cameras.rb', line 103 def attempt_login(credential) result_opts = { credential: credential, status: Metasploit::Model::Login::Status::INCORRECT, proof: nil, host: host, port: port, protocol: 'tcp' } begin result_opts.merge!(try_digest_auth(credential)) rescue ::Rex::ConnectionError, BavisionCamerasException => e # Something went wrong during login. 'e' knows what's up. result_opts.merge!(status: LOGIN_STATUS::UNABLE_TO_CONNECT, proof: e.) end Result.new(result_opts) end |
#check_setup ⇒ String
Checks if the target is BAVision Camera’s web server. The login module should call this.
20 21 22 23 24 25 26 27 28 29 |
# File 'lib/metasploit/framework/login_scanner/bavision_cameras.rb', line 20 def check_setup login_uri = normalize_uri("#{uri}") res = send_request({'uri'=> login_uri}) unless res && res.headers['WWW-Authenticate'] && res.headers['WWW-Authenticate'].match(/realm="IPCamera Login"/) return "Unable to locate \"realm=IPCamera Login\" in headers. (Is this really a BAVision camera?)" end false end |
#digest_auth(user, password, response) ⇒ Object
The Rex HTTP Digest auth is making the camera server to refuse to respond for some reason. The API also fails to generate the CNONCE parameter (bug), which makes it unsuitable for our needs, therefore we have our own implementation of digest auth.
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 |
# File 'lib/metasploit/framework/login_scanner/bavision_cameras.rb', line 60 def digest_auth(user, password, response) nonce_count = 1 cnonce = Digest::MD5.hexdigest("%x" % (Time.now.to_i + rand(65535))) i = (response['www-authenticate'] =~ /^(\w+) (.*)/) # The www-authenticate header does not return in the format we like, # so let's bail. unless i raise BavisionCamerasException, 'www-authenticate header is not in the right format' end params = {} $2.gsub(/(\w+)="(.*?)"/) { params[$1] = $2 } a_1 = "#{user}:#{params['realm']}:#{password}" a_2 = "GET:#{uri}" request_digest = '' request_digest << Digest::MD5.hexdigest(a_1) request_digest << ':' << params['nonce'] request_digest << ':' << ('%08x' % nonce_count) request_digest << ':' << cnonce request_digest << ':' << params['qop'] request_digest << ':' << Digest::MD5.hexdigest(a_2) header = [] header << "Digest username=\"#{user}\"" header << "realm=\"#{params['realm']}\"" header << "qop=#{params['qop']}" header << "uri=\"/\"" header << "nonce=\"#{params['nonce']}\"" header << "nc=#{'%08x' % nonce_count}" header << "cnonce=\"#{cnonce}\"" header << "response=\"#{Digest::MD5.hexdigest(request_digest)}\"" header * ', ' end |
#try_digest_auth(cred) ⇒ Object
Auth to the server using digest auth
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/metasploit/framework/login_scanner/bavision_cameras.rb', line 33 def try_digest_auth(cred) login_uri = normalize_uri("#{uri}") res = send_request({ 'uri' => login_uri, 'credential' => cred, 'DigestAuthIIS' => false, 'headers' => {'Accept'=> '*/*'} }) digest = digest_auth(cred.public, cred.private, res.headers) res = send_request({ 'uri' => login_uri, 'headers' => { 'Authorization' => digest }}) if res && res.code == 200 && res.body =~ /hy\-cgi\/user\.cgi/ return {:status => LOGIN_STATUS::SUCCESSFUL, :proof => res.body} end {:status => LOGIN_STATUS::INCORRECT, :proof => res.body} end |