PHP防止'`-rf〜/`;'

时间:2018-10-02 10:41:47

标签: command-line php

大家好。 我遇到的问题是如何处理这种特定的输入情况。

我需要做的一部分项目是通过命令行将参数传入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";
?>

1 个答案:

答案 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而不是忽略该命令。