Ho notato un commento strongmente sottovalutato qui: link
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');");
Ho provato a ignorare il codice e portare all'esecuzione di input utente malizioso con eval
, ma non ho potuto. Mi chiedo perché sia stato downvoted.
Come puoi vedere se le parentesi graffe non corrispondono, non aggiunge 'if(0){' . $code . '}
ed esegue l'input dell'utente così com'è con parentesi graffe non corrispondenti che generano eccezioni e non verranno realmente eseguite.
Se le parentesi graffe sono una corrispondenza, chiama eval
, ma poiché è all'interno di if {0}
"sandbox", non fa nulla. Come può qualcuno aggirare questo?
So che la valutazione è insicura, ma voglio sapere qual è il trucco qui. Come si può ignorare la sicurezza di if (0) e le parentesi graffe nel codice sopra?
Ho provato ad aggiungere // {in modo da squilibrare le parentesi graffe e non aggiungerà if (0) e chiama eval, ma token_get_all rovina tutto ciò.