来自 findutils 的手册:
例如,像这两个命令这样的结构
Run Code Online (Sandbox Code Playgroud)# risky find -exec sh -c "something {}" \; find -execdir sh -c "something {}" \;非常危险。这样做的原因是“{}”被扩展为一个文件名,其中可能包含分号或 shell 特有的其他字符。例如,如果有人创建了该文件,
/tmp/foo; rm -rf $HOME那么上面的两个命令可能会删除某人的主目录。因此,出于这个原因,不要运行任何会将不受信任的数据(例如文件名)传递给将参数解释为要进一步解释的命令的命令(例如“sh”)的命令。
在 shell 的情况下,这个问题有一个巧妙的解决方法:
Run Code Online (Sandbox Code Playgroud)# safer find -exec sh -c 'something "$@"' sh {} \; find -execdir sh -c 'something "$@"' sh {} \;这种方法不能保证避免所有问题,但它比将攻击者选择的数据替换到 shell 命令的文本中要安全得多。
find -exec sh -c "something {}" \;在于替换为{}未加引号并因此不被视为单个字符串?在解决方案中find -exec sh -c 'something "$@"' sh {} \;,
first{}被替换了,但是因为没有{}被引用,是不是"$@"也和原来的命令有同样的问题?例如,
"$@"将扩大至"/tmp/foo;","rm","-rf",和
"$HOME"?
为什么{}没有转义或引用?
sh -c如果适用,仍然有或没有它;有或没有find可能没有必要),其中适用相同类型的问题和解决方案,哪些是最小的例子,以便我们可以专注于问题和解决方案尽可能少分心?请参阅为由`bash -c` 执行的命令提供参数的方法谢谢。
Ste*_*itt 29
这实际上与引用无关,而是与参数处理有关。
考虑一个危险的例子:
find -exec sh -c "something {}" \;
Run Code Online (Sandbox Code Playgroud)
这由外壳程序解析,并分成六个词:find, -exec, sh, -c, something {}(不再有引号), ;. 没有什么可以扩展的。shellfind以这六个词作为参数运行。
当find认定的东西的过程,也就是说foo; rm -rf $HOME,它会替换{}用foo; rm -rf $HOME,并运行sh的论据sh,-c和something foo; rm -rf $HOME。
sh现在看到-c,并作为结果解析something foo; rm -rf $HOME(第一个非选项参数)并执行结果。
现在考虑更安全的变体:
find -exec sh -c 'something "$@"' sh {} \;
Run Code Online (Sandbox Code Playgroud)
shell 运行时find带有参数find, -exec, sh, -c, something "$@", sh, {}, ;。
现在,当findfinds 时foo; rm -rf $HOME,它{}再次替换,并sh使用参数sh, -c, something "$@", sh, 运行foo; rm -rf $HOME。
sh看到-c,并解析something "$@"作为命令来运行,并sh与foo; rm -rf $HOME作为位置参数(从开始$0),扩大"$@"到foo; rm -rf $HOME 作为一个单一的值,并运行 something与单个参数foo; rm -rf $HOME。
您可以使用printf. 创建一个新目录,输入它,然后运行
touch "hello; echo pwned"
Run Code Online (Sandbox Code Playgroud)
运行第一个变体如下
find -exec sh -c "printf \"Argument: %s\n\" {}" \;
Run Code Online (Sandbox Code Playgroud)
产生
Argument: .
Argument: ./hello
pwned
Run Code Online (Sandbox Code Playgroud)
而第二个变体,运行为
find -exec sh -c 'printf "Argument: %s\n" "$@"' sh {} \;
Run Code Online (Sandbox Code Playgroud)
产生
Argument: .
Argument: ./hello; echo pwned
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2403 次 |
| 最近记录: |