从C程序我想调用一个带有文件名作为参数的shell脚本。用户可以控制文件名。 C类似于(初始化/错误检查省略):
sprintf(buf, "/bin/sh script.sh \"%s\"", filename);
system(buf);
目标设备实际上是一个嵌入式系统,所以我不需要担心恶意用户。显然,这将是Web环境中的攻击媒介。但是,如果系统上有一个文件名,例如,在其名称中包含反引号,则命令将失败,因为shell将对名称执行扩展。有没有阻止命令替换?
答案 0 :(得分:3)
好吧,你总是可以使用fork()然后execv()来重新实现system()。
http://www.opengroup.org/onlinepubs/000095399/functions/system.html
答案 1 :(得分:0)
尝试在系统功能中触发“unalias”。
答案 2 :(得分:0)
由于您将此标记为C,我将为您提供C答案。您将需要转义文件名 - 创建一个由shell正确处理的新字符串,以便This is a file name
生成This\ is\ a\ file\ name
或bad;rm *;filename
之类的内容变为bad\;rm\ \*\;filename
。然后你可以将它传递给shell。
另一种解决方法是直接使用fork
和exec
函数之一运行shell。直接将参数传递给程序不会导致shell命令行扩展或解释。
答案 3 :(得分:0)
正如Sharth所说,你不应该自己使用system
而是fork
和execv
。但是要回答如何使字符串安全传递给shell的问题(如果你坚持使用system
),你需要转义字符串。最简单的方法是首先用'
(单引号,反斜杠,单引号,单引号)替换每个'\''
(单引号),然后添加'
(单引号) )在字符串的开头和结尾。另一个相当容易(但通常效率较低)的方法是在每个字符前放置一个反斜杠,但是你仍然需要做一些特殊的引号技巧来处理嵌入的换行符,所以我更喜欢第一种方法。