1

私は C でセキュリティの問題を経験していました。以下のコードがどのようにスタックを破壊するのか理解できませんでした。

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

int chk_perm(){
        printf("\n Check Perm \n");
        return 2;
}
int main(int argc,char* argv[]){
        int fg;
        char filename[16];

        if(argc != 2){
                fprintf(stderr,"Usage : %s filename\n",argv[0]);
                exit(1);
        }

        fg = chk_perm();
        strcpy(filename,argv[1]);
        if(fg == 0xdeadbeef){
                //execute as root or deposit million dollars in bank account
        }
        else{
                //execute as a normal user , deduct $10 from an account
        }

        return 0;
}

渡された argv[1] は、fg の値を変更する場合があります。渡された argv[1] が望ましくない結果を引き起こす可能性のあるバイナリ全体であり、戻りアドレスとともに引数として渡すことができる場合、破損が発生すると言われています。

fg の値が変更されるように、strcpy がスタック check_perm をどのように破損するかを理解できませんでした。

プログラムについての私の仮定は、

プログラムの実行が開始されると、メイン関数のスタックが作成され、その引数、戻りアドレス、ローカル変数がスタックに置かれます。したがって、int fg はスタックの 4 バイト (08567500 loc) を占有し、filename[16] は次の 16 を占有します。バイト (08567504)。ファイル名が 16 バイトを超えてオーバーフローしている場合でも、その後にローカル変数が存在すると破損する可能性があります。

では、strcpy(filename,argv[1]); が原因で fg がどのように破損するのでしょうか。

4

3 に答える 3

3

アーキテクチャ上でスタックが下向きに成長する場合 (よくあることですが)、は の直後にfgメモリを占有します。これは、あなたが過去を書くとき、あなたが粉砕することを意味します。 filenamefilenamefg

于 2013-09-10T16:36:26.720 に答える
2

fgスタックにあります。そうですfilename。16 より大きい値を指定すると、上書きさstrcpy()れます。filenamefg

于 2013-09-10T16:35:12.623 に答える
1

他の人が指摘したように、filenameバッファを超えて書いています。その場合、スタックの次の項目はfg変数であるため、入力ファイル名が 15 文字を超える場合はバイトが書き込まれます (さらに 1 バイトが含まれます: ゼロ ターミネータ)。

filenameユーザーが提供する可能性のあるものを保持するのに十分な大きさにするかargv[1]、コピーしすぎるバイトを防ぐ必要があります。ただし、この場合は必要なスペースを割り当てることをお勧めします。

char filename[PATH_MAX+1];

動的に実行する場合:

char *filename;

if ( !(filename = malloc(strlen(argv[1]) + 1))) ) {
    ... (failure leg)
}

16ファイル名の長さをバイト (実際にはゼロ終端文字) に制限すること15は、ユーザーにとって非常に実用的ではありません。特に、ファイル パラメーターにフル パス名を指定する可能性があるためです。のような関数を使用するstrncpyと、ユーザーのファイル名が切り詰められ、ファイル オープン エラーが発生するか、最悪の場合、間違ったファイルが開かれる危険があります。

于 2013-09-10T16:38:20.943 に答える