当前位置: 首页 > 科技观察

你真的了解SQL注入吗?

时间:2023-03-15 23:25:50 科技观察

本文转载自微信公众号《Java极客技术》,作者鸭血范。转载本文请联系Java极客技术公众号。一个QQ视频腾讯视频IBM视频SQL注入攻击是互联网上非常常见的一种攻击!黑客在应用程序的输入参数中插入恶意SQL查询或添加语句,然后在后台SQL服务器上分析执行程序进行攻击!那么黑客是如何在系统中植入恶意SQL脚本来达到攻击目的的呢?现在的Web程序基本都是三层架构,也就是我们常说的MVC模型:表现层:用于数据的展示,即前端界面的业务逻辑层:用于接受传递的参数从前端页面in,并进行逻辑处理数据访问层:逻辑层处理完成后,会将数据存储到对应的数据库中,如mysql、oracle、sqlserver等。例如上图中,用户访问首页,经过以下过程:在浏览器中输入www.shiyanlou.com,接收到相应的服务器。Web服务器从本地存储加载index.php脚本程序,解析脚本程序连接到数据访问层的DBMS(数据库管理系统)执行Sql语句。数据库管理系统将Sql语句的执行结果返回给Web服务器。Web服务器将页面封装成HTML格式并发送给Web浏览器。Web浏览器解析HTML文件并将内容显示给用户整个过程中间的业务逻辑层只是进行逻辑处理,从用户到数据的获取。简单的说,三层架构是一个线性关系。2、SQL注入漏洞详解刚才我们提到,当我们访问一个网页时,Web服务器会向数据访问层发起SQL查询请求,如果授权验证通过,就会执行SQL语句。一般来说,正常使用是没有危险的,但是如果将用户输入的数据构造成恶意的SQL代码,Web应用程序不检查动态构造的SQL语句使用的参数,就会造成意想不到的后果多废话!让我们来看看黑客是如何绕过参数检查来窃取数据的!一、SQL注入实例一:猜数据库下面我们使用DVWA渗透测试平台作为攻击测试的目标,让大家更清楚的了解SQL注入猜数据库是如何发生的。启动服务后,首先在浏览器中观察url,先输入1,查看回显!从图中可以看出,ID:1,FirstName:admin,Surname:admin信息!后台执行什么样的SQL语句什么?点击viewsource查看源码,其中SQL查询代码为:SELECTfirst_name,last_nameFROMusersWHEREuser_id='1';OK!如果我们不按常理出牌,比如在输入框输入1'orderby1#。实际执行的SQL语句会变成这样:SELECTfirst_name,last_nameFROMusersWHEREuser_id='1'orderby1#这条语句的意思是查询users表中user_id为1的数据,按第一个字段排序。其中#后面的SQL语句会被当作注释,不会执行!当输入1'orderby1#和1'orderby2#时,均恢复正常!按3#输入1'顺序时,返回Error!由此我们知道users表只有两个字段,数据是两列!接下来,让我们玩点高级的吧!我们使用unionselect联合查询继续获取信息!在输入框直接输入1'unionselectdatabase(),user()#查询!实际执行的Sql语句是:SELECTfirst_name,last_nameFROMusersWHEREuser_id='1'unionselectdatabase(),user()#'通过返回信息,我们成功获取到:当前网站使用的数据库为dvwa当前执行查询用户名为root@localhost接下来我们尝试获取dvwa数据库中的表名!在输入框中输入1'unionselecttable_name,table_schemafrominformation_schema.tableswheretable_schema='dvwa'#进行查询!实际执行的Sql语句是:SELECTfirst_name,last_nameFROMusersWHEREuser_id='1'unionselecttable_name,table_schemafrominformation_schema.tableswheretable_schema='dvwa'#'通过上图返回信息,然后我们得到:dvwa数据库有两张数据表,分别是guestbook和用户。有的同学可能还不够满足??,那就来试试看重量级的用户名和密码吧!根据经验,我们可以大胆猜测users表的字段是user和password,所以输入:1'unionselectuser,passwordfromusers#查询:实际执行的Sql语句是:SELECTfirst_name,last_nameFROMusersWHEREuser_id='1'unionselectuser,passwordfromusers#'可以看到用户名和密码已经爆破成功。密码是用md5加密猜测的,可以直接上www。解密cmd5.com网站2.SQL注入示例2:认证绕过下面我们再尝试一个利用SQL漏洞绕过登录认证的例子!这是一个普通的登录页面,只要输入正确的用户名和密码就可以登录成功。我们试试随便用用户名123和密码123登录吧!好像不行,登录被阻塞了,我们从错误页面也获取不到任何信息!点击viewsource查看源码,SQL查询代码为:select*fromuserswhereusername='123'andpassword='123'按照上面例子的思路,我们尝试输入123'或者1=1#在用户名中,并在密码中输入123'或1=1#。恭喜,您已成功登录!为什么可以登录成功?实际执行的语句是:select*fromuserswhereusername='123'or11=1#'andpassword='123'or11=1#'根据Mysql语法,#后面的内容会被忽略,所以上面的语句等同于:select*fromuserswhereusername='123'or11=1由于判断语句or1=1总是成立的,结果当然会返回true,登录成功!我们再试一次,不用#来屏蔽单引号,在用户名中输入123'或'1'='1,在密码中输入123'或'1'='1。依然能够登录成功,实际执行的SQL语句是:select*fromuserswhereusername='123'or'1'='1'andpassword='123'or'1'='1'两个or语句make和两个判断before和after总是等于true,所以可以登录成功!3、SQL注入示例3:确定注入点通常,可能存在SQL注入漏洞的URL类似这样的形式:http://xxx.xxx.xxx/abcd.php?id=XX。SQL注入的判断主要有两个方面:判断带参数的Url是否可以进行SQL注入。如果有SQL注入,那是什么SQL注入?一个参数,有时可能有多个参数。有时是整型参数,有时是字符串参数,不能一概而论。总之,只要是带参数的动态网页,而且这个网页访问的是数据库,都有SQL注入的可能。比如有这样一个URL地址:http://xxx/abc.php?id=1首先,根据经验,可能会执行如下语句查询:select*fromwhereid=x因此,在URL地址栏输入http://xxx/abc.php?id=x和'1'='1页面依然运行正常,继续下一步!当然,不带参数的URL可能不安全,现在有很多第三方工具,比如postman工具,也可以模拟各种请求!黑客在攻击的时候也会用各种假设来验证自己的判断!3、如何防止SQL注入?上面描述的SQL攻击场景比较基础,只是简单的给大家介绍一下!那么对于这种黑客攻击,我们有什么办法可以做到呢?答案肯定是肯定的,就是审核前端用户输入的所有参数,最好判断或者全文替换!比如当用户输入非法字符时,使用正则表达式进行匹配判断!privateStringCHECKSQL="^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$";Pattern.matches(CHECKSQL,targerStr);或者,全局替换,两者都可以!publicstaticStringTransactSQLInjection(Stringsql){returnsql.replaceAll(".*([';]+|(--)+).*","");}也可以使用预编译语句集!比如在使用Mybatis的时候,尽量使用#{}语法来传递参数,而不是${}!例如!如果传入的用户名是a'或'1=1,则使用${}处理,直接替换字符串的sql,会解析为select*fromt_userwhereusername='a'or'11=1'在此这样,所有的用户数据都会被查出来,属于SQL注入!如果使用#{},sql动态解析预编译后,单引号会被转义为\',SQL最终会被解析为select*fromt_userwhereusername="a\'or\'1=1",这样会failtocheck输出任何数据,有效防止SQL注入!