[英]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.