第一次团队线下赛总结

这周四团队进行了一次内部比赛,学长让我们进行对各自搭建的登陆注册界面互相进行sql注入攻击,毫无准备的我很快就被打穿了…,唉,无奈代码写太简陋,没有提前准备,体验感极差hhh。。。



那么先来了解一下什么是sql注入
sql注入定义
所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。
sql注入原理
   当用户使用输入内容来构造动态sql语句以访问数据库时,如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的 字符串来传递,会发生sql注入。在某些表单中,用户输入的内容直接用来构造动态sql命令,或者作为存储过程的输入参数,这些表单特别容易受到sql注入的攻击。因此,没有对用户输入的合法性进行判断或者程序中本身的变量处理不当,这样,用户就可以提交一段数据库查询的代码, 根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是sql注入就发生了。
 如何防护  
主要有以下几点:
1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和
双”-“进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。

下面是我的登陆验证代码:

<?php

       $conn=mysql_connect("localhost",'root','root') or die("数据库连接失败!");//连接你的本地数据库
       localhost为服务器 root为用户名 root为密码

       mysql_select_db('myphp',$conn) or die("您要选择的数据库不存在");//选择你建立的数据库

       $name=$_POST['username'];

       $pass=$_POST['password'];//获取表单提交的内容用两个变量来存post方式接受的值

       $sql="select * from user where username='$name' and password='$pass'";//查询语句

       $query=mysql_query($sql);//函数执行一条 MySQL 查询。

       $arr=mysql_fetch_array($query);然后从$query中取一行数字数组

       if(is_array($arr)){//对$arr进行判断

              setcookie('username',$name,time()+3600);//设置cookie,时间为一小时,(以秒为单位)
              header("Location:index.php");//跳转页面

       }else{

              echo "您的用户名或密码输入有误,<a href=\"login.php\">请重新登录!</a>";

       }

?>

注意到了没,我们直接将用户提交过来的数据(用户名和密码)直接拿去执行,并没有实现进行特殊字符过滤,待会你将明白,这是致命的。
  代码分析:如果,用户名和密码都匹配成功的话,将跳转到目的操作界面 index.php,不成功,则给出提示信息。
演示注入手法
接下来将展开我们的重头戏SQL注入:
  填好正确的用户名(123)和密码(123)后,点击提交,将会返回给我们“登陆成功”的界面。
  因为根据我们提交的用户名和密码被合成到SQL查询语句当中之后是这样的:   

 select * from users where username='123' and password='123'

   很明显,用户名和密码都和我们之前给出的一样,肯定能够成功登陆。
但是,如果我们输入一个错误的用户名或密码呢?很明显,肯定登入不了吧。恩,正常情况下是如此,但是对于有SQL注入漏洞的网站来说,只要构造个特殊的“字符串”,照样能够成功登录。
比如在用户名输入框中输入:’or 1=1#,密码随便输入,这时候的合成后的SQL查询语句为:

select * from users where username='' or 1=1#' and password=md5(' ')
语义分析:“#”在mysql中是注释符,这样#号后面的内容将被mysql视为注释内容,
这样就不会去执行了,换句话说,以下的两句sql语句等价:

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#)能够登录!看到了吧,一个经构造后的sql语句竟有如此可怕的破坏力,相信你看到这后,开始对sql注入有了一个理性的认识了吧~


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2058751973@qq.com

×

喜欢就点赞,疼爱就打赏