phpcode-injection

dealing with eval in PHP


Disclaimer: This is just an example to learn about PHP code injections and not production code used in any way. I am fully aware that this is not good coding practice.

I have the following PHP Script:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Sample Script</title>
  </head>
  <body>
    <h1>Sample page</h1>
    <p>Now doing the maths. Please enter a formula to compute. Example: 1+1.</p>
    <form method="get">
      <p>Formula: <input type="text" name="maths" /></p>
      <p><input type="submit" value="compute" /></p>
    </form>
<? 
  if (( isset($_REQUEST["maths"])) && ($_REQUEST["maths"] != "") )
    { 

      echo "<p>The result is: ";
      eval("echo (".$_REQUEST["maths"].");");
      echo "</p>";
    }
?>
  </body>
</html>

This script is vulnerable to PHP code injection and I can break it via (which I found out mostly via trial and error).

$a='1');phpinfo();echo($a

However, I don't fully understand what is going on. From my understanding, I would need to finish the echo statement, insert my own code (e.g. phpinfo()) and then write another function (e.g. echo) to deal with the closing bracket.

I assumed something like this would work:

");phpinfo();echo("

However, this doesn't work as an injection since phpinfo is treated as part of the string and doesn't get evaluated by eval. I also tried to escape the quotation marks, but to no avail.

Questions:


Solution

  • When you use that input, the result of substituting the variable is:

    eval("echo ($a='1');phpinfo();echo($a);");
    

    So this assigns $a='1', and echoes the result of that assignment (the value that was assigned to $a). Then it executes phpinfo(). And finally it echoes $a again.

    If you try to use );phpinfo();echo( it doesn't work because it tries to execute echo (). But echo requires at least 1 argument.

    So to inject code here, you have to ensure that the input begins with something that will be valid after echo (, and it has to end with something that's valid before );. Put the additional code that you want to inject between these two parts.