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. Commented Jan 10, 2018 at 3:53
  • It was just a quick and dirty abstraction of some source code I was reviewing. Commented 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 Commented 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= Commented 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. Commented Jan 10, 2018 at 4:12
  • Yep i was testing in the browser and just noticed now the browser escaped it inside html comments. Commented Jan 10, 2018 at 4:17

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.