FC2のexec-shield (2)

スタック上に置かれたコードの実行不許可についてはきちんと効いているのだろうか。こちらも確認してみました。背景となる技術については Shudo's Note さんの5/17の記事などを参照していただくとして、結論のみ。デフォルトでばっちり効いています!。こちらも、 buffer overflow などによる exploit を困難にする効果があります。


FC2のデフォルトでは、/proc/sys/kernel/exec-shield が 1 になっています。これは「/usr/bin/execstack -q で 'X' となっているバイナリについてはstack上のコードの実行を許可、'-' となっているバイナリについては不許可」というモードです。execstackコマンドはバイナリ中のあるフラグを見ています。出力の 'X' は、eXecの略でしょう。

(実行例)
$ execstack -q /bin/foo
 - /bin/foo
$ execstack -q /bin/bar
 X /bin/bar

そして、

  • FC2に付属のバイナリの殆ど全ては '-' になっています
  • gccを用いて自分でバイナリを作成した場合も、特殊なコード*1を書いた場合を除いて '-' に設定されます

要するに、殆ど全てのバイナリで、stack上のコードの実行が禁止されているわけです。


/etc/sysctl.conf を書き換えるなどして、/proc/sys/kernel/exec-shield を 2 にして起動すると、全てのバイナリで強制的にstack上のコードの実行が禁止されます*2。こうしておくほうがよりセキュアな設定といえますが、各種JIT(javaコマンド含む)、insmodの一部機能、wineなどは動かなくなるはずです。


最後に、デフォルトで 'X' にコンパイルされるようなコードを、

  • execstack -s してから実行
  • /proc/sys/kernel/exec-shield を 2 にしてから実行

してみてください。すると、SIGSEGVで異常終了することと思います。これで、実際に防御機構が働いていることを確認できます。


なお、トランポリンの詳細については id:yupo5656:20040602 に書いてありますので参照のこと。

*1:「特殊なコード」というのは、「トランポリン」が生成されるコードのこと。同URIサンプルコードなど

*2:http://kerneltrap.org/node/view/913 が詳しい