結局どうすりゃいいのさ (攻撃されないCFLAGS/LDFLAGS)


最近のエントリの総まとめ。適当なネットワークデーモンなどを手動でmakeする際におすすめのgccのオプション。ソフトウェアにbuffer overflowをはじめとするありがちな欠陥があった場合でも、攻撃者にプロセスを乗っ取られないよう、コンパイラカーネルで精一杯防御するためのCFLAGSとLDFLAGS。とりあえずFedora5以降を想定しています。


# 2006/6現在で私が把握しているものです。どんどん変化(進化)しますのでご注意。特にFedoraは。。
# 自分でフォローしたい場合、Hardened Gentooのページや、Fedoraここは役立つと思います

基本


上記のように、「多少遅くなってもセキュアなバイナリ希望」という場合、もともとのCFLAGS/LDFLAGSに加えて、

CFLAGS=-fstack-protector-all -O2 -fno-strict-aliasing -D_FORTIFY_SOURCE=2
LDFLAGS=-Wl,-z,now,-z,relro 

とするのがいいんじゃないでしょうか。さらに、ライブラリを作っているのではなく、実行ファイルを作っている場合は、

CFLAGS=-fPIE
LDFLAGS=-pie

も追加してください。実行ファイル作成の際、ライブラリのスタティックリンクはなるべくやめましょう(自分で調整できるなら)。

味付け


スタックの使いかたを巷のプログラムとはひと味違うものにしておくと、script kiddyの攻撃をかわせる可能性が高まります。たぶん。次の -mpreferred-stack-boundary オプションも付け加えましょう。

CFLAGS=-mpreferred-stack-boundary=5

なお、5のところは、12以下であればもっと大きな値でもよいです。ただしあまり大きくするとスタックをすごく*1消費しますので、せいぜい5から7程度にしておくのが無難でしょう。


さらに、元々のMakefileに -fomit-frame-pointer と書いてあったらこれを取り去り、書いていなければこれを書き加えるのも手です。return to libc attackは、フレームポインタの有無で攻撃の戦略が結構変わりますので、このフレームポインタ有無をデフォルトから反転させることで script kiddy の(ry


品質の悪そうなプログラムは使いたくない、というなら、

CFLAGS=-Wformat=2 -Wstrict-aliasing=2

コンパイルして、あんまり多くの警告がでる場合は使用をやめるとよいでしょう。ただし、冤罪(GCCの誤警告)の可能性もありますのでご注意。

# ほんとは、 -fvolatile なる逆最適化オプションも紹介しようと思っていたのだが、このオプションはGCC3.4から存在しなくなっていた..

仕上げ


最後に、全ての実行ファイルと共有ライブラリに対して、次を実行します。最終品質検査です。

% readelf -l 実行ファイルorライブラリ | grep GNU_STACK | grep RWE
% readelf -d 実行ファイルorライブラリ | grep TEXTREL

もし、どちらかの行の実行で、あるいは両方で、なんらかの出力があったら、その 実行ファイルor共有ライブラリ は使うのを控え、別のソフトを探すとよいかもしれません。わかってそういうことをしている可能性もあるので絶対ダメというわけではないですが。


以上、Exec-Shield(NXとASLR)がonになっているのは前提とします。最近のディストリビューションならそうなっていることでしょう。

いたずら


ELF Kickersというツールに含まれている sstrip というコマンドでバイナリをstripしておくと、binutilsで解析できない(が実行はできる)バイナリになります。気安め程度ですが、objdumpやreadelfされるのが嫌なら検討するとよいかも。最近のbinutilsでは読めたりして。未確認です。elfutilsで読めるかどうかも未確認。

実行時


(あとで書く) export MALLOC_CHECK_=2

*1:O(N**2)で