C语言编程中常见的漏洞原因

时间:2021-08-03 13:21:19

1. gets

gets()函数不检查缓冲长度,可能导致漏洞。调用函数gets(buffer),会把用户输入的内容放在buffer中,但是对这个内容没有检查长度。如果用户输入内容过长,就会覆盖在buffer之后定义的变量,也就是说用户可以随意更改一些程序中的变量。

那么应该怎么用才安全呢?使用fgets()函数更好一些。首先你要用malloc为buffer分配一部分固定的空间,然后调用fgets的时候传递进去预计长度的值,这样就不会造成溢出了。

2. strcpy

这个家族有三个函数:strcpy、strcat和strcmp,都有溢出问题,因为不检查长度。一种对应方法就是,在使用这些函数前加入检查长度的语句。还有一种方法是使用strncpy、strncat和strncmp,是会检查长度的版本,不过这种方法的问题是,如果截取了长度,不能保证字符串以’\0’结尾,所以可能需要添加一些代码判断一下。

3. sprintf

这个函数的问题也是不检查长度。使用snprintf更好一些。这个函数不仅能够避免缓冲区溢出(检查长度),还可以返回传递字符串的长度,以供判断是否需要处理截取后的’\0’结尾问题。

4. printf及相关函数

这一类的漏洞与字符串格式攻击相关,也就是我们常说的利用格式化字符串漏洞进行攻击。这种攻击通常会导致信息泄露、覆盖内存(%n)等等。这个漏洞可以被以下函数触发:printf, fprintf, sprintf以及snprintf。这些函数的共同特点就是,都以格式化的字符串作为参数,即百分号之后的格式约定。
这种漏洞的应对方式就是,记住一定要硬编码格式化字符串。

5. 文件打开

打开文件的时候要特别小心。文件处理可能有多种被攻击的方法,这里只介绍几个例子。

一般来说我们在打开文件之前都会先确认文件是否存在,但是攻击者可能会建立一个文件(甚至只是建立了一个重要系统文件的符号化链接),在你的检查和实际使用文件之间的时候。open函数比fopen要更安全一些。在打开文件前,unlink文件以消除符号化链接。先用open函数生成一个文件描述符fd,如果fd为-1则打开文件失败。然后再用fdopen来打开这个文件描述符所指的文件,如果之前有符号化链接,那么因为被消除,这个文件就不能打开。