Eth*_*man 41 c security exploit buffer-overflow
"普通人不想自由.他只是想要安全." - HL Menken
我正在尝试编写非常安全的C.下面我列出了一些我使用的技术,并且询问它们是否像我认为的那样安全.请不要犹豫将我的代码/先入之见撕成碎片.任何能找到最微不足道的漏洞或者教我一个新想法的答案都会受到高度重视.
根据GNU C编程教程 getline:
getline函数将根据需要通过realloc函数自动扩大内存块,因此永远不会缺少空间 - 这是getline如此安全的一个原因.[..]请注意,无论多长时间,getline都可以安全地处理您的输入线.
我假设getline应该在所有输入下防止从流中读取时发生缓冲区溢出.
如果malloc遇到错误,malloc将返回NULL指针.这会带来安全风险,因为仍然可以将指针算法应用于NULL(0x0)指针,因此维基百科推荐
/* Allocate space for an array with ten elements of type int. */
int *ptr = (int*)malloc(10 * sizeof (int));
if (ptr == NULL) {
/* Memory could not be allocated, the program should handle
the error here as appropriate. */
}
Run Code Online (Sandbox Code Playgroud)
当使用sscanf时,我已经养成了将要提取的字符串分配给输入字符串大小的习惯,希望避免出现溢出的可能性.例如:
const char *inputStr = "a01234b4567c";
const char *formatStr = "a%[0-9]b%[0-9]c":
char *str1[strlen(inputStr)];
char *str2[strlen(inputStr)];
sscanf(inputStr, formatStr, str1, str2);
Run Code Online (Sandbox Code Playgroud)
因为str1和str2是inputStr的大小,并且不能从inputStr读取比strlen(inputStr)更多的字符,所以看起来不可能,因为inputStr的所有可能值都会导致缓冲区溢出?
虽然我发布了大量问题但我不希望任何人回答所有这些问题.这些问题更多地是我正在寻找的各种答案的指南.我真的想学习安全的C心态.
许多资源都是从答案中借来的.
我认为你的sscanf例子是错误的.使用这种方式时它仍然会溢出.
试试这个,它指定要读取的最大字节数:
void main(int argc, char **argv)
{
char buf[256];
sscanf(argv[0], "%255s", &buf);
}
Run Code Online (Sandbox Code Playgroud)
在测试方面,我会编写一个程序,生成随机长度的随机字符串并将它们提供给您的程序,并确保它们得到适当的处理.
从流中读取
“将根据需要自动扩大内存块”这一事实getline()意味着这可以被用作拒绝服务攻击,因为生成一个太长的输入会耗尽可用内存,这是微不足道的。进程(或更糟糕的是,系统!)。一旦发生内存不足的情况,其他漏洞也可能会发挥作用。低内存/无内存中的代码行为很少是好的,并且很难预测。恕我直言,对所有事物设置合理的上限会更安全,尤其是在安全敏感的应用程序中。
此外(正如您通过提及特殊字符所预期的那样),getline()仅给您一个缓冲区;它不对缓冲区的内容做出任何保证(因为安全性完全取决于应用程序)。因此,清理输入仍然是处理和验证用户数据的重要组成部分。
扫描仪
我倾向于使用正则表达式库,并且对用户数据定义非常狭窄的正则表达式,而不是使用sscanf. 这样您就可以在输入时执行大量验证。
普通的留言