禁用 C 和 Pascal 中的 system() 和 exec() 函数
有没有办法通过使用任何编译器参数或修改头/单元文件来禁用 C/C++ 和 Pascal 中的 system()
和 exec()
函数? (这是 Windows)
我尝试对 gcc 和 g++ 使用 -Dsystem=NONEXIST
但 #include
会导致编译错误。
编辑:当然我知道他们可以使用#undef system来绕过防御,所以我尝试注释掉stdlib.h中的system函数行,但是也不起作用。
EDIT2(评论):这是一个系统,用户向该系统提交程序,服务器使用不同的输入数据编译并运行它,然后将程序输出与预先计算的标准输出进行比较,以查看程序是否正确。现在,一些用户发送诸如 system("shutdown -s -t 0");
之类的代码来关闭服务器。
服务器运行的是Windows系统,所以我没有任何chroot环境。此外,服务器应用程序是闭源的,因此我无法控制用户提交的程序的执行方式。我能做的就是修改编译器命令行参数并修改头文件。
Is there any way to disable system()
and exec()
function in C/C++ and Pascal, by using any compiler argument or modifying header/unit file? (It's a Windows)
I've tried using -Dsystem=NONEXIST
for gcc and g++ but #include <cstdio>
causes compile error.
EDIT: Of course I know they can use #undef system
to bypass the defense, so I've tried to comment out the system
function line in stdlib.h, but that doesn't work too.
EDIT2 (comment): It's a system, to which users submit their programs and the server compile and run it with different input data, then compare the program output with pre-calculated standard output to see if the program is correct. Now some users send code like system("shutdown -s -t 0");
to shutdown the server.
The server is running Windows system so I don't have any chroot environment. Also the server application is closed-source so I can do nothing to control how the program submitted by user is executed. What I can do is to modify the compiler commandline argument and modify header files.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
好吧,你可以尝试:
在头文件中,但我很确定任何有价值的代码猴子都可以绕过这样的“保护”。
我有兴趣了解为什么您认为这是必要的(如果我们更好地理解问题,可能会有更好的解决方案)。
唯一想到的是您想要提供一些类似于 Euler 项目的在线编译器/运行器。如果是这种情况,那么您可以在代码中搜索字符串
system(
作为选项,但即使如此,坚定的一方也可以: 。
如果是这种情况,您可能需要考虑使用类似
chroot
这样就没有人可以访问任何危险的二进制文件,例如shutdown
(并且该特定的野兽无论如何都不应该真正由普通用户运行) - 换句话说,限制他们的环境,以便他们只能看到gcc
及其同类,因为即使您以某种方式阻止他们运行外部,您也需要进行适当的沙箱处理 。程序,他们可能仍然能够做危险的事情,比如覆盖文件或打开到自己的盒子的套接字连接,以发送您宝贵的信息内容。
Well, you could try:
in a header file but I'm pretty certain any code monkey worth their salt could bypass such a "protection".
I'd be interested in understanding why you thought this was necessary (there may be a better solution if we understood the problem better).
The only thing that comes to mind is that you want to provide some online compiler/runner akin to the Euler project. If that was the case, then you could search the code for the string
system<whitespace>(
as an option but, even then, a determined party could just:to get around your defenses.
If that is the case, you might want to think about using something like
chroot
so that no-one can even get access to any dangerous binaries likeshutdown
(and that particular beast shouldn't really be runnable by a regular user anyway) - in other words, restrict their environment so that the only things they can even see aregcc
and its kin.You need to do proper sandboxing since, even if you somehow prevented them from running external programs, they may still be able to do dangerous things like overwite files or open up socket connections to their own box to send through the contents of your precious information.
一种可能性是创建您自己的此类函数版本,并将它们链接到您在服务器上编译/链接的每个程序。如果在您的对象中找到该符号,它将优先。
只要确保您获得所有这些即可;)
以具有尽可能少的权限的用户身份运行程序会更好。然后你就不必担心他们删除/访问系统文件、关闭系统等。
编辑:当然,按照我的逻辑,用户也可以提供自己的功能版本,它执行动态库加载和符号查找以找到原始函数。您实际上只需要对其进行沙箱处理即可。
One possibility is to create your own version of such functions, and link them into every program you compile/link on the server. If the symbol is found in your objects, it'll take precedence.
Just make sure you get them all ;)
It would be much better to run the programs as a user with as few privileges as possible. Then you don't have to worry about them deleting/accessing system files, shutting down the system, etc.
EDIT: of course, by my logic, the user could provide their own version of the function also, which does dynamic library loading & symbol lookup to find the original function. You really just need to sandbox it.
对于 unixoid 环境,有 Geordi,它使用操作系统的大量帮助将代码沙箱到被处决。
基本上,您希望在非常受限的环境中运行代码; Linux 提供了一个特殊的进程标志,它可以禁用任何系统调用,这些系统调用可以访问该进程在设置该标志时没有的资源(即,它不允许打开新文件,但任何已打开的文件都可能会被打开)。可以正常访问)。
我认为Windows应该有类似的机制。
For unixoid environments, there is Geordi, which uses a lot of help from the operating system to sandbox the code to be executed.
Basically you want to run the code in a very restricted environment; Linux provides a special process flag for that which disables any system calls that would give access to resources that the process did not have at the point where the flag was set (i.e. it disallows opening new files, but any files that are already open may be accessed normally).
I think Windows should have a similar mechanism.
并非如此(因为调用一些库函数等技巧会调用
system
本身,或者因为生成进程的功能只需使用fork
和execve 即可完成
系统调用,仍然可用...)。但是你为什么这么问?
Not really (because of tricks like calling some library function which would call
system
itself, or because the functionality of spawning processes can be done with justfork
&execve
system calls, which remain available...).But why do you ask that?
您永远不能(正如您所发现的)依靠用户输入来保证安全。
system
和execXX
不太可能是您唯一的问题。这意味着您有以下选择:
unix 上的 Number 3 可以使用 readelf 或 objdump 等实用程序来检查链接符号。这也可以使用二进制文件描述符库来完成。
第 4 种方法需要修改编译器标志,但可能是上面列出的选项中最安全的。
You can never (as you have found out) rely on user input to be safe.
system
andexecXX
are unlikely to be your only problems.This means you have the following options:
chroot
ed jail (not sure how to do this on windows)Number 3 on unix can use utilities like readelf or objdump can check for linked in symbols. This can also probably be done using the Binary File Descriptor Library as well.
Number 4 will require fiddling with compiler flags but probably is the safest out of the options listed above.
使用类似的东西
在这种情况下,即使用户想要交换宏值,他们也不能 。如果他们尝试像这样交换宏值,
则不能,因为 C 不允许在宏中使用这种类型的名字。即使他们以某种方式交换了这些值,那么我们也包含了那些会产生编译时错误的头文件。
You could use something like this
In this case even if the user wants to swap macro values they can't. If they try to swap macro values like this
they can't because C wouldn't allow this type of first name in macros. Even if somehow they swap these values then we have included those header files that will create a compile time error.