Linuxにおけるバッファオーバーフローの例

データがプログラムが割り当てたバッファのサイズを超えると、余分なデータは隣接するメモリ領域にオーバーフローして、プログラムがクラッシュしたり、攻撃者が悪意のあるコードを実行するために利用したりする一般的なセキュリティホールです。

以下は、単純なバッファオーバーフロー脆弱性を示す、Linux インスタンスです。

#include <stdio.h>
#include <string.h>
void vulnerableFunction(char *input) {
char buffer[10];
strcpy(buffer, input);
printf("You entered: %s\n", buffer);
}
int main() {
char input[20];
printf("Enter a string: ");
scanf("%s", input);
vulnerableFunction(input);
return 0;
}

上記のコードにおいて、vulnerableFunctionはバッファオーバーフローの脆弱性を持つ関数です。文字列を引数に取り、10バイト分のバッファにコピーします。この際、引数の文字列が10文字を超えるとバッファオーバーフローが発生します。

main 関数では、scanf 関数からユーザー入力を受け取り、vulnerableFunction 関数に渡します。scanf 関数にはユーザー入力の長さ制限がないため、ユーザーは 10 文字を超える文字列を入力することができ、バッファオーバーフローの脆弱性が発生します。

バッファーオーバーフローの脆弱性を利用した例を以下に示します

$ ./buffer_overflow
Enter a string: aaaaaaaaaaaaaaaaaaaaabbbb
You entered: aaaaaaaaaaaaaaaaaaaaabbbb

このサンプルでは、ユーザーが入力した文字列の長さが22で、バッファのサイズを超えています。strcpy関数はターゲットバッファのサイズをチェックしないため、すべての22文字がバッファにコピーされ、バッファオーバーフローが発生します。この場合、プログラムはクラッシュせず、出力された文字列はバッファのサイズを超えます。

バッファオーバーフロー脆弱性は、攻撃者が悪意のあるコード(関数のポインタの書き換えや、戻り値アドレスの変更など)を実行するために悪用することができます。バッファオーバーフロー脆弱性を防ぐために、strncpy などの文字列コピーの長さを制限する安全な関数をコードで使用し、入力の検証を実施して入力がバッファのサイズを超えないようにする必要があります。

bannerAds