php.ini magic_quotes_gpc配置防注入方法(1/5)

 更新时间:2016年11月25日 15:25  点击:1396

1. php 配置文件 php.ini 中的 magic_quotes_gpc 选项没有打开,被置为 off
  2. 开发者没有对数据类型进行检查和转义
  不过事实上,第二点最为重要。我认为, 对用户输入的数据类型进行检查,向 mysql教程 提交正确的数据类型,这应该是一个 web 程序员最最基本的素质。但现实中,常常有许多小白式的 web 开发者忘了这点, 从而导致后门大开。
  为什么说第二点最为重要?因为如果没有第二点的保证,magic_quotes_gpc 选项,不论为 on,还是为 off,都有可能引发 sql 注入攻击。下面来看一下技术实现:
 一. magic_quotes_gpc = off 时的注入攻击
  magic_quotes_gpc = off 是 php 中一种非常不安全的选项。新版本的 php 已经将默认的值改为了 on。但仍有相当多的服务器的选项为 off。毕竟,再古董的服务器也是有人用的。
  当magic_quotes_gpc = on 时,它会将提交的变量中所有的 '(单引号)、"(双号号)、(反斜线)、空白字符,都为在前面自动加上 。下面是 php 的官方说明:

复制代码 代码如下:
magic_quotes_gpc boolean

sets the magic_quotes state for gpc (get/post/cookie) operations. when magic_quotes are on, all ' (single-quote), " (double quote), (backslash) and nul's are escaped with a backslash automatically

如果没有转义,即 off 情况下,就会让攻击者有机可乘。以下列测试脚本为例:
复制代码 代码如下:

<?
if ( isset($_post["f_login"] ) )
{
// 连接数据库教程...
// ...代码略...

// 检查用户是否存在
$t_struname = $_post["f_uname"];
$t_strpwd = $_post["f_pwd"];
$t_strsql = "select * from tbl_users where username='$t_struname' and password = '$t_strpwd' limit 0,1";

if ( $t_hres = mysql_query($t_strsql) )
{
// 成功查询之后的处理. 略...
}
}
?>

<html><head><title>sample test</title></head>
<body>
<form method=post action="">
username: <input type="text" name="f_uname" size=30><br>
password: <input type=text name="f_pwd" size=30><br>

<input type="submit" name="f_login" value="登录">
</form>
</body> 

 


