バッファオーバーフロー
バッファオーバーフロー攻撃を防ぐには、領域長とデータ長を意識したプログラミングを行う事が重要である:
データをバッファに挿入する際には、データ長がバッファ長を超えない事を調べる検査ロジックをプログラムに書き加えておく
データが文字列の場合は文字列長を数え間違えないよう、文字列の終端にあるナル文字も数える
データ長に依存したループを書くときに間違ってループを回しすぎる(Off-by-oneエラー)事が無いようにする
事前にデータ長の上限がわからない場合は、バッファをmalloc等で動的に確保し、不要になったら確実にfreeする
mallocなどでヒープ領域に動的にメモリを確保する関数に対するオーバーフロー攻撃である。基本的な攻撃手法としては、関数がヒープに確保したメモリ領域が2つあるとき、そのうち一方の領域に対して確保済みのメモリサイズより大きなデータを入力する事でオーバーフローを起こし、もう一方のメモリ領域を書き換えるというものである。mallocは複雑な方法でメモリ確保の場所を決定しているものの、連続して2度mallocを実行した場合、その結果として確保される2つのメモリ領域は(仮想アドレス空間上で)近くに配置されている傾向があるため、上述のようなバッファオーバーフロー攻撃が可能になる。
ret2esp(Return to esp)攻撃は、2017年現在のASLRの実装のデフォルトではコード領域(.textセクション)をランダマイズしない事を利用してASLRを回避する攻撃手法である。ここでespはx86におけるスタックポインタである。この攻撃は.textセクション内に「jmp esp」のような命令がある場合に成立する。攻撃者はバッファオーバーフローを利用してespの(仮想アドレス空間上の)下にシェルコードを配置した上で、リターンアドレスを「jmp esp」の箇所に書き換える。するとまずリターンアドレスの書き換えにより「jmp esp」のところにジャンプし、次に「jmp esp」が実行されてespの箇所にジャンプするので、その下に配置したシェルコードが実行される事になる。
標準Cライブラリ等にはバッファオーバーフロー検知機能が施されていない関数が収録されているので、これを検知機能を持った関数に置き換えたライブラリを標準Cライブラリの代わりに使う事で攻撃を検知できる。例えばLibsafeは標準Cライブラリのstrcpy(*dest,*src)をより安全な関数に置き換えており、入力srcのサイズがコピー先のdestのサイズが大きいか否かを検知できる。