简体   繁体   English

带有gcc修改的修补程序身份验证程序

[英]Patch authentication program with gcc modification

My problem is that with the newer versions of gcc the security leak for the following little authentication program cannot be fixed. 我的问题是,使用较新版本的gcc,无法修复以下小型身份验证程序的安全漏洞。

The following program should only output "Access garanted" if the right password gets typed, but with a buffer overflow it´s possible to "hack" this program. 如果键入正确的密码,则以下程序仅应输出“授权访问”,但是由于缓冲区溢出,可能会“入侵”该程序。

Program (raw): 程序(原始):

#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");
    }
}

Output: 输出:

[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!
=_=_=_=_=_=_=_=_=_=

So I know that this is only possible because of the buffer overflow and the resulting overwrite of the next variable in the stack. 因此,我知道这仅是因为缓冲区溢出和堆栈中下一个变量的覆盖导致的。 And in my case this variable is the "auth_flag" variable and since the value of this variable isn´t equals to 0 the condition for executing the if-statement in the main() function is given. 在我的情况下,该变量是“ auth_flag”变量,由于该变量的值不等于0,因此给出了在main()函数中执行if语句的条件。 Therefore I tried to manipulate the stack so that the "auth_flag" cannot be overwritten anymore. 因此,我试图操纵堆栈,以使“ auth_flag”不再能被覆盖。

Program (tried to fix the issue): 程序(试图解决该问题):

#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");
    }
}

After compiling the output was: 编译后的输出为:

[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!
=_=_=_=_=_=_=_=_=_=

So obviously the modification didn t work. But I 因此,显然修改没有用t work. But I t work. But I ve read that this is because newer gcc versions don`t arrange the variables like in the order given from the program but rather like is wants to. t work. But I已经读到这是因为较新的gcc版本不会按照程序给定的顺序排列变量,而是希望如此。 Is there any possibility to modify gcc that is works like older versions? 是否有可能修改类似于旧版本的gcc?

This line is very unsecure with a passwd string that could have any length. 这行是非常不安全的,可以包含任何长度的passwd字符串。

strcpy(passwd_buffer, passwd);

Why not use this? 为什么不使用这个?

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

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


Aside from this particular problem of overflow, variables are just an abstraction to name the values in an algorithm in order to help the programmers elaborate a reasonning. 除了这个特定的溢出问题之外,变量只是在算法中命名值的抽象,以帮助程序员详细说明推理。
A soon as an optimizing compiler is used the variables may not even exist . 使用优化编译器后,变量可能甚至不存在
It's hard to figure this out because when asking for an unoptimised build in order to use a debugger, we actually ask the compiler to make the variable exist in order to observe them in the debugger. 很难弄清楚这一点,因为当要求使用调试器进行未经优化的构建时,我们实际上是要求编译器使变量存在,以便在调试器中进行观察。
But the optimised code is very different from the unoptimised one. 但是优化后的代码与未优化后的代码有很大不同。
Even in unoptimised mode, nothing in the standard of the language specifies how the variables should be laid out. 即使在未优化的模式下,该语言的标准也没有规定变量的布局方式。
A compiler could choose a layout different from another one. 编译器可以选择与其他布局不同的布局。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM