繁体   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