禁用 C 和 Pascal 中的 system() 和 exec() 函数

发布于 2024-12-13 08:59:06 字数 554 浏览 2 评论 0原文

有没有办法通过使用任何编译器参数或修改头/单元文件来禁用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

偏爱自由 2024-12-20 08:59:07

好吧,你可以尝试:

#define system DontEvenThinkAboutUsingThisFunction
#define exec   OrThisOneYouClown

在头文件中,但我很确定任何有价值的代码猴子都可以绕过这样的“保护”。

我有兴趣了解为什么您认为这是必要的(如果我们更好地理解问题,可能会有更好的解决方案)。

唯一想到的是您想要提供一些类似于 Euler 项目的在线编译器/运行器。如果是这种情况,那么您可以在代码中搜索字符串 system( 作为选项,但即使如此,坚定的一方也可以

#define InoccuousFunction system

: 。

如果是这种情况,您可能需要考虑使用类似 chroot这样就没有人可以访问任何危险的二进制文件,例如shutdown(并且该特定的野兽无论如何都不应该真正由普通用户运行) - 换句话说,限制他们的环境,以便他们只能看到 gcc 及其同类,

因为即使您以某种方式阻止他们运行外部,您也需要进行适当的沙箱处理 。程序,他们可能仍然能够做危险的事情,比如覆盖文件或打开到自己的盒子的套接字连接,以发送您宝贵的信息内容。

Well, you could try:

#define system DontEvenThinkAboutUsingThisFunction
#define exec   OrThisOneYouClown

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:

#define InoccuousFunction system

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 like shutdown (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 are gcc 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.

爱冒险 2024-12-20 08:59:07

一种可能性是创建您自己的此类函数版本,并将它们链接到您在服务器上编译/链接的每个程序。如果在您的对象中找到该符号,它将优先。

只要确保您获得所有这些即可;)

以具有尽可能少的权限的用户身份运行程序会更好。然后你就不必担心他们删除/访问系统文件、关闭系统等。

编辑:当然,按照我的逻辑,用户也可以提供自己的功能版本,它执行动态库加载和符号查找以找到原始函数。您实际上只需要对其进行沙箱处理即可。

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.

风流物 2024-12-20 08:59:07

对于 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.

痴情换悲伤 2024-12-20 08:59:07

并非如此(因为调用一些库函数等技巧会调用 system 本身,或者因为生成进程的功能只需使用 forkexecve 即可完成 系统调用,仍然可用...)。

但是你为什么这么问

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 just fork & execve system calls, which remain available...).

But why do you ask that?

无需解释 2024-12-20 08:59:07

您永远不能(正如您所发现的)依靠用户输入来保证安全。 systemexecXX 不太可能是您唯一的问题。

这意味着您有以下选择:

  1. 在某种经过 chroot 编辑的监狱中运行程序(不知道如何在 Windows 上执行此操作)
  2. 在编译之前扫描代码以确保不存在“非法”函数。
  3. 编译后扫描可执行二进制文件,以确保它没有使用任何“禁止”的库函数。
  4. 防止链接器链接到任何外部库,包括 UNIX 上的标准 C 库 (libc)。然后,您创建自己的“libc”,它明确允许某些功能。

unix 上的 Number 3 可以使用 readelf 或 objdump 等实用程序来检查链接符号。这也可以使用二进制文件描述符库来完成。

第 4 种方法需要修改编译器标志,但可能是上面列出的选项中最安全的。

You can never (as you have found out) rely on user input to be safe. system and execXX are unlikely to be your only problems.

This means you have the following options:

  1. Run the program in some kind of chrooted jail (not sure how to do this on windows)
  2. Scan the code before before compiling to ensure there are no "illegal" functions.
  3. Scan the executable binary after compiling to ensure that it is not using any "forbidden" library function.
  4. Prevent the linker from linking to any external libraries including the standard C library (libc) on unix. You then create your own "libc" which explicilty allow certain functions.

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.

╰沐子 2024-12-20 08:59:07

使用类似的东西

#include<stdlib.h>
#include<unistd.h>
#define system  <stdlib.h>
#define exec   <unistd.h>

在这种情况下,即使用户想要交换宏值,他们也不能 。如果他们尝试像这样交换宏值,

#define <stdlib.h> system
#define <unistd.h> exec

则不能,因为 C 不允许在宏中使用这种类型的名字。即使他们以某种方式交换了这些值,那么我们也包含了那些会产生编译时错误的头文件。

You could use something like this

#include<stdlib.h>
#include<unistd.h>
#define system  <stdlib.h>
#define exec   <unistd.h>

In this case even if the user wants to swap macro values they can't. If they try to swap macro values like this

#define <stdlib.h> system
#define <unistd.h> exec

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文