gpt4 book ai didi

c - 修改gcc的补丁认证程序

转载 作者:行者123 更新时间:2023-11-30 14:37:36 25 4
gpt4 key购买 nike

我的问题是,使用较新版本的 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!
=_=_=_=_=_=_=_=_=_=

很明显,修改没有起作用。但我读到这是因为较新的 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 )

<小时/>

除了这个特殊的溢出问题之外,变量只是一种抽象,用于命名算法中的值,以帮助程序员详细阐述推理。
一旦使用优化编译器,变量可能甚至不存在
很难弄清楚这一点,因为当要求未优化构建以便使用调试器时,我们实际上要求编译器使变量存在以便在调试器中观察它们。
但优化后的代码与未优化的代码有很大不同。
即使在未优化的模式下,语言标准中也没有指定变量的布局方式。
编译器可以选择与其他布局不同的布局。

关于c - 修改gcc的补丁认证程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57205347/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com