7

I'm trying to learn more about PHP eval() exploitation and I came across this scenario:

<?php

$test = array();
$test[0] = "command0 ";
$test[1] = $_GET["cmd1"];
$test[2] = "command2 ";
$test[3] = "command3 ";

$params = "";
for ($i = 0; $i < count($test); $i++) {
        $params .= "\$test[$i]";
}

echo $params;
echo "<br>";

$cmd = "echo \"" . $params . "\";";
echo $cmd;
echo "<br>";

eval($cmd);
?>

I've tried to inject several combinations of double-quotes and backslashes into the $_GET parameter but have had no luck breaking out of the $cmd string.

Beyond the XSS bug, is this code snippet vulnerable? Can this be abused for PHP code injection?

2
  • I think you have setup a bit of complexity for teaching yourself eval() exploitation. I did notice that when you define the strings in $test[x] for {x=0,2,3} there is a space afterwards but when you set $_GET["cmd1"] there is no string afterwards.
    – Eric G
    Jan 10, 2018 at 3:53
  • It was just a quick and dirty abstraction of some source code I was reviewing.
    – Robleh
    Jan 10, 2018 at 23:35

2 Answers 2

5

No, this is not vulnerable to PHP code injection.

The string passed to eval() is simply not user-controlled. There is no path from the source $_GET["cmd1"] to the sink eval():

  • The argument to eval() is $cmd.
  • $cmd is assembled from a fixed string and $params.
  • $params is accumulated from a fixed string and $i.
  • $i is an iteration variable that depends on the (fixed) length of the array $text.

That said, passing a generated array through eval is certainly not good style and you're obviously not sanitizing output which makes the code vulnerable to XSS.

1
  • Makes sense thank you, +1 for mentioning source to sink
    – Robleh
    Jan 10, 2018 at 23:40
1

The code you are evaluating here is actually completely fixed, so PHP code injection is not possible here.

The code that gets evaled is always:

echo "$test[0]$test[1]$test[2]$test[3]";

It references those variables as string data, which is safe (except against XSS).

3
  • Did you test this? e.g., ?cmd1=TEST I get command0 TESTcommand2 command3 but If I do ?cmd1=<?php TEST ?> the output is command0 command2 command3. I have tried some PHP scripts, instead of TEST like phpinfo(); it doesn't show me the output, but it doesn't show me the raw text from ?cmd1=
    – Eric G
    Jan 10, 2018 at 4:11
  • @EricG That's because it's vulnerable to XSS and you don't see the pseudo-tag <?php ...?> printed. It becomes clearer if you inspect the source code.
    – Arminius
    Jan 10, 2018 at 4:12
  • Yep i was testing in the browser and just noticed now the browser escaped it inside html comments.
    – Eric G
    Jan 10, 2018 at 4:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .