応答処理と fail_with
HTTP 応答の扱いと、失敗時の fail_with です。Failure 定数は lib/msf/core/module/failure.rb にあります。
応答オブジェクト
Section titled “応答オブジェクト”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?check では CheckCode::*、exploit / run では fail_with を使うのが定石です。
CheckCode 例
Section titled “CheckCode 例”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')endfail_with の代表値
Section titled “fail_with の代表値”| 定数 | 使う場面 |
|---|---|
Failure::BadConfig | オプション不足・矛盾 |
Failure::Unreachable | 接続できない / res.nil? |
Failure::Disconnected | 途中切断 |
Failure::NoAccess | 認証失敗・権限不足 |
Failure::NotFound | パス / ファイルが無い |
Failure::NotVulnerable | 脆弱でないと分かった |
Failure::NoTarget | target 選択が合わない |
Failure::UnexpectedReply | 想定外の応答コード / 本文 |
Failure::TimeoutExpired | タイムアウト |
Failure::PayloadFailed | ペイロードは送ったがセッションなし |
Failure::Unknown | 切り分け不能 |
Failure::UserInterrupt | ユーザ中断 |
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?応答パース例
Section titled “応答パース例”%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)HTML の簡易除去は strip_tags(html) があります。

