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的内容。这里给出一段例子:
//构造过滤函数 www.111cn.net
function flt_tags($text)
{
$badwords=array("操你妈","fuck"); //词汇过滤列表
$text=rtrim($text);
foreach($badwords as $badword) //这里进行词汇的过滤
{
if(stristr($text,$badword)==true){ die("错误:你提交的内容含有敏感字眼,请不要提交敏感内容
2007-07-24的文章 转自http://www.111cn.net/13013/viewspace_12473.html
以下仅供参考,在中国社会环境错综复杂,不同级别的人拿得是相同工资很普遍.高薪关键是面试时的口才+经验+实力+运气+人际交往能力
很高兴各位很看到这篇文章,我希望能以这个架阶为平台,为我的PHPER朋友们更好了解自身成长的过程,包括技术阶段、人生规划和就业策略,从而帮助各位或是公司人事部找到合适自己的路子;本篇文章会继续完善,包括各级别的面试题案例解析,当然笔者由于年纪与经验各方面不足,故之能说是参考,因为现实因素很复杂.^_^
1.一段phper水平与待遇 ->初级工程师
Jiania->答:内容:不问专业,首先是位合格网民与玩家,看懂HTML,XHTML,DHTML,能写基础CSS,Javascrīpt,能自己搭配Windows平台(WAMP),懂得基础的SQL/mysql语句与phpmyadmin操作,懂得数据备份与恢复,能写简单的留言本,新闻系统.能看懂简单的PHP程序代码,并能做简单修改.对版本控制客户端软件有所了解;无工作经验.
此类人才策略:
这类人基本上大学刚毕业,不管是计算机专业,还是业余选手,在学校基本上没有学到多少知识,但是位合格的网民应是最基本了,这些人听老师讲过,自己看过一些入门书籍,懂得装操作系统(WAMP),基本优化,制做简单网页,或是复制他人代码,或是会使用其它CMS系统做点简单的企业网站,会使用FTP软件,对 B/S架构大致有点了解,有点基础的sql语句,如select,insert into,update,left join ,inner join等联合语句与数据的备份与恢复,但此类程序员一般对数据库的设计结构并无太多心得,例如数据类型的使用->时间上是用time类型,还是用int(10)类型在转化等等,此类程序员懂PHP基本语法知识,能看别人简单点代码复制到自己程序中使用.在javascrīpts懂得使用一些基本的JS语句.
在CSS+XHTML方面只有基本了解,并不懂得优化与其它高级使用,基本上编写出来的东西无法满足W3C标准.你也不可能要求他写出的PHP程序安全性过关,基本上对sql injection没有太多概念.^_^,带SQL程序可攻击性99.99%
为什么任何程序员必经的过程要懂html,js等基础呢?因为这是必经过程,在以后你可以不用管这些,交给专业网页充计师来处理,但学习之前你必需有基本的了解!
适合公司对象:中小型公司,不以网络开发为主,技术部只需1-2人就行的公司.
Jiania->答:待遇:800-1.5K 地区+运气 2K-.3k左右
以北京四环以内来讲,房租(1000)省点合租床位(300-500)+伙食(800)+交通(200)+手机(100),起点得2K-3K,不然没法混了.
2.二段phper水平与待遇 ->中/高级工程师 (中国式名片)
Jiania->答:内容:继承上面,较熟悉DIV+CSS结构设计,了解XML, 了解CGI标准,了解W3C标准;理解MV结构,懂得使用AJAX,了解TCP/IP协议,书写Javascrīpt,熟悉搭配Windows平台 (WAMP),LAMP平台环境搭配, 懂得CVS/SVN版本控制安装与使用,能看懂UML设计图,较好的书写习惯;懂得使用PEAR与一些开源类(Adodb, Jpgraph..);懂得Smarty等模板应用;熟悉MYSQL/SQL数据操作与结构优化,能独立设计数据结构,对PHP常用的命令,如数组操作, function编写,简单OO应用,能独立开发企业网站,能写普通的功能应用与原有系统上的扩展模块;英语基本阅读能力,一年左右开发经验;
Jiania->答:待遇:2.5K-3.5K 地区+运气 4k-5K左右 左右或是更高,看国企业,还是外企业,公司大小等因素.
以北京四环以内来讲,房租(1000起点)省点合租床位(300-500)++伙食(800)+交通(200)+手机(100)+谈恋爱(1000)+请客聚会(500起),
工资起点得4K-5K不然没法混了.
3.三段phper水平与待遇 样->资深工程师
Jiania ->答:内容:继承上面,有C语言或其它语言基础,能读懂PHP C 源代码, 懂得CGI标准,熟悉W3C标准;懂得MVC架构,了解与懂得使用SPL,能读懂主流CMS的源代码,能对其进行二次开发,良好OO架构与编写能力,参与或是有能力写出PEAR子功能包,读懂Zend Framework等开源框架并懂得使用,
一.先开启php curl函数库的步骤
1).去掉windows/php.ini 文件里;extension=php_curl.dll前面的; /*用 echo phpinfo();查看php.ini的路径*/
2).把php5/libeay32.dll,ssleay32.dll复制到系统目录windows/下
3).重启apache
二.例子
例子:
<?php
$cookie_jar = tempnam(''./tmp'',''cookie'');
$ch = curl_init(); curl_setopt($ch,CURLOPT_URL,''http://******'');
curl_setopt($ch, CURLOPT_POST, 1);
$request = ''email_address=&password=&action='';
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
//把返回来的cookie信息保存在$cookie_jar文件中
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_jar);
//设定返回的数据是否自动显示
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//设定是否显示头信息
curl_setopt($ch, CURLOPT_HEADER, false);
//设定是否输出页面内容
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_exec($ch);
curl_close($ch); //get data after login
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, ''http://*****'');
curl_setopt($ch2, CURLOPT_HEADER, false);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch2, CURLOPT_COOKIEFILE, $cookie_jar);
$orders = curl_exec($ch2);
echo '''';
echo strip_tags($orders);
echo '''';
curl_close($ch2);
?>
方法2用fsockopen:
<?php
function GetWebContent($host, $method, $str, $sessid = '''')
{
$ip = gethostbyname($host);
//echo "ip=$ip<br>";
[email=$fp=@fsockopen($ip,80]$fp=@fsockopen($ip,80[/email]);
if (!$fp) return;
fputs($fp, "$method ");
fputs($fp, "Host: $host ");
if (!empty($sessid))
{
fputs($fp, "Cookie: PHPSESSID=$sessid; path=/; ");
}
if ( substr(trim($method),0, 4) == "POST")
{
fputs($fp, "Content-Length: ". strlen($str) . " "); // 别忘了指定长度
}
//fputs($fp, "Content-Type: application/x-www-form-urlencoded ");
fputs($fp, "Content-Type: application/x-www-form-urlencoded ");
fputs($fp, "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1) )");//add by Ew 071012
fputs($fp, "Connection: Keep-Alive ");
if ( substr(trim($method),0, 4) == "POST")
{
fputs($fp, $str." ");
}
while(!feof($fp))
{
$response .= fgets($fp);
}
$hlen = strpos($response," "); // LINUX下是 " "
$header = substr($response, 0, $hlen);
//echo "header=$header<hr><hr>";
$entity = substr($response, $hlen + 4);
if ( preg_match(''/PHPSESSID=([0-9a-z]+);/i'', $header, $matches))
{
$a[''sessid''] = $matches[1];
}
if ( preg_match(''/Location: ([0-9a-z_?=&#.]+)/i'', $header, $matches))
{
$a[''location''] = $matches[1];
}
$a[''content''] = $entity;
fclose($fp);
return $a;
}
$response = GetWebContent("$host","POST /$login_page HTTP/1.0", $str);//登入得到新的session_id
//...可以在这里先保存session_id
$response = GetWebContent("$host","GET /$somepage HTTP/1.0", '''', $response[''sessid'']);//使用session_id访问页面
echo $response[''location''].$response[''content'']."<br>";
?>
|
● 写文件 和读取文件的方式一样,先看看是不是能写: <?php $file = ''dirlist.php''; 能写了的话可以使用file_put_contents函数写入: <?php file_put_contents函数在php5中新引进的函数(不知道存在的话用function_exists函数先判断一下)低版本的php无法使用,可以使用如下方式: $f = fopen($file, ''w''); 替换之. 写文件的时候有时候需要锁定,然后写: function cache_page($pageurl,$pagedata){ |