获取 PHP eval 的跟踪调用列表或手动覆盖它

Get trace call list of PHP eval or override it manually

我正在调查 Revive Adserver 中一个尚未发现的零日攻击。攻击发生在一个位置,攻击者能够调用已经在 Revive Adserver 代码库的开发和生产版本中的 eval

我调查了 access_logs,他们表明用户正在对交付脚本 fc.php 进行 POST 攻击,但 POST 的有效负载仍然不清楚。

Revive Adserver 的代码库有时非常复杂、陈旧和怪异。代码中有很多地方调用了 eval,您可能会发现类似这样的内容:

$values = eval(substr(file_get_contents(self::$file), 6));

这其实是一个Smarty模板的东西,但是看起来真的很吓人。

如前所述,整个代码中有很多 eval 次出现,此时要花很多时间来完成每一次。

是否可以覆盖 PHP 中的 eval 函数以显示一些跟踪信息,即从哪个文件调用它,它发生在哪一行?

如果不是,是否可以通过修改 PHP 的 C/C++ 源代码并完全重新编译来做到这一点?

或者是否有 PHP 扩展程序或某些工具可以跟踪整个脚本中的所有 eval 回调?

如果没有这样的东西,如果有人开发它会很棒,因为它会加快调查包含 eval 的恶意代码。

is there a possibility to override eval function in PHP to display some trace information, i.e. from which file it was called, on which line did it occur?

有点。

您可以在 php.ini 中添加 evaldisable_functions。然后,当您调用 eval 时,您将得到致命错误 function eval not found 或类似的错误。

然后使用自定义错误处理程序。

   set_error_handler(function($errno, $errstr, $errfile, $errline){
       if(false !== strpos($errstr,'eval')){
           throw new Exception();
       }else{
           return false; //see below
       }
       //debug_print_backtrace() - I prefer exceptions as they are easier to work with, but you can use this arcane thing too.
   });

或类似的东西(未经测试)。

很遗憾,您不能将 eval 重新定义为您自己的函数。 Eval 并不是一个真正的函数,它是一种语言结构,如 issetemptyinclude 等...例如 function_exists('empty') 始终为 false。有些只是 "function" 更像其他的。

在任何情况下,您可能都必须禁用 eval,我实在想不出解决办法。

提示

别忘了你可以这样做:

  try{
       throw new \Exception;
  }catch(\Exception $e){
      echo $e->getTraceAsString();
  }

它既抑制了异常(因此执行继续),又为您提供了一个很好的堆栈跟踪。

提示

http://php.net/manual/en/function.set-error-handler.php

It is important to remember that the standard PHP error handler is completely bypassed for the error types specified by error_types unless the callback function returns FALSE

因此,鉴于上述情况,您 can/should return 对于所有其他错误都是错误的。然后PHP会举报他们。我不确定在这种情况下它真的很重要,因为这并不是真的要用在生产代码中,但我觉得值得一提。

希望对您有所帮助。