バッファオーバーフローの脆弱性

とても初歩的なんだろうけれど、バッファオーバフローの脆弱性というのを確認した。

以下のコードがあるとき、bufの範囲を超えた入力をうけつけると、その配列より前に宣言しているnの値を書き換えることができてしまう。

#include <stdio.h>
#include <stdlib.h>

int main() {
  int n = 0;
  char buf[8];
  scanf("%s", buf);

  if (n == 0) {
    printf("OK");
  } else {
    printf("NG");
  }
  return 0;
}

標準入力に8文字以上を入力した場合、nの値は書き換わってしまう。 *1

こういうので、関数フレームのリターンアドレスとか書き換えられたら確かにやばい。 けど、実際にはgccなどのコンパイラはスタックを保護してくれるので、そんな簡単には書き換わらない。

これ確認しようとすると、明示的にスタック保護を無効化する-fno-stack-protectorを付けてコンパイルする必要がある。

gcc -fno-stack-protector -o main main.c

自作Cコンパイラだとそんな保護機能は作ってないので簡単に試せるけれど。

参考:はじめて学ぶバイナリ解析

脆弱性をついてシェルを起動するところくらいまで解説があって、とっかかりとしてはわかりやすかった。*2

バイナリ解析

*1:ちょうど8文字入力した場合は、OKが返ってくるが、終端文字(=0)でnの値が上書きはされている。

*2:コンパイラの保護は無効化するけど