有没有办法阻止 sh/bash 执行命令替换?

发布于 2024-09-29 05:12:07 字数 284 浏览 3 评论 0原文

我想从 C 程序中调用一个以文件名作为参数的 shell 脚本。用户可以控制文件名。 C 类似于(省略初始化/错误检查):

sprintf(buf, "/bin/sh script.sh \"%s\"", filename);
system(buf);

目标设备实际上是嵌入式系统,因此我不需要担心恶意用户。显然,这将是网络环境中的攻击媒介。尽管如此,如果系统上存在一个文件名(例如,其名称中包含反引号),则命令将失败,因为 shell 将对名称执行扩展。有什么办法可以防止命令替换吗?

From a C program I want to call a shell script with a filename as a parameter. Users can control the filename. The C is something like (initialization/error checking omitted):

sprintf(buf, "/bin/sh script.sh \"%s\"", filename);
system(buf);

The target device is actually an embedded system so I don't need to worry about malicious users. Obviously this would be an attack vector in a web environment. Still, if there is a filename on the system which, for example, contains backquotes in its name, the command will fail because the shell will perform expansion on the name. Is there any to prevent command substitution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

橘味果▽酱 2024-10-06 05:12:07

好吧,您始终可以通过调用 fork() 然后调用 execv() 来重新实现 system()。

http://www.opengroup.org/onlinepubs/000095399/functions/system.html

Well, you could always reimplement system() using a call to fork() and then execv().

http://www.opengroup.org/onlinepubs/000095399/functions/system.html

你的背包 2024-10-06 05:12:07

尝试在系统函数中触发“unalias”。

Try triggering "unalias " in the system function.

老街孤人 2024-10-06 05:12:07

既然您将其标记为 CI,将为您提供 C 答案。您需要对文件名进行转义——创建一个由 shell 正确处理的新字符串,以便 This is a file name 生成 This\ is\ a\ file\ namebad;rm *;filename 变为 bad\;rm\ \*\;filename。然后你可以将其传递给 shell。

解决此问题的另一种方法是直接使用 fork 和其中一个 exec 函数运行 shell。直接向程序传递参数不会导致 shell 命令行扩展或解释。

Since you tagged this as C I will provide you with a C answer. You will need to escape the filename -- create a new string that will be treated properly by the shell, so that things like This is a file name produces This\ is\ a\ file\ name or bad;rm *;filename becomes bad\;rm\ \*\;filename. Then you can pass that to the shell.

Another way around this would be to run the shell directly with fork and one of the exec functions. Passing arguments directly to programs does not result in shell command line expansion or interpretation.

好倦 2024-10-06 05:12:07

正如 sharth 所说,您不应该使用 system 而应该自己使用 forkexecv 。但是要回答如何使字符串安全地传递到 shell 的问题(如果您坚持使用 system),您需要对字符串进行转义。最简单的方法是首先将每个出现的 ' (单引号)替换为 '\'' (单引号、反斜杠、单引号、单引号),然后在字符串的开头和结尾添加 ' (单引号)。另一种相当简单(但通常效率较低)的方法是在每个字符之前放置一个反斜杠,但是您仍然需要执行一些特殊的引号技巧来处理嵌入的换行符,所以我更喜欢第一种方法。

As sharth said, you should not use system but fork and execv yourself. But to answer the question of how you make strings safe to pass to the shell (in case you insist on using system), you need to escape the string. The simplest way to do this is to first replace every occurrence of ' (single quote) with '\'' (single quote, backslash, single quote, single quote) then add ' (single quote) at the beginning and end of the string. The other fairly easy (but usually less efficient) method is to place a backslash before every single character, but then you still need to do some special quotation mark tricks to handle embedded newlines, so I prefer the first method.

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