1

我正在使用 Unix 服务器。

我正在从我的客户端获取 ac 文件作为输入,并对其进行编译。

c 文件应该是非常基本的,并且只包含来自 stdio 、 stdlib 、数学、字符串的函数。

GCC 编译器中是否有任何标志不允许使用任何其他库,并且在使用其他库的情况下会引发编译错误?

如果有不涉及 GCC 的解决方案,它也可能很好,但我不想检查文件。

谢谢。

4

3 回答 3

6

限制库(包括编译时的头文件和链接时的库链接)不会阻止不受信任的代码直接调用危险的(如与安全相关的)内核系统调用。这可以通过不受信任的代码来完成,例如通过使用内联汇编或 shellcode/exploit 技术,例如通过故意覆盖堆栈上的返回地址以指向包含 shellcode 的字符串。

话虽如此,您可以使用-nostdlib -nodefaultlibs链接器选项来防止链接到库。但是,这仍然只允许您拥有整个 libc,或者一个都没有。您不能有选择地仅链接到 libc 的一部分(例如 have printf()but not system())。

只允许某些包含也不是很有效:代码可以只从包含文件中复制声明,而不是包含某些标头来绕过仅允许特定#include语句的限制。例子:

int system(const char *);
int main() {
    return system("uname -a");
}

如果它必须是安全的,您可能应该考虑在运行时对代码进行沙箱处理,而不是试图阻止不安全的代码编译。

于 2012-04-21T20:08:49.970 回答
1

将选项-nodefaultlibs或传递-nostdlib给 gcc,以及仅包含允许库的选项(如-lm数学库)。有关这些选项的更多信息,请查看gcc 手册

-nodefaultlibs
链接时不要使用标准系统库。只有您指定的库才会传递给链接器。

于 2012-04-21T19:59:50.460 回答
1

为了说明您允许包含 stdlib.h 的不安全性,我将编写一个可以在您的机器上运行任意代码的小程序。

#include <stdlib.h>

int main() {
    system("`which python` -c \"print 'hello word'\"");
    // instead of simply printing hello world i could open a socket back to the 
    // attacker's machine and start reading in abitrary code and executing it.
    return 0;
}
于 2012-04-21T20:13:19.843 回答