我正在使用unix服务器。
我从我的客户端获取一个c文件作为输入,我编译。
c文件应该是非常基本的,并且只包含来自stdio,stdlib,math,string的函数。
GCC编译器中是否有任何标志不允许使用任何其他库,并且在使用其他库时会抛出编译错误?
如果有一个不涉及GCC的解决方案,它也可能是好的,但我不想检查该文件。
感谢。
答案 0 :(得分:6)
限制库(包括编译时的头文件和链接时的库链接)不会阻止不受信任的代码直接调用危险(如安全相关的)内核系统调用。这可以通过不可信代码来完成,例如通过使用内联汇编或shellcode / exploit技术,例如通过故意覆盖堆栈上的返回地址指向包含shellcode的字符串。
话虽如此,您可以使用-nostdlib -nodefaultlibs
链接器选项来阻止链接到库。但是,这仍然只允许您拥有整个libc,或者不包含任何libc。您无法有选择地仅链接到libc的一部分(例如,有printf()
而不是system()
)。
只允许某些包含也不是非常有效:代码只能复制包含文件中的声明,而不是包含某些标题以绕过限制,只允许特定的#include
语句。例如:
int system(const char *);
int main() {
return system("uname -a");
}
如果它必须是安全的,你应该考虑在运行时沙箱化代码而不是试图防止不安全的代码编译。
答案 1 :(得分:1)
将选项-nodefaultlibs
或-nostdlib
传递给gcc,以及仅包含允许的库的选项(如数学库的-lm
)。有关这些选项的详细信息,请查看gcc manual。
<强>
-nodefaultlibs
强>
链接时请勿使用标准系统库。只有 您指定的库将传递给链接器。
答案 2 :(得分: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;
}