. 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>
在这个脚本中,当用户输入正常的用户名和密码,假设值分别为 zhang3、abc123,则提交的 sql 语句如下:
代码如下:
select * from tbl_users
where username='zhang3' and password = 'abc123' limit 0,1
如果攻击者在 username 字段中输入:zhang3' or 1=1 #,在 password 输入 abc123,则提交的 sql 语句变成如下:
代码如下:
select * from tbl_users
where username='zhang3' or 1=1 #' and password = 'abc123' limit 0,1
由于 # 是 mysql中的注释符, #之后的语句不被执行,实现上这行语句就成了:
代码如下:
select * from tbl_users
where username='zhang3' or 1=1
这样攻击者就可以绕过认证了。如果攻击者知道数据库结构,那么它构建一个 union select,那就更危险了:
假设在 username 中输入:zhang3 ' or 1 =1 union select cola, colb,cold from tbl_b #
在password 输入: abc123,
则提交的 sql 语句变成:
代码如下:
select * from tbl_users
where username='zhang3 '
or 1 =1 union select cola, colb,cold from tbl_b #' and password = 'abc123' limit 0,1
php教程 防止sql注入代码
*/
function inject_check($sql_str) { //防止注入
$check = eregi('select|insert|update|delete|'|/*|*|../|./|union|into|load_file|outfile', $sql_str);
if ($check) {
echo "输入非法注入内容!";
exit ();
} else {
return $sql_str;
}
}
function checkurl() { //检查来路
if (preg_replace("/https教程?://([^:/]+).*/i", "1", $_server['http_referer']) !== preg_replace("/([^:]+).*/", "1", $_server['http_host'])) {
header("location: http://www.111cn.net");
exit();
}
}
//调用
checkurl();
$str = $_get['url'];
inject_check($sql_str);//这条可以在获取参数时执行操作
php教程 sql 预防注入与攻击技术实现以及办法
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
由于php教程和mysql教程本身得原因,php+mysql的注射要比asp教程困难,尤其是注射时语句的构造方面更是个难点,本文主要是借对okphp bbs v1.3一些文件得简单分析,来谈谈php+mysql注射语句构造方式,希望本文对你有点帮助。
声明:文章所有提到的“漏洞”,都没有经过测试,可能根本不存在,其实有没有漏洞并不重要,重要的是分析思路和语句构造。
二.“漏洞”分析:
1.admin/login.php注射导致绕过身份验证漏洞:
代码:
代码
$conn=sql_connect($dbhost, $dbuser, $dbps教程wd, $dbname); $password = md5($password); $q = "select id,group_id from $user_table where username='$username' and password='$password'"; $res = sql_query($q,$conn); $row = sql_fetch_row($res); $q = "select id,group_id from $user_table where username='$username' and password='$password'
中
$username 和 $password 没过滤,很容易就绕过。(php100中文网)
对于select * from $user_table where username='$username' and password='$password'这样的语句改造的方法有:
构造1(利用逻辑运算):$username=' or 'a'='a $password=' or 'a'='a
相当于sql语句:
select * from $user_table where username='' or 'a'='a' and password='' or 'a'='a'
构造2(利用mysql里的注释语句# ,/* 把$password注释掉):$username=admin'#(或admin'/*)
即:
select * from $user_table where username='admin'#' and password='$password'
相当于:
select * from $user_table where username='admin'
在admin/login.php中$q语句中的$password在查询前进行了md5加密所以不可以用构造1中的语句绕过。这里我们用构造2:
select id,group_id from $user_table where username='admin'#' and password='$password'"
相当于:
select id,group_id from $user_table where username='admin'
首先我们推荐filter_sanitize_string ,filter_sanitize_string 过滤器去除或编码不需要的字符。
这个过滤器删除那些对应用程序有潜在危害的数据。它用于去除标签以及删除或编码不需要的字符。
name: "string"
id-number: 513
可能的选项或标志:
filter_flag_no_encode_quotes - 该标志不编码引号
filter_flag_strip_low - 去除 ascii 值在 32 以下的字符
filter_flag_strip_high - 去除 ascii 值在 32 以上的字符
filter_flag_encode_low - 编码 ascii 值在 32 以下的字符
filter_flag_encode_high - 编码 ascii 值在 32 以上的字符
filter_flag_encode_amp - 把 & 字符编码为 &
*/
$var="<b>bill gates<b>";
var_dump(filter_var($var, filter_sanitize_string));
/*
第二个函数strip_tags
strip_tags() 函数剥去 html、xml 以及 php教程 的标签。
语法
strip_tags(string,allow)
*/
echo strip_tags("hello <b>world!</b>");
//hello world!
function uh($str)
{
$farr = array(
"/s+/",
//过滤多余的空白
"/<(/?)(script|i?frame|style|html|body|title|link|meta|?|%)([^>]*?)>/isu",
//过滤 <script 等可能引入恶意内容或恶意改变显示布局的代码,如果不需要插入flash等,还可
以加入<object的过滤
"/(<[^>]*)on[a-za-z]+s*=([^>]*>)/isu",
//过滤网页特效的on事件
);
$tarr = array(
" ",
"<123>", //如果要直接清除不安全的标签,这里可以留空
"12",
);
$str = preg_replace( $farr,$tarr,$str);
return $str;
}
更多详细内容请查看:http://www.111cn.net/phper/19/70dd2a905e74cefc9be9c0f17268dadc.htm
?>