私のクラスには、教科書やそのための構造化された学習資料がありません。私はすべての学習をグーグルで行っており、私がそれをやっている間にそれを拾っている間、それは正直になるのに時間がかかります。
クラスの割り当て:
ファイルprog-bad.cにプログラム(多少の疑似コード)があります。このプログラムは、コンパイルまたは実行するために作成されているのではなく、読み取られるように作成されています。
脆弱性とは何か、これらの脆弱性が何を引き起こす可能性があるのかを見つけ、見つけた内容について簡単な説明を書いてください。
#include <stdio.h>
int main() {
int studentId;
char studentName[100], buffer[100], percentage[10];
char* firstName = malloc(sizeof(char)*50);
char* lastName = malloc(sizeof(char)*50);
char* graduateLevel = NULL;
printf("\n**********Welcome to Student Registration Service**********\n");
printf("\nPlease enter your 10 digit Student ID: ");
scanf("%d", &studentId);
printf("\nPlease enter your first name: ");
gets(firstName);
printf("\nPlease enter your last name: ");
gets(lastName);
{
char level[2];
printf("\nPlease enter your graduate level (UG/PG): ");
gets(level);
graduateLevel = &level;
}
strcpy(studentName, firstName);
strcat(studentName, lastName);
printf("\nPlease enter your percentage in Highschool (like 85.50%): ");
gets(percentage);
// Student record saving in file
updateStudentRecord();
printf("\nStudent record saved with the following details: \n");
printf("\nStudent ID: %d", studentId);
printf("\nStudent Name: %s", studentName);
printf("\nStudent percentage in Highschool: ");
printf(percentage);
free(firstName);
free(firstName);
return(0);
}
私の答えは、プログラムを開いてオーバーフロー攻撃をバッファリングするscanf
、gets
、およびprintf
関数のすべての使用について話しています。しかし、私はプログラムがmalloc
を使用していることを知っている少し矛盾した原因です。これは、すべてをnonxacutableヒープに移動することによってスタックを保護する方法であると考えました。
これは、プログラムが思ったほど安全ではなく、一種のトリックの問題であることを意味しますか?
Mallocは-
char* firstName = malloc(sizeof(char)*50);
char* lastName = malloc(sizeof(char)*50);
これらはヒープ上にあるという点であなたは正しいです。しかし、その後、このデータはどうなりますか?そして、これらの機能はどのように機能しますか?
ユーザーから他に何が読み取られますか?そしてどうやって?
以下のコメントに返信してください
私の限られた範囲と理解でそれを見ると、脆弱性は次のとおりです。すべてのprintf、studentidのscanf
studentidはintです。だから私はその上での操作は安全だと信じています。
、姓と名を取得します
しかし、mallocは姓と名に使用されたので、それらのgetのすべてのインスタンスをある程度保護します。
取得直後のデータはヒープ上にあります。しかし、これはそれを安全にしますか?ユーザーがいずれかのフィールドに50文字を超える文字を入力するとどうなりますか? ヒープオーバーフロー を読むことをお勧めします。ヒープデータの破損が問題ではなかったとしても、コードがそのデータをどのように処理するかを確認してください。 strcpyとstrcatは何をしますか?
レベルの取得/パーセントの取得
はい。これらの両方がオーバーフローする可能性があるだけでなく、「gradualLevel =&level;」の後に何が起こるかライン?
2番目のコメントに返信-
あなたの最後の点について混乱し、「gradualLevel =&level;」の後に何が起こりますか?
「char level [2];」直上の波括弧内で宣言されています。つまり、そのブロックスコープ内でのみ保護されます。そのスコープは、「gradualLevel =&level;」の後の行で終わります。したがって、gradualLevelは、レベルが以前あった場所のアドレスを指します。しかし、コンパイラには、レベルが上書きされないようにする義務はありません。この時点以降にlevelを使用する操作は、未定義の動作です。
現在、この問題はかなり軽微です。コンパイラが再利用しない可能性はかなり高くなります。 get呼び出しから読み取られるレベルと比較して、無視できるレベルを超えています。しかし、このようなコードは、バグを追跡するのが奇妙で困難な場合が多く、その一部は悪用される可能性があります。
Strcpyとstrcatが問題であるいくつかの場所を読んだので、少し混乱していますが、それらが問題ではないこともわかりましたか?
まず、 strcpy と strcat の定義を読んで理解する必要があります。 strcpyを取りましょう-
Srcが指すnullで終了するバイト文字列(nullターミネーターを含む)を、最初の要素がdestが指す文字配列にコピーします。
したがって、nullターミネーター( '\ 0'-通常はバイト値0)に到達するまで、ソース配列から宛先配列に文字をコピーします。警告に注意してください-
Dest配列が十分に大きくない場合の動作は未定義です。文字列が重複する場合の動作は未定義です。 destが文字配列へのポインターでないか、またはsrcがヌル終了バイト文字列へのポインターでない場合の動作は未定義です。
だから-ライン
strcpy(studentName, firstName);
これらは適用されますか?宛先は、studentName-100文字の配列です。ソースはfirstName-50文字の配列へのポインターです。しかし、firstnameはnullで終了しますか?まあ、その価値は-
gets(firstName);
改行文字が見つかるか、ファイルの終わりが発生するまで、stdinをstrが指す文字配列に読み込みます。配列に読み込まれた最後の文字の直後にnull文字が書き込まれます。改行文字は破棄されますが、バッファには格納されません。
警告付き-
Gets()関数は境界チェックを実行しないため、この関数はバッファオーバーフロー攻撃に対して非常に脆弱です。安全に使用することはできません(プログラムがstdinに表示されるものを制限する環境で実行されない限り)。このため、この関数はC99標準の3番目の修正で非推奨になり、C11標準では完全に削除されました。 fgets()とgets_s()は、推奨される置き換えです。
gets()。は使用しないでください。
そう。 firstNameに「Dylan」と入力すると、「Dylan\0」が含まれます。 200バイトで入力するとどうなりますか?
標準は未定義ですが、ほとんどの実際のシステムでは簡単に推測できます。 firstNameの後のメモリに書き込みを続けるだけです。次に何が起こりますか?まあ-それがメモリ空間を離れる場合、プロセスが合法的にOSに書き込むことができるので、おそらくそれを強制終了します。しかし、そうでない場合、何かがクラッシュする原因となるような何らかの問題が発生するか(格納されているはずのものはもうありません)、またはプログラムが終了するまで、気付かないうちに実行され続けます。ここで指摘したように、ダメージは限定的です。このデータはヒープに保存されます。
そう。 strcpyまですべてが問題なく続くと仮定しましょう。そこで何が起こりますか? strcpyは、firstNameが50文字のみであることを認識していません。または、studentNameは100文字のみと想定されています。ヌルターミネータに到達するまでコピーを続けます。
lastNameとstrcatにはまったく同じ問題があります。