如果我错了,请纠正我,我在该网站上进行了研究,但找不到有关此问题的任何综合文章。C中有许多不安全的函数可以导致缓冲区溢出,并且可以使用安全的函数来替换它们。我有几个:
gets()
===替换为=== fgets()
sprintf()
===替换为===吗?strcat()
===替换为===吗?strcpy()
===替换为=== strncpy()
vsprintf()
===替换为=== vsnprintf()
另外,我坚持下面的不安全字节复制和不安全字节输入代码。我该如何解决问题?为什么此代码有漏洞?
int copy_buf (char *to, int pos, char *from, int len)
{
int i;
for (i=0;i<len;<i++){
to[pos] = from [i];
pos++;
}
return pos
}
Run Code Online (Sandbox Code Playgroud)
对于字节输入,是fread()
不安全的功能吗?为什么缓冲区溢出在这里发生?
short read_chunk(FILE fil, char *to)
{
short len;
fread(&len, 2, 1, fil);
fread(to, 1, len, fil);
return len;
}
Run Code Online (Sandbox Code Playgroud)
strncpy
是不是一个安全的替代strcpy
。实际上,尽管在命名上很不幸,但这些功能是无关的。安全替换strcpy
是strlcpy
一些* nix实现提供的非标准功能,作为扩展。使用strncpy
“安全”字符串复制是不合格代码的直接标志。
不安全的函数的另一组(虽然不安全出于不同的原因)是从功能ato..
基团:atoi
,atof
,atol
等。如果发生溢出,这些函数将触发未定义的行为。他们的安全替代品是从功能strto...
组:strtol
,strtod
和这样的。
copy_buf
从某种意义上说,您的函数没有什么“不安全”的地方,因为它为调用代码提供了执行对的安全调用所需的一切手段copy_buf
。在这种情况下,传递正确值的责任由调用者承担。
您的read_chunk
函数更加危险,因为调用代码无法知道缓冲区应该有多大。对于从外部传递的缓冲区,此功能还没有完美的解决方案。至少使调用代码也传递缓冲区的大小是有意义的。这将read_chunk
确保缓冲区不会溢出。另外,read_chunk
应告知调用代码不完整的读取。您应该为调用者提供完成阅读的方式。
这是一些不安全的C函数及其替换的New函数的列表
无论某些功能如何使用,某些功能都具有危险的行为。通常在执行此类功能时并未考虑安全性问题。gets()函数是不安全的,因为它不会对其输入的大小执行边界检查。
攻击者可以轻松地将任意大小的输入发送到gets()并溢出目标缓冲区。同样,>>运算符在读入静态分配的字符数组时使用也不安全,因为它不会对其输入的大小执行边界检查。攻击者可以轻松地将任意大小的输入发送给>>运算符,并使目标缓冲区溢出。
下面的代码调用gets()将信息读入缓冲区。
char buf[24];
printf("Please enter your name and press <Enter>\n");
gets(buf);
...
}
Run Code Online (Sandbox Code Playgroud)
但是,程序员使用的函数gets()本质上是不安全的,因为它会盲目地将所有输入从STDIN复制到缓冲区,而不检查大小。这允许用户提供一个大于缓冲区大小的字符串,从而导致溢出情况
您可以在此处进一步阅读有关C / C ++中的危险的更多信息。
sprintf => snprintf
strcat => strncat
Run Code Online (Sandbox Code Playgroud)