解析和应对PHP中的eval函数
<p>免责声明:这只是一个示例,用于学习PHP代码注入,而不是在任何方式中使用的生产代码。我完全意识到这不是良好的编码实践。</p>
<p>我有以下PHP脚本:</p>
<pre class="brush:php;toolbar:false;"><!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>示例脚本</title>
</head>
<body>
<h1>示例页面</h1>
<p>现在进行数学计算。请输入一个公式进行计算。例如:1+1。</p>
<form method="get">
<p>公式:<input type="text" name="maths" /></p>
<p><input type="submit" value="计算" /></p>
</form>
<?
if (( isset($_REQUEST["maths"])) && ($_REQUEST["maths"] != "") )
{
echo "<p>结果是:";
eval("echo (".$_REQUEST["maths"].");");
echo "</p>";
}
?>
</body>
</html></pre>
<p>这个脚本容易受到PHP代码注入的攻击,我可以通过以下方式来破坏它(大部分是通过试错发现的):</p>
<pre class="brush:php;toolbar:false;">$a='1');phpinfo();echo($a</pre>
<p>然而,我并不完全理解其中的原理。据我理解,我需要完成echo语句,插入自己的代码(例如phpinfo()),然后编写另一个函数(例如echo)来处理闭合括号。</p>
<p>我以为像这样的代码会起作用:</p>
<pre class="brush:php;toolbar:false;">");phpinfo();echo("</pre>
<p>然而,这并不起作用,因为phpinfo被视为字符串的一部分,不会被eval函数评估。
我还尝试了转义引号,但没有成功。</p>
<p>问题:</p>
<ul>
<li>在这里注入代码的正确方式是什么?</li>
<li>为什么<code>$a='1');phpinfo();echo($a</code>会起作用?</li>
</ul><p><br /></p>