<?php教程
require_once(dirname(__file__)."/../include/common.inc.php");
if(emptyempty($dopost))
{
$dopost = "";
}
if($dopost=="rename")
{
if(rename('dedesql.query.php','arc.sqlquery.class.php')){
echo "成功!";
}else{
echo "失败!";
}
exit();
}
if($dopost=="viewinfo")
{
if(emptyempty($tablename))
{
echo "没有指定表名!";
}
else
{
$dsql->setquery("show create table ".$dsql->dbname.".".$tablename);
$dsql->execute('me');
$row2 = $dsql->getarray('me',mysql教程_both);
$ctinfo = $row2[1];
echo "<xmp>".trim($ctinfo)."</xmp>";
}
exit();
}
if($dopost=="index")
{
require_once(dedeinc.'/arc.partview.class.php');
$envs = $_sys_globals = array();
$envs['aid'] = 0;
$pv = new partview();
$row = $pv->dsql->getone('select * from `#@__homepageset`');
$templet = str_replace("{style}",$cfg_df_style,$row['templet']);
$homefile = dirname(__file__).'/'.$row['position'];
$homefile = str_replace("//","/",str_replace("","/",$homefile));
$fp = fopen($homefile,'w') or die("无法更新网站主页到:$homefile 位置");
fclose($fp);
$tpl = $cfg_basedir.$cfg_templets_dir.'/'.$templet;
$pv->settemplet($tpl);
$pv->savetohtml($homefile);
$pv->close();
echo "成功更新首页!";
exit();
}
else if($dopost=="query")
{
$sqlquery = trim(strips教程lashes($sqlquery));
if(eregi("drop(.*)table",$sqlquery) ||eregi("drop(.*)database",$sqlquery))
{
echo "<span style='font-size:10pt'>删除'数据表'或'数据库教程'的语句不允许在这里执行。</span>";
exit();
}
if(eregi("^select ",$sqlquery))
{
$dsql->setquery($sqlquery);
$dsql->execute();
if($dsql->gettotalrow()<=0)
{
echo "运行sql:{$sqlquery},无返回记录!";
}
else
{
echo "运行sql:{$sqlquery},共有".$dsql->gettotalrow()."条记录,最大返回100条!";
}
$j = 0;
while($row = $dsql->getarray())
{
$j++;
if($j>100)
{
break;
}
echo "<hr size=1 width='100%'/>";
echo "记录:$j";
echo "<hr size=1 width='100%'/>";
foreach($row as $k=>$v)
{
echo "<font color='red'>{$k}:</font>{$v}<br/>rn";
}
}
exit();
}
if($querytype==2)
{
$sqlquery = str_replace("r","",$sqlquery);
$sqls = split(";[ t]{0,}n",$sqlquery);
$nerrcode = "";$i=0;
foreach($sqls as $q)
{
$q = trim($q);
if($q=="")
{
continue;
}
$dsql->executenonequery($q);
$errcode = trim($dsql->geterror());
if($errcode=="")
{
$i++;
}
else
{
$nerrcode .= "执行: <font color='blue'>$q</font> 出错,错误提示:<font color='red'>".$errcode."</font><br>";
}
}
echo "成功执行{$i}个sql语句!<br><br>";
echo $nerrcode;
}
else
{
$dsql->executenonequery($sqlquery);
$nerrcode = trim($dsql->geterror());
echo "成功执行1个sql语句!<br><br>";
echo $nerrcode;
}
exit();
}
if($dopost=="view")
{
;echo '<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=gb2312'>
<title>sql命令行工具</title>
<link href='img/base.css教程' rel='stylesheet' type='text/css'>
</head>
<body background='img/allbg.gif' leftmargin='8' topmargin='8'>
<table width="98%" border="0" align="center" cellpadding="3" cellspacing="1" bgcolor="#d1ddaa">
<tr>
<td height="19" background="img/tbg.gif">
<table width="96%" border="0" cellspacing="1" cellpadding="1">
<tr>
<td width="24%"><strong>sql命令运行器:</strong></td>
<td width="76%" align="right"> <b><a href="sys_data.php"><u>数据备份</u></a></b>
| <b><a href="sys_data_revert.php"><strong><u>数据还原</u></strong></a></b>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td height="200" bgcolor="#ffffff" valign="top">
<table width="100%" border="0" cellspacing="4" cellpadding="2">
<form action="" method="post" name="infoform" target="stafrm">
<input type='hidden' name='dopost' value='viewinfo' />
<tr bgcolor="#f3fbec">
<td width="15%" height="24" align="center">系统的表信息:</td>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="35%">
<select name="tablename" id="tablename" style="width:100%" size="6">
';
$dsql->setquery("show tables");
$dsql->execute('t');
while($row = $dsql->getarray('t',mysql_both))
{
$dsql->setquery("select count(*) from ".$row[0]);
$dsql->execute('n');
$row2 = $dsql->getarray('n',mysql_both);
$dd = $row2[0];
echo " <option value='".$row[0]."'>".$row[0]."(".$dd.")</option>rn";
}
;echo ' </select>
</td>
<td width="2%"> </td>
<td width="63%" valign="bottom">
<div style="float:left;margin-right:20px;">
<input type="submit" name="submit1" value="优化选中表" class="coolbg np" onclick="this.form.dopost.value='opimize';" />
<br />
<input type="submit" name="submit2" value="修复选中表" class="coolbg np" onclick="this.form.dopost.value='repair';" style="margin-top:6px;" />
<br />
<input type="submit" name="submit3" value="查看表结构" class="coolbg np" onclick="this.form.dopost.value='viewinfo';" style="margin-top:6px;" />
</div>
<div style="float:left">
<input type="submit" name="submit5" value="优化全部表" class="coolbg np" onclick="this.form.dopost.value='opimizeall';" />
<br />
<input type="submit" name="submit6" value="修复全部表" class="coolbg np" onclick="this.form.dopost.value='repairall';" style="margin-top:6px;" />
</div>
</td>
</tr>
</table></td>
</tr>
<tr>
<td height="200" align="center">返回信息:</td>
<td>
<iframe name="stafrm" frameborder="0" id="stafrm" width="100%" height="100%"></iframe>
</td>
</tr>
</form>
<form action="" method="post" name="form1" target="stafrm">
<input type='hidden' name='dopost' value='query'>
<tr>
<td height="24" colspan="2" bgcolor="#f3fbec"><strong>运行sql命令行:
<input name="querytype" type="radio" class="np" value="0">
单行命令(支持简单查询)
<input name="querytype" type="radio" class="np" value="2" checked>
多行命令</strong></td>
</tr>
<tr>
<td height="118" colspan="2">
<textarea name="sqlquery" cols="60" rows="10" id="sqlquery" style="width:90%"></textarea>
</td>
</tr>
<tr>
<td height="53" align="center"> </td>
<td>
<input name="imagefield" type="image" src="img/button_ok.gif" width="60" height="22" border="0" class='np' />
</td>
</tr>
</form>
</table>
</td>
</tr>
</table>
</body>
</html>
';}
?>

<?php教程
/*************************
说明:
判断传递的变量中是否含有非法字符
如$_post、$_get
功能:
防注入
**************************/
//要过滤的非法字符  这个过滤的字符 还可以增加
$arrfiltrate=array("'",";","union");
//出错后要跳转的url,不填则默认前一页
$strgourl="";
//是否存在数组中的值
function funstringexist($strfiltrate,$arrfiltrate){
foreach ($arrfiltrate as $key=>$value){
if (eregi($value,$strfiltrate)){
return true;
}
}
return false;
}

//合并$_post 和 $_get
if(function_exists(array_merge)){
$arrpostandget=array_merge($http_post_vars,$http_get_vars);
}else{
foreach($http_post_vars as $key=>$value){
$arrpostandget[]=$value;
}
foreach($http_get_vars as $key=>$value){
$arrpostandget[]=$value;
}
}

//验证开始
foreach($arrpostandget as $key=>$value){
if (funstringexist($value,$arrfiltrate)){
echo "<script language="网页特效">alert("非法字符");</script>";
if (empty($strgourl)){
echo "<script language="javascript">history.go(-1);</script>";
}else{
echo "<script language="javascript">window.location="".$strgourl."";</script>";
}
exit;
}
}
?>

当要在防止页面攻击时,可在页面的头部include防攻击文件,就像通用防注入文件。我们可以用三种情况来办到:
1、在每个文件内引用。这样的文件是可以,不过如果一个网站内有几百个文件的话就不方便了。
2、在共同包含文件内引用一下,比如 config.inc.php教程。这是一个好办法,也是目前市场上比较流行的做法。
3、在php.ini中引用。在配置文件内引用的话,将影响到所有的网站,包含所有页面,这就像当年流行的一些免费空间商,当你免费开通一个ftp空间,上传网站以后,空间内会出现广告一样。不知道是不是这种方法,但是目的是一样的。这样做的好处是:如果是一个公司或者是一个企业内部网站的话,即安全,维护也方便。


前两种方法大家都清楚,第三种就是在php.ini中,找到此节:

;automatically add files before or after any php document.
;auto_prepend_file = "phpids.php"
;auto_append_file = "alert.php"

默认是空,请添加所包含的文件。
同时找到:

 

;unix: "/path1:/path2"
;include_path = ".:/php/includes"
;
;windows: "path1;path2"
include_path = ".;f:phpnowhtdocs"


  因为我的是win环境,所以开启了windows选项,包含路径可自由修改。同时,这样的功能也为我们攻击也造成了方便,比如挂马。现在“市场”上也有很多的挂马技巧,就不多说了。我们可以利用auto_prepend_file选项,来批量挂马了,可以将整个服务器上的网站挂上,优点为:不影响速度、不修改文件、方法新颖。 缺点为:必须对php.ini有写权限。

(1) 打开php教程的安全模式
  php的安全模式是个非常重要的内嵌的安全机制,能够控制一些php中的函数,比如system(),
  同时把很多文件操作函数进行了权限控制,也不允许对某些关键文件的文件,比如/etc/passwd,
  但是默认的php.ini是没有打开安全模式的,我们把它打开:
  safe_mode = on


(2) 用户组安全
  当safe_mode打开时,safe_mode_gid被关闭,那么php脚本能够对文件进行访问,而且相同
  组的用户也能够对文件进行访问。
  建议设置为:
  safe_mode_gid = off
  如果不进行设置,可能我们无法对我们服务器网站目录下的文件进行操作了,比如我们需要
  对文件进行操作的时候。


(3) 安全模式下执行程序主目录
  如果安全模式打开了,但是却是要执行某些程序的时候,可以指定要执行程序的主目录:
  safe_mode_exec_dir = d:/usr/bin
  一般情况下是不需要执行什么程序的,所以推荐不要执行系统程序目录,可以指向一个目录,
  然后把需要执行的程序拷贝过去,比如:

  safe_mode_exec_dir = d:/tmp/cmd

  但是,我更推荐不要执行任何程序,那么就可以指向我们网页目录:

  safe_mode_exec_dir = d:/usr/www

 

 

[!--infotagslink--]

相关文章

  • php 中file_get_contents超时问题的解决方法

    file_get_contents超时我知道最多的原因就是你机器访问远程机器过慢,导致php脚本超时了,但也有其它很多原因,下面我来总结file_get_contents超时问题的解决方法总结。...2016-11-25
  • php抓取网站图片并保存的实现方法

    php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
  • HTTP 408错误是什么 HTTP 408错误解决方法

    相信很多站长都遇到过这样一个问题,访问页面时出现408错误,下面一聚教程网将为大家介绍408错误出现的原因以及408错误的解决办法。 HTTP 408错误出现原因: HTT...2017-01-22
  • Android子控件超出父控件的范围显示出来方法

    下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
  • ps把文字背景变透明的操作方法

    ps软件是现在非常受大家喜欢的一款软件,有着非常不错的使用功能。这次文章就给大家介绍下ps把文字背景变透明的操作方法,喜欢的一起来看看。 1、使用Photoshop软件...2017-07-06
  • Mysql select语句设置默认值的方法

    1.在没有设置默认值的情况下: 复制代码 代码如下:SELECT userinfo.id, user_name, role, adm_regionid, region_name , create_timeFROM userinfoLEFT JOIN region ON userinfo.adm_regionid = region.id 结果:...2014-05-31
  • intellij idea快速查看当前类中的所有方法(推荐)

    这篇文章主要介绍了intellij idea快速查看当前类中的所有方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-09-02
  • js导出table数据到excel即导出为EXCEL文档的方法

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta ht...2013-10-13
  • mysql 批量更新与批量更新多条记录的不同值实现方法

    批量更新mysql更新语句很简单,更新一条数据的某个字段,一般这样写:复制代码 代码如下:UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';如果更新同一字段为同一个值,mysql也很简单,修改下where即...2013-10-04
  • ps怎么制作倒影 ps设计倒影的方法

    ps软件是一款非常不错的图片处理软件,有着非常不错的使用效果。这次文章要给大家介绍的是ps怎么制作倒影,一起来看看设计倒影的方法。 用ps怎么做倒影最终效果&#819...2017-07-06
  • js基础知识(公有方法、私有方法、特权方法)

    本文涉及的主题虽然很基础,在许多人看来属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题。这里会涉及到对象属性的封装、原型、构造函数、闭包以及立即执行表达式等知识。公有方法 公有方法就是能被外部访问...2015-11-08
  • 安卓手机wifi打不开修复教程,安卓手机wifi打不开解决方法

    手机wifi打不开?让小编来告诉你如何解决。还不知道的朋友快来看看。 手机wifi是现在生活中最常用的手机功能,但是遇到手机wifi打不开的情况该怎么办呢?如果手机wifi...2016-12-21
  • PHP 验证码不显示只有一个小红叉的解决方法

    最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
  • c#中分割字符串的几种方法

    单个字符分割 string s="abcdeabcdeabcde"; string[] sArray=s.Split('c'); foreach(string i in sArray) Console.WriteLine(i.ToString()); 输出下面的结果: ab de...2020-06-25
  • js控制页面控件隐藏显示的两种方法介绍

    javascript控制页面控件隐藏显示的两种方法,方法的不同之处在于控件隐藏后是否还在页面上占位 方法一: 复制代码 代码如下: document.all["panelsms"].style.visibility="hidden"; document.all["panelsms"].style.visi...2013-10-13
  • 连接MySql速度慢的解决方法(skip-name-resolve)

    最近在Linux服务器上安装MySql5后,本地使用客户端连MySql速度超慢,本地程序连接也超慢。 解决方法:在配置文件my.cnf的[mysqld]下加入skip-name-resolve。原因是默认安装的MySql开启了DNS的反向解析。如果禁用的话就不能...2015-10-21
  • C#方法的总结详解

    本篇文章是对C#方法进行了详细的总结与介绍,需要的朋友参考下...2020-06-25
  • Zend studio文件注释模板设置方法

    步骤:Window -> PHP -> Editor -> Templates,这里可以设置(增、删、改、导入等)管理你的模板。新建文件注释、函数注释、代码块等模板的实例新建模板,分别输入Name、Description、Patterna)文件注释Name: 3cfileDescriptio...2013-10-04
  • EXCEL数据上传到SQL SERVER中的简单实现方法

    EXCEL数据上传到SQL SERVER中的方法需要注意到三点!注意点一:要把EXCEL数据上传到SQL SERVER中必须提前把EXCEL传到服务器上.做法: 在ASP.NET环境中,添加一个FileUpload上传控件后台代码的E.X: 复制代码 代码如下: if...2013-09-23
  • mysql锁定单个表的方法

    mysql锁定单个表的方法 复制代码 代码如下:mysql>lock table userstat read; mysql>unlock tables; 页级的典型代表引擎为BDB。 表级的典型代表引擎为MyISAM,MEMORY以及很久以前的ISAM。 行级的典型代表引擎为INN...2014-05-31