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?

Robleh
  • 73
  • 1
  • 4
  • 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 '18 at 03:53
  • It was just a quick and dirty abstraction of some source code I was reviewing. – Robleh Jan 10 '18 at 23:35

2 Answers2

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.

Arminius
  • 43,922
  • 13
  • 140
  • 136
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).

Alexander O'Mara
  • 8,774
  • 6
  • 34
  • 38
  • Did you test this? e.g., `?cmd1=TEST` I get `command0 TESTcommand2 command3` but If I do `?cmd1=` 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 '18 at 04:11
  • @EricG That's because it's vulnerable to XSS and you don't see the pseudo-tag `` printed. It becomes clearer if you inspect the source code. – Arminius Jan 10 '18 at 04:12
  • Yep i was testing in the browser and just noticed now the browser escaped it inside html comments. – Eric G Jan 10 '18 at 04:17