代码之家  ›  专栏  ›  技术社区  ›  jbarlow

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

  •  4
  • jbarlow  · 技术社区  · 14 年前

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

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

    目标设备实际上是一个嵌入式系统,所以我不需要担心恶意用户。显然,这将是Web环境中的攻击向量。但是,如果系统上有一个文件名,例如其名称中包含反引号,则该命令将失败,因为shell将对该名称执行扩展。是否有防止命令替换的措施?

    4 回复  |  直到 14 年前
        1
  •  3
  •   Bill Lynch    14 年前

    好吧,您总是可以使用对fork()的调用,然后使用execv()来重新实现system()。

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

        2
  •  0
  •   Hemanth    14 年前

    尝试触发系统功能中的“unalias”。

        3
  •  0
  •   nategoose    14 年前

    既然你把这个标记为C,我会给你一个C的答案。您将需要对文件名进行转义——创建一个新的字符串,该字符串将被shell正确处理,以便 This is a file name 生产 This\ is\ a\ file\ name bad;rm *;filename 变成 bad\;rm\ \*\;filename . 然后你可以把它传给壳。

    另一种解决方法是直接用 fork 其中一个 exec 功能。直接向程序传递参数不会导致shell命令行扩展或解释。

        4
  •  0
  •   R.. GitHub STOP HELPING ICE    14 年前

    正如沙思所说,你不应该使用 system 但是 fork execv 你自己。但要回答这样一个问题:如何使字符串安全地传递给shell(以防您坚持使用 系统 )需要转义字符串。最简单的方法是首先替换 ' (单引号)带 '\'' (单引号、反斜杠、单引号、单引号)然后添加 ' (单引号)在字符串的开始和结束处。另一个相当简单(但通常效率较低)的方法是在每个字符之前放置一个反斜杠,但是您仍然需要做一些特殊的引号技巧来处理嵌入的换行符,所以我更喜欢第一个方法。