初めに
こんにちは、今回はシェルの安定化がテーマです。
Linux マシンの攻略において、リバースシェルを利用して初期侵入をした場合、「シェルを安定化」させてから権限昇格や横展開を狙っていくフローが一般的だと思います。
これまで、矢印やtab 補完を利用可能にするための操作として機械的に実施してきましたが、ふと要するに何をしている操作なのか気になりました。
本記事はほとんど自分の学びをまとめているものですが一応、ターゲットとしては
・「シェルの安定化」をそもそも知らない人
・機械的に実行はしているものの、仕組みが良く分からない人
向けの記事となります。
本編
それでは本編に入っていきます。今回は HackTheBox の HairCut を題材にしていますが、攻略記事ではないので、攻略手順は他の方の回答を参考にしていただけますと幸いです。
シェルの安定化(Shell Stability)とは
シェルの安定化とは、リバースシェルやバインドシェルを使って侵入した際に得られる簡易シェル(不安定なシェル)を、より快適に操作できるインタラクティブなシェルに変える作業です。
Unix 系の OS では、インタラクティブなシェル操作(矢印キー、tab補完、カーソル移動など)を行うためには、シェルが端末(TTY/PTY)に接続されている必要があります。
しかし、リバースシェルでは以下のフローで動作しており、/bin/sh
が直接TCP接続されているため、インタラクティブ操作ができないというわけです。
[被害者] /bin/sh → [TCP接続] → [攻撃者] nc
以下の図では矢印キー入力を試していますが、エスケープシーケンスが処理されずに文字列が直接見えてしまっています。
他にも、vimなどの挙動も怪しくなったり文字化けしたりするなど、簡易シェルは色々と使いづらいです。
※TTY、PTY の違いは下表の通りです。PTY は「仮想的に作られた TTY」で、ターミナルをエミュレートする仕組みで、シェルの安定化にはこちらを利用します。
TTY | PTY | |
---|---|---|
意味 | Teletypewriter(端末) | 擬似端末(Pseudo Terminal) |
物理性 | 物理または仮想的な直接端末 | 完全に仮想的な端末 |
割り振りパス | /dev/tty* | /dev/pts/* |
例 | ログイン端末、Ctrl+Alt+F1〜F6 など | SSH、tmux、リバースシェルなど |
使われ方 | ローカルユーザーが直接使う | プログラム・リモートアクセスで利用 |
シェルの安定化手順
ここからは、シェルの安定化のための操作を解説していきます。
① 簡易シェルを疑似端末付きのシェルに昇格させる
まず初めに、pythonを利用して簡易シェルを疑似端末付きに昇格させます。
www-data@haircut:~/html/uploads$ python3 -c 'import pty; pty.spawn("/bin/bash")'
pty
: Python に標準搭載されているモジュールで、擬似端末(pseudo-terminal) を操作するためのライブラリ
もし初期侵入した対象にpythonが入っていない場合は下記の操作を試してもよいです。
www-data@haircut:~/html/uploads$ script /dev/null -c bash
こちらはscript
コマンドを利用して新しい擬似端末セッションを開始し、その中でコマンド(ここでは bash)を動かしています。/dev/null
にログを送り、出力ファイルを作らず実行ログを捨てています。
② 一度ローカル端末(kali)に戻る
ここまで完了したら、一度Ctr+Z
で今動いているフォアグラウンドのプロセスを一時停止して、バックグラウンドに送ります。
www-data@haircut:~/html/uploads$ ^Z
zsh: suspended nc -lnvp 4444
┌──(kali㉿kali)-[~]
└─$
これは、一度ローカル端末に戻り、ローカル側の設定変更をするためです。
③ TTYの動作変更
kaliに戻ったら続いて以下のコマンドを実行します。
┌──(kali㉿kali)-[~]
└─$ stty raw -echo; fg
[1] + continued nc -lnvp 4444
whoami
www-data
www-data@haircut:~/html/uploads$
二つ続いていますが、一つ目のコマンドstty raw -echo
はシェルの入力をそのまま送り、余計な表示を抑えることで、リバースシェルが自然な挙動をするように調整しています。
二つ目のコマンドfg
は、Ctr+Z
でバックグラウンドに送ったnc
のプロセスをもう一度フォアグラウンドに送っています。
以上の操作により、インタラクティブなシェルを手に入れることができました。
あとがき
今回は、シェルの安定化について取り扱いました。
やっていることはシンプルですが、改めて整理できてよかったです。