大家好。 我遇到的问题是如何处理这种特定的输入情况。
我需要做的一部分项目是通过命令行将参数传入PHP脚本。例如./do_op_2.php“ rm -rf〜/`;”
我尝试过使用escapeshellarg($ argv [1]),escapesellcmd($ argv [1]);但仍然无济于事,它仍然执行命令。我尝试遍历字符串以查找`和;在任何事情发生之前,它仍然会执行。
如果还有其他具体问题,请询问,我愿意提供更多信息。
有好奇心的人的代码。
#!/usr/bin/php
<?php
unset($argv[0]);
$argv[1] = escapeshellarg($argv[1]);
$argv[1] = escapeshellcmd($argv[1]);
function add($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a + $b);
else
return (0);
}
function minus($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a - $b);
else
return (0);
}
function mult($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a * $b);
else
return (0);
}
function divide($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a / $b);
else
return (0);
}
function mod($a, $b)
{
if (is_numeric($a) && is_numeric($b))
return ($a % $b);
else
return (0);
}
function ft_split($str)
{
$ret = array_filter(preg_split('/\s+/', $str));
return ($ret);
}
if ($argc == 2)
{
$split = ft_split(trim($argv[1], " \t"));
if (is_numeric($split[0]) && is_numeric($split[2]))
{
if ($split[1] == "+")
echo add(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "-")
echo minus(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "*")
echo mult(trim($argv[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "/")
echo divide(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else if ($split[1] == "%")
echo mod(trim($split[0], " \t"), trim($split[2], " \t")) . "\n";
else
echo "Syntax Error\n";
}
else
echo "Syntax Error\n";
}else
echo "Incorrect Parameters\n";
?>
答案 0 :(得分:0)
我唯一想到的是command substitution(另请参阅parameter substitution)-在bash和其他shell中会发生。如果这是怎么回事,那么您对情况的报告可能会产生误导(请继续阅读)。
PHP不太可能这样做,它将由Shell完成,并且没有办法修改代码以防止这种情况...这是Shell的功能。
例如,使用${...}
的变量:
$ FOO="test"
$ echo ${FOO}
test
也可以运行命令并将输出(stdout)用作$(...)
的值:
$ echo $(date)
Tue 2 Oct 12:02:59 BST 2018
这的另一个变种是使用反引号:
$ echo `date`
Tue 2 Oct 12:04:03 BST 2018
您在问题中列出了以下内容:
./do_op_2.php '`rm -rf ~/`;'
使用单引号('
)可以防止Shell替换反引号:
$ echo '${FOO}'
${FOO}
$ echo '`date`'
`date`
但是使用双引号("
)不会阻止这种情况:
$ echo "${FOO}"
test
$ echo "`date`"
Tue 2 Oct 12:05:17 BST 2018
我只能假设您报告了单引号,但是当您观察到这种行为时实际上使用了双引号。您的评论支持这一理论。
例如
./do_op_2.php "`rm -rf test.doc`;"
将删除test.doc而不是忽略该命令。