入口メソッド
メタデータとオプションが終わったら、フレームワークが呼び出す 入口メソッド を実装します。type によって名前が違います。
| type | 入口 | いつ呼ばれるか |
|---|---|---|
| exploit | exploit | run / exploit コマンド |
| exploit / 一部 auxiliary | check | check コマンド、または AutoCheck |
| auxiliary(通常) | run | run |
| auxiliary + Scanner | run_host(ip) | 各 host ごと(run は mixin が持つ) |
| auxiliary + Scanner の check | check_host(ip) | 各 host の check |
| post | run | run(要 SESSION) |
check(任意だが推奨)
Section titled “check(任意だが推奨)”脆弱かどうかの判定だけを行い、ペイロードは流さない(または最小の証明に留める)メソッドです。戻り値は CheckCode::* です。fail_with は使わず、CheckCode を返します。
| CheckCode | 意味 |
|---|---|
Unknown | 情報不足(タイムアウトなど) |
Safe | 脆弱でない / 対象外 |
Detected | サービスは見つかったが可否不明 |
Appears | バージョンなど受動的根拠で怪しそう |
Vulnerable | 実際に挙動で確認できた |
Unsupported | check 非対応 |
def check res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'index.php') ) return CheckCode::Unknown('no response') if res.nil? return CheckCode::Safe('not ExampleApp') unless res.body.include?('ExampleApp')
if res.body =~ /Version: 1\.[0-2]/ return CheckCode::Appears('ExampleApp 1.0-1.2 detected') end
CheckCode::Detected('ExampleApp found, version unknown')endScanner では次です。
def check_host(ip) # ip ごとに判定 CheckCode::Safeendメッセージは vprint_* を優先し、「Vulnerable です」と自分で断言しすぎない方がよいです。フレームワークが CheckCode を表示します。
exploit
Section titled “exploit”exploit の本体です。接続 → 脆弱性利用 → ペイロード配送 →(必要なら)handler の流れが多いです。
def exploit res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'ping'), 'vars_post' => { 'ip' => "127.0.0.1;#{payload.encoded}" } ) fail_with(Failure::Unreachable, 'no response') if res.nil?endCmdStager 利用時です。
def execute_command(cmd, _opts = {}) send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'ping'), 'vars_get' => { 'ip' => "127.0.0.1;#{cmd}" } )end
def exploit if target['Arch'] == ARCH_CMD execute_command(payload.encoded) else execute_cmdstager(linemax: 1500) endendTCP 雛形(example.rb)では connect → sock.put → handler です。
失敗時は fail_with(Failure::..., message) を使います。定数は 応答処理と fail_with を参照してください。
run(auxiliary / post)
Section titled “run(auxiliary / post)”def run print_status("Running against #{peer}") # 処理 print_good('Done')endpost では session が使えます。
def run print_status(cmd_exec('id'))endrun_host(Scanner)
Section titled “run_host(Scanner)”def run_host(ip) res = send_request_cgi('method' => 'GET', 'uri' => '/') return if res.nil? print_good("#{ip}:#{rport} #{res.code}") report_service(host: ip, port: rport, name: 'http', info: res.headers['Server'])endrun を自分で定義して Scanner の仕組みを潰さないこと。host 単位の状態はローカル変数に閉じます。
AutoCheck との関係
Section titled “AutoCheck との関係”prepend Msf::Exploit::Remote::AutoCheck すると、exploit / run の前に check が自動実行されます。詳細は AutoCheck です。
デバッグ出力
Section titled “デバッグ出力”| メソッド | 用途 |
|---|---|
print_status | 通常の進捗 [*] |
print_good | 成功 [+] |
print_error | 失敗 [-] |
print_warning | 警告 |
vprint_* | VERBOSE true のときだけ |
次は 成果の保存 です。

