【问题标题】:How to detect if a string contains PHP code? PHP如何检测字符串是否包含 PHP 代码? PHP
【发布时间】:2019-04-16 07:44:21
【问题描述】:

我会记录对我的网站提出的每个请求。我非常清楚在执行任何包含来自查询字符串的数据的 MySQL 查询之前需要采取的安全措施。我尽可能多地从注射中清除它,到目前为止,所有测试都已成功使用:

htmlspecialchars, strip_tags, mysqli_real_escape_string

但是在访问页面的日志中,我发现了包含大量 php 代码的失败黑客尝试的查询字符串:

?1=%40ini_set%28"display_errors"%2C"0"%29%3B%40set_time_limit%280%29%3B%40set_magic_quotes_runtime%280%29%3Becho%20%27->%7C%27%3Bfile_put_contents%28%24_SERVER%5B%27DOCUMENT_ROOT%27%5D.%27/webconfig.txt.php%27%2Cbase64_decode%28%27PD9waHAgZXZhb

在前面的例子中我们可以看到:

display_errors, set_time_limit, set_magic_quotes_runtime, file_put_contents

另一个例子:

/?s=/index/%5Cthink%5Capp/invokefunction&function=call_user_func_array&vars[0]=file_put_contents&vars[1][]=ctlpy.php&vars[1][]=<?php @assert($_REQUEST["ysy"]);?>ysydjsjxbei37$

这个最糟糕,里面甚至还有一些&lt;?php$_REQUEST["ysy"] 的东西。虽然我能够对其进行清理、剥离标签并在解码字符串时对 &lt;&gt; 进行编码,但我可以看到正在发送的请求的类型。

有没有什么办法可以检测到一个包含php代码的字符串,比如:

filter_var($var, FILTER_SANITIZE_PHP); 

仅供参考:这不是一个真正的功能,我试图说明我在寻找什么。

或某种功能:

function findCode($var){
   return ($var contains PHP) ? true : false
}

再说一遍,不是真的

无需清理,已处理,只需检测字符串中的 PHP 代码。我需要这个,因为我想检测它们并将它们保存在其他日志中。

注意:切勿执行或评估来自查询字符串的代码

【问题讨论】:

  • 首先,不要eval
  • 请不要建议他为每个查询使用一个api。在这里,安全性甚至比性能更重要。查询可能包含您确实不想发送给 Internet 上的第三方的敏感数据。
  • 访问者可以通过请求提交任何查询。它可能包含 PHP,也可能包含 Javascript(想想:XSS)和可能​​的其他有害内容(语言、图片等)。这是活生生的事实。您可以只接受您实际需要的那些参数,然后只接受那些参数允许的值。存储每个请求并不能使您的网站更安全。确保你不做任何愚蠢的事情,做不应该被允许的事情。
  • 在日志文件中包含这些内容有什么害处?就其本身而言,它只是文本。除非您明确尝试将其作为 PHP 代码执行,否则它不会执行任何操作。几乎所有攻击都归结为:不要尝试将用户输入作为 PHP/SQL/HTML 等执行。,你会没事的。
  • 好的,我明白了。答案是:不,不可靠(这是简短的答案......)。您还说:“我非常清楚在执行任何包含来自查询字符串的数据的 MySQL 查询之前需要采取的安全措施。”。然而,使用htmlspecialchars()strip_tags()mysqli_real_escape_string() 进行消毒并不是正确的方法。最好使用prepared statements。这是an explanation

标签: php security code-injection sanitization mysql-real-escape-string


【解决方案1】:

@KIKO Software 在阅读了很多 cmets 之后想出了一个巧妙的想法,即使用 PHP 分词器,但结果非常困难,因为要分析的字符串需要具有几乎完美的语法,否则会失败。

所以我想出的最好的解决方案是一个简单的函数,它试图找到常用的 PHP 语句,在我的例子中,特别是在带有代码注入的查询字符串上。此解决方案的另一个优点是我们可以根据需要修改和添加任意数量的 PHP 语句。 请记住,使列表变大会大大减慢您的脚本速度。此函数使用 strpos 而不是 preg_match (regex),因为它被证明执行得更快。

这不会在字符串中找到 100% 的 PHP 代码,但您可以自定义它以尽可能多地查找,永远不要包含可以在常规英语中使用的术语,例如“echo”或“if”

function findInStr($string, $findarray){
    $found=false;   
    for($i=0;$i<sizeof($findarray);$i++){
        $res=strpos($string,$findarray[$i]);
        if($res !== false){
            $found=true;
            break;
        }
    }
    return $found;
}

简单使用:

$search_line=array(
            'file_put_contents',
            '<?=',
            '<?php',
            '?>',
            'eval(',
            '$_REQUEST',
            '$_POST',
            '$_GET',
            '$_SESSION',
            '$_SERVER',
            'exec(',
            'shell_exec(',
            'invokefunction',
            'call_user_func_array',
            'display_errors',
            'ini_set',
            'set_time_limit',
            'set_magic_quotes_runtime',
            'DOCUMENT_ROOT',
            'include(',
            'include_once(',
            'require(',
            'require_once(',
            'base64_decode',
            'file_get_contents',
            'sizeof',
            'array('
        );

if(findInStr("this has some <?php echo 'PHP CODE' ?>",$search_line)){
  echo "PHP found";
}

【讨论】:

  • 您可以使用正则表达式来扩展它:/[a-z_]{1,}\(|\$_[a-z]{3,7}/i。安全性稍差一些,但它可以捕获函数调用和超级全局变量。对于一个简单的检查,这应该足够了。
猜你喜欢
  • 2016-12-25
  • 2014-09-11
  • 2012-06-23
  • 2012-02-21
  • 2021-09-15
  • 2011-05-24
  • 2014-07-25
  • 2015-04-11
  • 1970-01-01
相关资源
最近更新 更多