我注意到这里有一个被严重低估的评论:http: //php.net/manual/en/function.php-check-syntax.php
function eval_syntax($code)
{
$braces = 0;
$inString = 0;
// We need to know if braces are correctly balanced.
// This is not trivial due to variable interpolation
// which occurs in heredoc, backticked and double quoted strings
foreach (token_get_all('<?php ' . $code) as $token)
{
if (is_array($token))
{
switch ($token[0])
{
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case T_START_HEREDOC: ++$inString; break;
case T_END_HEREDOC: --$inString; break;
}
}
else if ($inString & 1)
{
switch ($token)
{
case '`':
case '"': --$inString; break;
}
}
else
{
switch ($token)
{
case '`':
case '"': ++$inString; break;
case '{': ++$braces; break;
case '}':
if ($inString) --$inString;
else
{
--$braces;
if ($braces < 0) return false;
}
break;
}
}
}
// If $braces is not zero, then we are sure that $code is broken.
// We run it anyway in order to catch the error message and line number.
// Else, if $braces are correctly balanced, then we can safely put
// $code in a dead code sandbox to prevent its execution.
// Note that without this sandbox, a function or class declaration inside
// $code could throw a "Cannot redeclare" fatal error.
echo "Braces: ".$braces."\r\n";
$braces || $code = "if(0){{$code}\n}";
if (false === eval($code)) {}
}
eval_syntax("file_put_contents('/home/yourname/Desktop/done.txt', 'OVERWRITTEN');");
我试图绕过代码并导致恶意用户输入执行eval
,但我做不到。我想知道为什么它被否决了。
如您所见,如果大括号不匹配,它不会添加'if(0){' . $code . '}
并按原样执行用户输入,不匹配的大括号将引发异常并且不会真正运行。
如果大括号匹配,它会调用eval
,但由于它在if {0}
“沙盒”内部,它什么也不做。有人怎么能绕过这个?
我知道 eval 是不安全的,但我想知道这里有什么诀窍。如何绕过上面代码中的 if (0) 和大括号检查的安全性?
我试图添加 // { 所以它会不平衡大括号,它不会添加 if (0) 并调用 eval,但是 token_get_all 破坏了它。