专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »网站安全 » 科讯cms漏洞防范:PHP程序漏洞产生的原因和防范思路方法 »正文

科讯cms漏洞防范:PHP程序漏洞产生的原因和防范思路方法

来源: 发布时间:星期四, 2009年9月24日 浏览:72次 评论:0
  滥用

  1.漏洞原因:

  Include是编写PHP网站WebSite中最常用并且支持相对路径有很多PHP脚本直接把某输入变量作为Include参数造成任意引用脚本、绝对路径泄露等漏洞看以下代码:

  ...

  $page=$_GET["page"];

  ($page);

  ...

  很明显我们只需要提交区别Includepage变量就可以获得想要页面如果提交个不存在页面就可以使PHP脚本发生而泄露实际绝对路径(这个问题解决办法在下面文章有介绍说明)

  2.漏洞解决:

  这个漏洞解决很简单就是先判断页面是否存在再进行Include或者更严格地使用对可Include文件作出规定看以下代码:

  $pagelist=.gif' />("test1.php","test2.php","test3.php"); //这里规定可进行文件

  (is($_GET["page"])) //判断是否有$page

  {

  $page=$_GET["page"];

  foreach($pagelist as $prepage)

  {

  ($page$prepage) //检查文件是否在允许列表中

  {

  ($prepage);

  $checkfind=true;

  ;

  }

  }

  ($checkfindtrue){ un($checkfind); }

  { die("无效引用页!"); }

  }

  这样就可以很好地解决问题了

  小提示:有此问题还有:requirerequire_once_oncereadfile在编写时候也要注意

  未对输入变量进行过滤

  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,"\r\n$text1&line;$text2&line;$text3");

  fclose($fd);

  文本漏洞可以说是更加严重倘若我们提交变量中插入段很小PHP代码就可以另这个文本数据库test.php变成PHP后门甚至插入上传代码让我们可以上传个完善PHP后门接着提升权限服务器就是你

  2.漏洞解决:

  这个漏洞解决思路方法其实很简单就是严格对全部提交变量进行过滤些敏感进行替换我们可以借助PHP提供htmlspecialchars来替换HTML内容这里给出段例子:

  //构造过滤

  function flt_tags($text)

  {

  $badwords=.gif' />("操你妈","fuck"); //词汇过滤列表

  $text=rtrim($text);

  foreach($badwords as $badword) //这里进行词汇过滤

  {

  (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); //还是空格替换

  (get_magic_quotes_gpc){ $text=stripslashes($text); } //如果magic_quotes开启则进行\'替换

   $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,"\r\n$text1&line;$text2&line;$text3");

  fclose($fd);

  经过番替换和过滤后你就可以安全地把数据写入文本或数据库了

  管理员判断不完全

  1.漏洞原因:

  我们用PHP写脚本通常要涉及管理员权限问题些脚本仅仅对管理员权限作出"是"判断而往往忽略了"否"判断在PHP配置文件中register_globals打开情况下(4.2.0以后版本默认关闭但有不少人为了方便而打开它这是极度危险行为)就会出现提交变量冒充管理员情况我们看例子代码:

  $cookiesign="admincookiesign"; //判断是否Admincookie变量

  $adminsign=$_COOKIE["sign"]; //获取用户cookie变量

  ($adminsign$cookiesign)

  {

  $admin=true;

  }

  ($admin){ echo "现在是管理员状态"; }

  看上去好像很安全样子呵呵现在我们假设PHP配置文件中register_globals为打开状态我们提交这样个地址“test.php?admin=true”结果看到了吗?我们虽然没有正确Cookie但由于register_globals为打开状态使得我们提交admin变量自动注册为true而且脚本缺少“否”判断就使得我们顺利地通过admin=true取得管理员权限了这个问题存在于大部分网站WebSite和论坛当中

  2.漏洞解决:

  解决这个问题我们只需要在脚本中加入对管理员“否”判断即可我们仍然假设PHP配置文件中register_globals为打开状态代码:

  $cookiesign="admincookiesign"; //判断是否Admincookie变量

  $adminsign=$_COOKIE["sign"]; //获取用户cookie变量

  ($adminsign$cookiesign)

  {

  $admin=true;

  }

  

  {

  $admin=false;

  }

  ($admin){ echo "现在是管理员状态"; }

  这样就算攻击者在没有正确Cookie情况下提交了admin=true变量脚本在以后判断中也会把$admin设置为False这样就解决了部分问题但由于$admin是变量倘若在以后其他脚本引用中出现了漏洞使得$admin被重新赋值就会引发新危机因此我们应该使用常量来存放管理员权限判定使用Define语句定义个admin常量来记录管理员权限在此以后若配重新赋值就会出错达到保护看以下代码:

  $cookiesign="admincookiesign"; //判断是否Admincookie变量

  $adminsign=$_COOKIE["sign"]; //获取用户cookie变量

  ($adminsign$cookiesign)

  {

  (admin,true);

  }

  

  {

  (admin,false);

  }

  (admin){ echo "现在是管理员状态"; }

  值得注意我们使用了Define语句所以在Admin常量时前面不要习惯性加变量符号$而应该使用Admin和!admin

  文本数据库暴露

  1.漏洞原因:

  前面已经说过由于文本数据库具有很大灵活性不需要任何外部支持加上PHP对文件处理能力十分强因此文本数据库在PHP脚本中应用甚广甚至有几个很好论坛就是使用文本数据库但有得必有失文本数据库安全性也是比其他数据库要低

  2.漏洞解决:

  文本数据库作为个普通文件它可以被下载就像MDB所以我们要用保护MDB办法来保护文本数据库把文本数据库后缀名改为.PHP并在数据库行加入这样文本数据库就会作为个PHP文件并且在第行退出执行也就是返回个空页面从而达到保护文本数据库

  路径泄露

  1.漏洞原因:

  PHP遇到就会给出出错脚本位置、行数和原因例如:

  Notice: Use of und constant test - assumed 'test' in D:\erpub\bigfly\test.php _disibledevent=>   $errstr=str_replace(getcwd,"",$errstr);

  }

  switch($errno)

  {

   E_ERROR:

  echo "ERROR: [ID $errno] $errstr (Line: $errline of $errfile)

  \n";

  echo "已经停止运行请联系管理员";

  //遇到Error级时退出脚本

  exit;

  ;

   E_WARNING:

  echo "WARNING: [ID $errno] $errstr (Line: $errline of $errfile)

  \n";

  ;

  default:

  //不显示Notice级

  ;

  }

  }

  //把处理设置为my_error_handler

  _error_handler("my_error_handler");

  …

  这样就可以很好地解决安全和调试方便矛盾了而且你还可以花点心思使提示更加美观以配合网站WebSite风格不过注意两点是:

  (1)E_ERROR、E_PARSE、E_CORE_ERROR、E_CORE_WARNING、E_COMPILE_ERROR、E_COMPILE_WARNING是不会被这个句柄处理也就是会用最原始方式显示出来不过出现这些都是编译或PHP内核出错在通常情况下不会发生

  (2)使用_error_handlererror_reporting 将会失效也就是所有(除上述)都会交给自定义处理

  其它有有关_error_handler信息大家可以参考PHP官方手册

  POST漏洞

  1.漏洞原因:

  前面已经说过依靠register_globals来注册变量是个不好习惯些留言本和论坛更要严格检查获得页面方式和提交时间间隔以防止灌水式发帖和外部提交我们看下以下某留言本代码:

  ...

  $text1=flt_tags($text1);

  $text2=flt_tags($text2);

  $text3=flt_tags($text3);

  $fd=fopen("data.php","a");

  fwrite($fd,"\r\n$text1&line;$text2&line;$text3");

  fclose($fd);

  ...

  很明显如果我们提交网址”post.php?text1=testhaha&text2=testhaha&text3=testhaha”数据就会被正常写入文件中并没有检测变量来源和浏览器获得页面方式如果我们向这个页面重复多次提交就会起到洪水作用现在也有些软件Software利用这个漏洞来在论坛或留言本上发广告这是可耻行为(我朋友留言本就在1星期内被灌了10多页无奈)

  2.漏洞解决:

  在进行数据处理和保存前首先判断浏览器获得页面方式使用$_SERVER["REQUEST_METHOD"]变量来获得浏览器获得页面方式检查其是否为”POST”在脚本中使用session来记录用户是否通过正常途径(即填写提交内容页面)来提交数据或使用$_SERVER["HTTP_REFERER"]来检测但不推荐这样做部分浏览器没有设置REFERER有部分防火墙也会屏蔽REFERER另外我们也要对提交内容检查看数据库中是否有重复内容以留言本为例使用Session进行判定:

  填写浏览内容页面中我们在最前端加上:

  $_SESSION["allowgbookpost"]=time; //登记填写时时间

  在接受留言数据并保存页面中我们在进行数据处理前我们也用Session进行以下处理:

  (strtoupper($_SERVER["REQUEST_METHOD"])!=”POST”){ die(":请勿在外部提交"); } //检查页面获得思路方法是否为POST

  (!is($_SESSION["allowgbookpost"]) or (time-$_SESSION["allowgbookpost"] < 10)){ die(":请勿在外部提交"); } //检查留言填写时时间

  (is($_SESSION["gbookposttime"]) and (time-$_SESSION["gbookposttime"] < 120)){ die(":两次提交留言间隔不得少于 2 分钟"); } //检查留言间隔

  un($_SESSION["allowgbookpost"]); //注销allowgbookpost变量以防止次进入填写页面多次进行提交

  $_SESSION["gbookposttime"]=time; //登记发送留言时间防止灌水或恶意攻击

  ...

  数据处理及保存

  ...

  经过这样重重审查就安全很多了

 

0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: