由一次SQL注入去理解防SQL注入
来源:互联网 发布:淘宝代练可靠吗 编辑:程序博客网 时间:2024/06/01 14:06
SQL注入是PHP运用最常见的漏洞之一,很多开发人员都会时刻提防着它,防SQL注入的普遍做法是对数据输入进行过滤,以及对发送到数据库的数据进行转义。其实就是永远不要相信用户输入数据。为了更好的理解SQL注入,笔者今天自己尝试用SQL“攻击”自己了一次。以下是建立攻击的一个过程。
1、建立用户表
我用PHPMyAdmin在我test数据库建立了一张user表,表中有三个字段,分别是用户名、密码、邮箱,然后插入了一条测试数据
用户名是:周运金,密码是test(用了MD5加密)
2、建立登陆页面form.html
<html><head><title>Sql注入</title><meta http-equiv="content-type"content="text/html;charset=utf-8"></head><body><form action="validate.php" method="post"> <fieldset > <legend>Sql注入</legend> <table> <tr> <td>用户名:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>密 码:</td> <td><input type="text" name="password"></td> </tr> <tr> <td><input type="submit" value="提交"></td> <td><input type="reset" value="重置"></td> </tr> </table> </fieldset></form></body></html>
效果:
3、创建处理登陆Validate.php
<?php //面向对象的连接方式 $mysqli =new mysqli("localhost","root","123","test"); if(!$mysqli ){ echo mysqli_connect_error(); } $mysqli->set_charset("utf8"); $mysqli->query("set names 'utf8'"); $name=$_POST['username']; $pwd=md5($_POST['password']); $sql="select * from user where username='$name' and password='$pwd'"; $query=$mysqli->query($sql); if($query == false){ echo $mysqli->error; } else{ $rows =$query->num_rows; if($rows){ header("Location:manage.php"); }else{ echo "您的用户名或密码输入有误,<a href='form.html'>请重新登录!</a>"; } } $mysqli->close();?>
这里说明一下,原始MySQL在PHP5.5之后已经被php抛弃,采用面像对象连接的MYSQLI。
4、建立登陆成功的页面manage.php
<?php echo "You are a manager"; ?>
这样就完成了一个有SQL注入漏洞的登陆程序了。很明显程序没有对用户输入的数据进行处理就直接放进sql语句里面了。这是很危险的做法。
接下来就开始攻击一下吧,做法其实很简单只要去拼凑sql语句就好了。
我先输入正确的用户名和密码:
为了显示密码我这里没有用密码框了。输入完之后成功登陆
接下来正式注入了,用户名输入:’ or 1=1# 密码随便输入
点击提交之后:
居然登陆成功了。哈哈哈,接下来分析一下注入后SQL语句吧:
我在sql语句那里设置了一个断点,看一下拼接后的sql
这里可以看到拼接后的sql语句是:
select * from user where username=” or 1=1#’ and password=’202cb962ac59075b964b07152d234b70’这里的#是mysql的注释符,意思就是忽略后面的sql语句,这样的话就不用验证了,而且在username后面还有一句逻辑语句or 1=1,这样的话这条语句永远成立,所以就通过了验证。
接下来就谈谈常见的方SQL注入方法:
1、最常见的就是采用mysqli_real_escape_string函数进行转义一些特殊的字符比如\n、\r、\、’、” 等(在查找mysql_real_escape_string函数的时候发现PHP文档说这个函数在php5.5之后就被抛弃了,改用mysqli_real_escape_string,看来PHP要全面使用面向对象的mysqli了),就像刚才的注入有个单引号,用了这个函数之后就会被转义,这样拼接就失败了。我们来看看再用之前的’ or 1=1#去拼接,加入这个函数之后会怎样:
$name=mysqli_real_escape_string($mysqli,$_POST['username']); //必须使用数据库连接,这样看来是专门为防sql注入准备的,比较安全 $pwd=mysqli_real_escape_string($mysqli,md5($_POST['password']));
结果不能登录了,设个断点看一下转义之后sql语句:
这个是PHP文档给出的例子
<?php // Assume this is a simple comments form with a name and comment. $name = mysqli_real_escape_string($conn, $_POST['name']); $comments = mysqli_real_escape_string($conn, $_POST['comments']); // Here is where most of the action happens. But see note below // on dumping back out from the database // We should use the ENT_QUOTES flag second parameter... $name = htmlspecialchars($name); $comments = htmlspecialchars($comments); $insert_sql = "INSERT INTO tbl_comments ( c_id, c_name, c_comments ) VALUES ( DEFAULT, '" . $name . "', '" . $comments . "')"; $res = mysqli_query($conn, $insert_sql); if ( $res === false ) { // Something went wrong, handle it } // Now output page showing comments?>
看到单引号‘被转义成了/’了这样的话拼接就没用了。
二、打开magic_quotes_gpc来防止SQL注入
这个原理跟第一个的原理类似,是将GET、POST、COOKIE传过来的数据进行自动转义,相当于用addslshes()函数进行转义。但是这种方式没有办法防止当参数是数字型的sql攻击,因为数字是没有单引号或者双引号的。解决的办法是用intaval()函数强制将字符数据转换成数字。如果开启了magic_quotes_gpc=on,在第一个方法中记得用stripslashes函数去掉/
三、自定义过滤函数
以下是W3C给出的一个过滤函数我将转义函数改了
function check_input($value,$con){// 去除斜杠if (get_magic_quotes_gpc()) { $value = stripslashes($value); }// 如果不是数字则加引号if (!is_numeric($value)) { $value = "'" . mysqli_real_escape_string($con,$value) . "'"; }return $value;}
这个函数考虑到使用mysqli_real_escape_string比使用addslshes()更加安全
最后注意了:
在写这篇文章的时候,笔者参考了一篇文章说sql注入可以绕开以上的方法了,吓得得我一身冷汗,看了之后果然觉得厉害。文章中建议使用不要用mysql_query了而是用PDO和MYSQLi来代替mysql_query,心想还好我用的是mysqli,它采用了mysqli的Prepared Statement机制可以有效解决sql注入。大家可以参考一下
文章地址:参考文章
总结:
1、sql注入的方式其实很简单,但是后果却是很致命的,所以开发人员一定记住永远不要去相信客户的数据。
2、防sql注入的方法有很多,但是一定得保持一定得技术更新,因为黑客的技术越来越厉害了,要经常更新这方面的防护知识,随时保持最新的防漏洞知识。
- 由一次SQL注入去理解防SQL注入
- 防sql注入&文本框防sql注入
- 防SQL注入
- SQL防注入简介
- SQL防注入简介
- SQL防注入
- SQL防注入简介
- asp sql 防注入
- 防SQL注入
- 防SQL注入攻击
- SQL防注入简介
- 'SQL防注入
- 防sql注入代码
- 防sql注入
- 被动防SQL注入
- 防SQL注入
- sql防注入 sql防注入 sql防注入 sql防注入
- 防sql注入!
- C++迭代器iterator
- IP协议
- 数据压缩实验一:yuv转rgb
- 应用程序、内核、驱动的关系
- JavaWeb监听器
- 由一次SQL注入去理解防SQL注入
- 修改XAMPP for mac中的MySQL字符集
- 在云开发的新时代中,可以看到的十大趋势
- pthreads 里mutex和cond为何需要配合使用
- ZOJ1137&&POJ1466-Girls and Boys
- 从零开始部署小型企业级虚拟桌面 -- Vmware Horizon View 6 For Linux VDI -- 概念简介
- 三步安装最新版gitlab
- 浅析Java中的反射机制原理
- jsp中引用Dao或Service