您现在的位置: 万盛学电脑网 >> 程序编程 >> 网络编程 >> php编程 >> 正文

PHP程序漏洞产生的原因分析与防范方法说明

作者:佚名    责任编辑:admin    更新时间:2022-06-22

 本篇文章主要是对PHP程序漏洞产生的原因分析与防范方法进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助

滥用include    1.漏洞原因:    Include是编写PHP网站中最常用的函数,并且支持相对路径。有很多PHP脚本直接把某输入变量作为Include的参数,造成任意引用脚本、绝对路径泄露等漏洞。看以下代码:    ...  $includepage=$_GET["includepage"];  include($includepage);  ...   很明显,我们只需要提交不同的Includepage变量就可以获得想要的页面。如果提交一个不存在的页面,就可以使PHP脚本发生错误而泄露实际绝对路径(这个问题的解决办法在下面的文章有说明)。    2.漏洞解决:    这个漏洞的解决很简单,就是先判断页面是否存在再进行Include。或者更严格地,使用数组对可Include的文件作出规定。看以下代码:     代码如下: $pagelist=array("test1.php","test2.php","test3.php"); //这里规定可进行include的文件  if(isset($_GET["includepage"])) //判断是否有$includepage  {  $includepage=$_GET["includepage"];  foreach($pagelist as $prepage)  {  if($includepage==$prepage) //检查文件是否在允许列表中  {  include($prepage);  $checkfind=true;  break;  }  }  if($checkfind==true){ unset($checkfind); }  else{ die("无效引用页!"); }  }   这样就可以很好地解决问题了。    小提示:有此问题的函数还有:require(),require_once(),include_once(),readfile()等,在编写的时候也要注意。    未对输入变量进行过滤    1.漏洞原因:    这 个漏洞早在ASP中出现过,当时造成的注入漏洞不计其数。但由于PHP在当时的影响力较小,所以没有太多的人能够注意这点。对于PHP来说,这个漏洞 的影响性比ASP更大,因为有比较多的PHP脚本使用到文本型数据库。当然也存在SQL语句的注入问题。举个比较经典的例子,首先是数据库的:     代码如下: $id=$_GET["id"];    $query="SELECT * FROM my_table where id='".$id."'"; //很经典的SQL注入漏洞  $result=mysql_query($query);     这里很明显我们可以用注入来获得数据库的其它内容了。这里就不再详细叙述,和ASP注入一样的,大家可以看看以前的黑防。然后我们看文本数据库的问题:  复制代码 代码如下: $text1=$_POST["text1"];  $text2=$_POST["text2"];  $text3=$_POST["text3"];    $fd=fopen("test.php","a");  fwrite($fd,"rn$text1&line;$text2&line;$text3");  fclose($fd);     文本的漏洞可以说是更加严重。倘若我们的提交的变量中插入一段很小的PHP代码,就可以另这个文本数据库test.php变成PHP后门。甚至插入上传代码,让我们可以上传一个完善的PHP后门。接着提升权限,服务器就是你的了。    2.漏洞解决:    这个漏洞的解决方法其实很简单,就是严格对全部提交的变量进行过滤。对一些敏感的字符进行替换。我们可以借助PHP提供的htmlspecialchars()函数来替换HTML的内容。这里给出一段例子:     代码如下: //构造过滤函数  function flt_tags($text)  {  $badwords=array("操","fuck"); //词汇过滤列表  $text=rtrim($text);  foreach($badwords as $badword) //这里进行词汇的过滤  {  if(stristr($text,$badword)==true){ die("错误:你提交的内容含有敏感字眼,请不要提交敏感内容。"); }  }  $text=htmlspecialchars($text); //HTML替换  //这两行把回车替换为    $text=str_replace("r"," ",$text);  $text=str_replace("n","",$text);  $text=str_replace("&line;","│",$text); //文本数据库分隔符"&line;"替换为全角的"│"  $text=preg_replace("/s{ 2 }/"," ",$text); //空格替换 中国网管联盟 $text=preg_replace("/t/"," ",$text); //还是空格替换  if(get_magic_quotes_gpc()){ $text=stripslashes($text); } //如果magic_quotes开启,则进行'的替换  return $text;  }    $text1=$_POST["text1"];  $text2=$_POST["text2"];  $text3=$_POST["text3"];    //过滤全部输入  $text1=flt_tags($text1);  $text2=flt_tags($text2);  $text3=flt_tags($text3);    $fd=fopen("test.php","a");  fwrite($fd,"rn$text1&line;$text2&line;$text3");  fclose($fd);     经过一番替换和过滤后,你就可以安全地把数据写入文本或数据库了。    管理员判断不完全   1.漏洞原因:    我们用PHP写脚本,通常要涉及管理员的权限问题。而一些脚本仅仅对管理员权限作出"是"判断,而往往忽略了"否"判断。在PHP配置文件中 register_globals打开的情况下(4.2.0以后版本默认关闭,但有不少人为了方便而打开它,这是极度危险的行为),就会出现提交变量冒充 管理员的情况。我们看一下的例子代码:  代码如下: $cookiesign="admincookiesign"; //判断是否Admin的cookie变量  $adminsign=$_COOKIE["sign"]; //获取用户的cookie变量    if($adminsign==$cookiesign)  {  $admin=true;  }    if($admin){ echo "现在是管理员状态。"; }     看上去好像很安全的样子,呵呵。现在我们假设PHP配置文件中register_globals为打开状态。我们提交这样一个地址“test.php? admin=true”,结果看到了吗?我们虽然没有正确的Cookie,但由于register_globals为打开状态,使得我们提交的admin 变量自动注册为true。而且脚本缺少“否”判断,就使得我们顺利地通过admin=true取得管理员的权限了。这个问题存在于大部分网站和论坛当中。    2.漏洞解决:    解决这个问题,我们只需要在脚本中加入对管理员的“否”判断即可。我们仍然假设PHP配置文件中register_globals为打开状态。看一下的代码:   代码如下: $cookiesign="admincookiesign"; //判断是否Admin的cookie变量  $adminsign=$_COOKIE["sign"]; //获取用户的cookie变量    if($adminsign==$cookiesign)  {  $admin=true;  }  else  {  $admin=false;  }  if($admin){ echo "现在是管理员状态。"; }     这 样,就算攻击者在没有正确Cookie的情况下提交了admin=true的变量,脚本在以后的判断中也会把$admin设置为False。这样就解 决了部分的问题。但由于$admin是变量,倘若在以后的其他脚本引用中出现了漏洞使得$admin被重新赋值就会引发新的危机。因此,我们应该使用常量 来存放管理员权限的判定。使用Define()语句定义一个admin常量来记录管理员权限,在此以后若配重新赋值就会出错,达到保护的目的。看以下代 码:  复制代码 代码如下: $cookiesign="admincookiesign"; //判断是否Admin的cookie变量  $adminsign=$_COOKIE["sign"]; //获取用户的cookie变量    if($adminsign==$cookiesign)  {  define(admin,true);  }  else  {  define(admin,false);  }  if(admin){ echo "现在是管理员状态。"; }     值得注意的是,我们使用了Define语句,所以在调用Admin常量时前面不要习惯性的加变量符号$,而应该使用Admin和!admin。    文本数据库暴露    1.漏洞原因:    前面已经说过,由于文本数据库具有很大的灵活性,不需要任何外部支持。加上PHP对文件的处理能力十分强,因此文本数据库在PHP脚本中的应用甚广。甚至有几个很好的论坛程序就是使用文本数据库的。但有得必有失,文本数据库的安全性也是比其他数据库要低的。    2.漏洞解决:    文 本数据库作为一个普通的文件,它可以被下载,就像MDB一样。所以我们要用保护MDB的办法来保护文本数据库。把文本数据库的后缀名改为.PHP。并 在数据库的第一行加入。这样文本数据库就会作为一个PHP文件,并且在第一行退出执行。也就是返回一个空页面,从而达到保护文本数据库的目的。    错误路径泄露    1.漏洞原因:    PHP遇到错误时,就会给出出错脚本的位置、行数和原因,例如:    Notice: Use of undefined constant test - assumed 'test' in D:interpubbigflytest.php on line 3   有很多人说,这并没有什么大不了。但泄露了实际路径的后果是不堪设想的,对于某些入侵者,这个信息可是非常重要,而事实上现在有很多的服务器都存在这个问题。&nb