关于strcpy的安全漏洞

时间:2014-01-16 06:29:46

标签: c strcpy

通过导致缓冲区溢出,我们可以覆盖保存标志值0的内存,因此即使是错误的密码也会破坏代码..

这将如何在内部发生?有人可以请详细解释..这会在记忆中实际发生吗?

#include<stdio.h>

int main(int argc, char *argv[])
{
int flag = 0;
char passwd[10];

memset(passwd,0,sizeof(passwd));

strcpy(passwd, argv[1]);

if(0 == strcmp("LinuxGeek", passwd))
{
    flag = 1;
}

if(flag)
{
    printf("\n Password cracked \n");
}
else
{
    printf("\n Incorrect passwd \n");

}
return 0;

}

2 个答案:

答案 0 :(得分:6)

请记住,从理论的角度来看,如果存储在passwd中的字符串溢出,它会调用未定义的行为,结果是不可预测的。

实际上,在许多将局部变量存储在堆栈中的现代平台上,如果编译器将flag置于高于passwd缓冲区的位置,它可能会溢出{{1调用。

即。你的堆栈看起来像这样:

strcpy

如果您向| ... | +------------+ | flag | / \ +------------+ | | passwd[10] | | increasing addresses | ... | 写入的字节超过10个字节,passwd只需写入strcpy

请注意,行为因编译器到编译器,平台到平台而异。这个解释涵盖了常见系统上发生的事情,但是知道理论上可以建立一个不使用堆栈的平台,所以这个解释不适用。

答案 1 :(得分:3)

C中的局部变量通常在堆栈上分配。堆栈往往在内存中向下增长,因此“flag”的存储将在为“passwd”分配的存储之后立即生效。

strcpy不检查正在复制的数据量是否会溢出正在复制数据的缓冲区。所以,假设argv [1]完全是11个字符,这就是将要发生的事情:

  • 前10个字符将进入passwd
  • char 11将进入标志
  • 的第一个存储字节
  • 终止空字符将进入标志
  • 的第二个存储字节

因此,标志将为非零。

确切的行为因编译器而异 - 但这是典型的情况。

使用strncpy来避免这种情况。