簡體   English   中英

帶有gcc修改的修補程序身份驗證程序

[英]Patch authentication program with gcc modification

我的問題是,使用較新版本的gcc,無法修復以下小型身份驗證程序的安全漏洞。

如果鍵入正確的密碼,則以下程序僅應輸出“授權訪問”,但是由於緩沖區溢出,可能會“入侵”該程序。

程序(原始):

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

int check_auth(char *passwd){
    int auth_flag = 0;
    char passwd_buffer[16];
    strcpy(passwd_buffer, passwd);
    if(strcmp(passwd_buffer, "brillig") == 0){
        auth_flag = 1;
    }
    if(strcmp(passwd_buffer, "outgrabe") == 0){
        auth_flag = 1;
    }
    return auth_flag;
}

int main(int argc, char **argv){
    if(argc < 2){
        printf("Usage: %s <password>\n", argv[0]);
        exit(0);
    }
    if(check_auth(argv[1])){
        printf("=_=_=_=_=_=_=_=_=_=\n");
        printf("Access garanted!\n");
        printf("=_=_=_=_=_=_=_=_=_=\n");
    }else{
        printf("=_=_=_=_=_=_=_=_=_=\n");
        printf("Access denied!\n");
        printf("=_=_=_=_=_=_=_=_=_=\n");
    }
}

輸出:

[w4r10ck@localhost Hacking_with_C]$ gcc auth_buffer_overflow.c 
[w4r10ck@localhost Hacking_with_C]$ ./a.out "outgrabe"
=_=_=_=_=_=_=_=_=_=
Access garanted!
=_=_=_=_=_=_=_=_=_=
[w4r10ck@localhost Hacking_with_C]$ ./a.out "brillig"
=_=_=_=_=_=_=_=_=_=
Access garanted!
=_=_=_=_=_=_=_=_=_=
[w4r10ck@localhost Hacking_with_C]$ ./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
=_=_=_=_=_=_=_=_=_=
Access garanted!
=_=_=_=_=_=_=_=_=_=

因此,我知道這僅是因為緩沖區溢出和堆棧中下一個變量的覆蓋導致的。 在我的情況下,該變量是“ auth_flag”變量,由於該變量的值不等於0,因此給出了在main()函數中執行if語句的條件。 因此,我試圖操縱堆棧,以使“ auth_flag”不再能被覆蓋。

程序(試圖解決該問題):

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

int check_auth(char *passwd){
    char passwd_buffer[16];
    int auth_flag = 0;
    strcpy(passwd_buffer, passwd);
    if(strcmp(passwd_buffer, "brillig") == 0){
        auth_flag = 1;
    }
    if(strcmp(passwd_buffer, "outgrabe") == 0){
        auth_flag = 1;
    }
    return auth_flag;
}

int main(int argc, char **argv){
    if(argc < 2){
        printf("Usage: %s <password>\n", argv[0]);
        exit(0);
    }
    if(check_auth(argv[1])){
        printf("=_=_=_=_=_=_=_=_=_=\n");
        printf("Access garanted!\n");
        printf("=_=_=_=_=_=_=_=_=_=\n");
    }else{
        printf("=_=_=_=_=_=_=_=_=_=\n");
        printf("Access denied!\n");
        printf("=_=_=_=_=_=_=_=_=_=\n");
    }
}

編譯后的輸出為:

[w4r10ck@localhost Hacking_with_C]$ ./a.out "brillig"
=_=_=_=_=_=_=_=_=_=
Access garanted!
=_=_=_=_=_=_=_=_=_=
[w4r10ck@localhost Hacking_with_C]$ ./a.out "outgrabe"
=_=_=_=_=_=_=_=_=_=
Access garanted!
=_=_=_=_=_=_=_=_=_=
[w4r10ck@localhost Hacking_with_C]$ ./a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaa
=_=_=_=_=_=_=_=_=_=
Access garanted!
=_=_=_=_=_=_=_=_=_=

因此,顯然修改沒有用t work. But I t work. But I已經讀到這是因為較新的gcc版本不會按照程序給定的順序排列變量,而是希望如此。 是否有可能修改類似於舊版本的gcc?

這行是非常不安全的,可以包含任何長度的passwd字符串。

strcpy(passwd_buffer, passwd);

為什么不使用這個?

strncpy(passwd_buffer, passwd, sizeof(passwd_buffer)-1);
passwd_buffer[sizeof(passwd_buffer)-1]='\0';

https://en.cppreference.com/w/c/string/byte/strncpy


除了這個特定的溢出問題之外,變量只是在算法中命名值的抽象,以幫助程序員詳細說明推理。
使用優化編譯器后,變量可能甚至不存在
很難弄清楚這一點,因為當要求使用調試器進行未經優化的構建時,我們實際上是要求編譯器使變量存在,以便在調試器中進行觀察。
但是優化后的代碼與未優化后的代碼有很大不同。
即使在未優化的模式下,該語言的標准也沒有規定變量的布局方式。
編譯器可以選擇與其他布局不同的布局。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM