Responses and fail_with
How to handle HTTP responses and report failures with fail_with. Failure constants are defined in lib/msf/core/module/failure.rb.
Response object
Section titled “Response object”res = send_request_cgi(...)fail_with(Failure::Unreachable, "#{peer} - no response") if res.nil?
code = res.codebody = res.bodyheaders = res.headersserver = res.headers['Server']cookies = res.get_cookieslocation = res.redirection if res.redirect?A common pattern is to use CheckCode::* in check and fail_with in exploit or run.
CheckCode example
Section titled “CheckCode example”def check res = send_request_cgi('method' => 'GET', 'uri' => normalize_uri(target_uri.path)) return CheckCode::Unknown('no response') if res.nil? return CheckCode::Safe('not ExampleApp') unless res.body.include?('ExampleApp') return CheckCode::Appears('ExampleApp detected')endCommon fail_with values
Section titled “Common fail_with values”| Constant | When to use it |
|---|---|
Failure::BadConfig | Missing or conflicting options |
Failure::Unreachable | Cannot connect, or res.nil? |
Failure::Disconnected | Disconnected mid-operation |
Failure::NoAccess | Authentication failed or permissions are insufficient |
Failure::NotFound | Path or file does not exist |
Failure::NotVulnerable | Target is known not to be vulnerable |
Failure::NoTarget | Selected target does not match |
Failure::UnexpectedReply | Unexpected response code or body |
Failure::TimeoutExpired | Timed out |
Failure::PayloadFailed | Payload sent but no session opened |
Failure::Unknown | Cannot determine the cause |
Failure::UserInterrupt | User interrupted the operation |
fail_with(Failure::NoAccess, "login failed: HTTP #{res.code}") unless res.code == 302fail_with(Failure::UnexpectedReply, 'token missing') if token.blank?fail_with(Failure::BadConfig, 'PASSWORD is required') if datastore['PASSWORD'].blank?Response parsing examples
Section titled “Response parsing examples”%r{Version: (?<version>\d+\.\d+)} =~ res.bodyif version && Rex::Version.new(version) <= Rex::Version.new('1.3') return CheckCode::Appears("Version #{version}")endjson = res.get_json_document rescue nilfail_with(Failure::UnexpectedReply, 'invalid json') unless json.is_a?(Hash)For basic HTML stripping, use strip_tags(html).

