ncのマニュアルにあるshサーバの実行例が気になったので図にまとめてみた。
マニュアルはBSD General Commands Manualである。
(LinuxでもncのマニュアルはBSDなんだな)
On ‘server’ side:
$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
On ‘client’ side:
$ nc host.example.com 1234
$ (shell prompt from host.example.com)
このサーバサイドコマンドであるcat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
をまとめる。
mkfifo
まずは最初の行で実行されているコマンドmkfifo
について。
これは名前付きパイプを生成するコマンドである。
パイプといえばシェルの縦棒(|
)に相当するもので、見た目としてはファイルのように現れる。
あるプロセスがそのファイルに書き込みをし、同時に別のプロセスがそのファイルから読み込みを行うと、コマンド同士が「|
」で繋がっていなくても、入出力が接続される。
nc -lの入出力
続いてnc -l
の入出力について。
nc -l
はポートを開けて通信を受け付けるコマンドである。
出力は簡単で、接続してきたプロセスが送信してきたものをそのまま吐き出す。
$ nc -l 1234 > output.txt
$ nc localhost 1234
THIS IS OUTPUT
<C-d>
こうするとoutput.txtには”THIS IS OUTPUT”と入っている。
入力は反対に、接続してきたプロセスに送るデータになる。
$ echo HELLO | nc -l 1234
$ nc localhost 1234
HELLO #勝手に出力される
問題のコード
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
生成された/tmp/f
は名前付きパイプである。
コマンドの最後にnc -l
の結果を/tmp/f
に流しているので、クライアントが送ってきた文字列が名前付きパイプが流れる。
つづいてコマンドの最初には/tmp/f
からの出力をbash
に流し、その出力をnc -l
に流れている。

したがってこの図のようになる。
このコマンドを実行すれば、nc
するとsh
のプロンプトが現れ、コマンドを打つとその実行結果が送られてくる。
まぁもちろん普段は絶対使用しないように。
コメント