复制代码代码以下:
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(64) NOT NULL, `password` varchar(64) NOT NULL, `email` varchar(64) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
添加一条记录用于测试:
INSERT INTO users (username,password,email)
VALUES('MarcoFly',md5('test'),'marcofly@test.com');
接下来,贴上登陆界面的源代码:
<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>
附上效果图:
<html>
<head> <title>登陆验证</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"> </head> <body> <?php $conn=@mysql_connect("localhost",'root','') or die("数据库链接失败!");; mysql_select_db("injection",$conn) or die("您要选择的数据库不存在"); $name=$_POST['username']; $pwd=$_POST['password']; $sql="select * from users where username='$name' and password='$pwd'"; $query=mysql_query($sql); $arr=mysql_fetch_array($query); if(is_array($arr)){ header("Location:manager.php"); }else{ echo "您的用户名或密码输入有误,<a href=\"Login.php\">请从新登陆!</a>"; } ?> </body> </html>
注意到了没有,咱们直接将用户提交过来的数据(用户名和密码)直接拿去执行,并无实现进行特殊字符过滤,待会大家将明白,这是致命的。 代码分析:若是,用户名和密码都匹配成功的话,将跳转到管理员操做界面(manager.php),不成功,则给出友好提示信息。 登陆成功的界面:
登陆失败的提示:html
到这里,前期工做已经作好了,接下来将展开咱们的重头戏:SQL注入 2) 构造SQL语句 填好正确的用户名(marcofly)和密码(test)后,点击提交,将会返回给咱们“欢迎管理员”的界面。 由于根据咱们提交的用户名和密码被合成到SQL查询语句当中以后是这样的: select * from users where username='marcofly' and password=md5('test') 很明显,用户名和密码都和咱们以前给出的同样,确定可以成功登录。可是,若是咱们输入一个错误的用户名或密码呢?很明显,确定登入不了吧。恩,正常状况下是如此,可是对于有SQL注入漏洞的网站来讲,只要构造个特殊的“字符串”,照样可以成功登陆。 好比:在用户名输入框中输入:' or 1=1#,密码随便输入,这时候的合成后的SQL查询语句为: select * from users where username='' or 1=1#' and password=md5('') 语义分析:“#”在mysql中是注释符,这样井号后面的内容将被mysql视为注释内容,这样就不会去执行了,换句话说,如下的两句sql语句等价: mysql
select * from users where username='' or 1=1#' and password=md5('')
等价于
select * from users where username='' or 1=1
由于1=1永远是都是成立的,即where子句老是为真,将该sql进一步简化以后,等价于以下select语句: select * from users 没错,该sql语句的做用是检索users表中的全部字段 小技巧:若是不知道' or 1=1#中的单引号的做用,能够本身echo 下sql语句,就一目了然了。 看到了吧,一个经构造后的sql语句竟有如此可怕的破坏力,相信你看到这后,开始对sql注入有了一个理性的认识了吧~ 没错,SQL注入就是这么容易。可是,要根据实际状况构造灵活的sql语句却不是那么容易的。有了基础以后,本身再去慢慢摸索吧。 有没有想过,若是经由后台登陆窗口提交的数据都被管理员过滤掉特殊字符以后呢?这样的话,咱们的万能用户名' or 1=1#就没法使用了。但这并非说咱们就毫无对策,要知道用户和数据库打交道的途径不止这一条。