C 解决“编写安全代码”中的安全漏洞

C 解决“编写安全代码”中的安全漏洞,c,security,C,Security,我正在研究代码安全性,并试图对以下两个片段进行安全性分析,这两个片段摘自《编写安全代码》,第二版: 在第一个例子中,我认为唯一不安全的语句是 strcpybuf,输入; 应该是哪一个 strncpybuf,输入,sizeofbuf-1; 所有其他printf都是安全的:尽管他们使用的参数比他们应该使用的少,但他们是故意这样做的 在第二种情况下,printfs是安全的,但是fprintfstdout,buf;不是且应替换为以下代码:fprintfstdout,%s,buf 我的问题是pFile=f

我正在研究代码安全性,并试图对以下两个片段进行安全性分析,这两个片段摘自《编写安全代码》,第二版:

在第一个例子中,我认为唯一不安全的语句是 strcpybuf,输入; 应该是哪一个 strncpybuf,输入,sizeofbuf-1; 所有其他printf都是安全的:尽管他们使用的参数比他们应该使用的少,但他们是故意这样做的

在第二种情况下,printfs是安全的,但是fprintfstdout,buf;不是且应替换为以下代码:fprintfstdout,%s,buf

我的问题是pFile=fopenargv[1],r;由于可能的竞争条件,分析程序也认为这是不安全的,但我看不出在这段代码中可以利用这一点。如果文件以只读方式打开,攻击者会对其进行恶意攻击吗?我想没有

所以问题是:你认为这个分析正确吗?你能找到其他缺陷吗?或者我的推理有问题吗


谢谢大家!

我的第一个想法是,将未经消毒的程序输入传递到libc调用中是不好的。libc会溢出的情况太多了,开发人员不应该传递超出libc预期的参数,比如在这种情况下字符串应该是 但是既然你提到了种族条件,我认为虽然在这个特殊的例子中没有特别的问题,但是使用fopen通常是不受欢迎的,因为它容易受到种族条件的影响。如果您正在寻址一个文件,则使用接受文件名而不是文件句柄的函数来寻址任何文件。如果使用一种或另一种操作,通过文件路径名引用文件,则文件的状态可能会更改,并且程序对该状态的假设可能不再正确。下面的文章对此进行了更好的解释


我的第一个想法是,将未经消毒的程序输入传递到libc调用中是不好的。libc会溢出的情况太多了,开发人员不应该传递超出libc预期的参数,比如在这种情况下字符串应该是 但是既然你提到了种族条件,我认为虽然在这个特殊的例子中没有特别的问题,但是使用fopen通常是不受欢迎的,因为它容易受到种族条件的影响。如果您正在寻址一个文件,则使用接受文件名而不是文件句柄的函数来寻址任何文件。如果使用一种或另一种操作,通过文件路径名引用文件,则文件的状态可能会更改,并且程序对该状态的假设可能不再正确。下面的文章对此进行了更好的解释

从中可以清楚地看出:

如果打开一个文件,然后从中读取,即使应用程序在这两个操作之间没有执行任何其他操作,其他一些进程也可能在文件打开后和读取之前更改该文件。如果相同或不同应用程序中的两个不同进程正在写入同一个文件,则无法知道哪一个将首先写入,哪一个将覆盖另一个写入的数据。这种情况会导致安全漏洞

可以利用两种基本类型的竞争条件:检查时间-使用时间TOCTOU和信号处理

此外,如图所示的fopen调用没有对文件名进行任何清理。你当然不会那么做,对吧?绝对应该对名称进行分析、检查,并且不要信任它,因为它是程序的参数。理想情况下,您应该

从以下内容可以清楚地描述:

如果打开一个文件,然后从中读取,即使应用程序在这两个操作之间没有执行任何其他操作,其他一些进程也可能在文件打开后和读取之前更改该文件。如果相同或不同应用程序中的两个不同进程正在写入同一个文件,则无法知道哪一个将首先写入,哪一个将覆盖另一个写入的数据。这种情况会导致安全漏洞

可以利用两种基本类型的竞争条件:检查时间-使用时间TOCTOU和信号处理


此外,如图所示的fopen调用没有对文件名进行任何清理。你当然不会那么做,对吧?绝对应该对名称进行分析、检查,并且不要信任它,因为它是程序的参数。理想情况下你应该

你的意思是:?是的,对不起!我不知道为什么它没有出现!strncpybuf,输入,sizeofbuf-1;仍然是错误的,因为如果源太长,它不会nul终止目标。@Steve你是对的。我将添加buf[sizeofbuf-1]=\0;在它之后还有一个输入错误:它是sizeofbuf-1而不是sizeofbuf-1。该死,安全检查很难。你是说:?是的,对不起!我不知道为什么它没有出现!strncpybuf,输入,sizeofbuf-1;仍然是错误的,因为它不会nul终止目的地i
f来源太长。@Steve你说得对。我将添加buf[sizeofbuf-1]=\0;在它之后还有一个输入错误:它是sizeofbuf-1而不是sizeofbuf-1。该死,安全检查很难。攻击者可以使用带有符号链接的fopen来了解,例如,某个他无权访问的文件是否存在?例如,当然可以。如果程序只是将文件转移到stdout,攻击者可以读取/etc/shadow,例如,这有点糟糕,但所有这些都是可以读取的私钥,等等。因此,攻击者可以使用带有符号链接的fopen来了解,例如,某个他无权访问的文件是否存在?例如,当然可以。如果程序只是将文件转移到stdout,攻击者可以读取/etc/shadow,例如,这有点糟糕,但它们都是可以读取的私钥,等等