一、Sql注入简介
Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,它目前黑客对数据库进行攻击的最常用手段之一。
在上图中,用户访问实验楼主页进行了如下过程:
-
在 Web 浏览器中输入
www.shiyanlou.com
连接到实验楼服务器。 -
业务逻辑层的 Web 服务器从本地存储中加载
index.php
脚本并解析。 -
脚本连接位于数据访问层的
DBMS
(数据库管理系统),并执行Sql
语句。 -
数据访问层的数据库管理系统返回
Sql
语句执行结果给 Web 服务器。 -
业务逻辑层的 Web 服务器将 Web 页面封装成 HTML 格式发送给表示层的 Web 浏览器。
-
表示层的 Web 浏览器解析 HTML 文件,将内容展示给用户。
二.SQL注入的本质就是修改当前查询语句的结构,从而获取额外的信息和内容。因此,判断SQL注入漏洞的第一步就是尝试利用"恒真“”恒假“的方式进行测试。
接下来我们再试试另一个利用 Sql 漏洞绕过登录验证的实例。
使用事先编写好的页面,这是一个普通的登录页面,只要输入正确的用户名和密码就能登录成功。
我们先尝试随意输入用户名 123 和密码 123 登录:
从错误页面中我们无法获取到任何信息。
看看后台代码如何做验证的:
s
实际执行的操作时:
select * from users where username='123' and password='123'
当查询到数据表中存在同时满足 username 和 password 字段时,会返回登录成功。
按照第一个实例的思路,我们尝试在用户名中输入 123' or 1=1 #
, 密码同样输入 123' or 1=1 #
:
为什么能够成功登陆呢?因为实际执行的语句是:
select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'
按照 Mysql 语法,# 后面的内容会被忽略,所以以上语句等同于(实际上密码框里不输入任何东西也一样):
select * from users where username='123' or 1=1
由于判断语句 or 1=1 恒成立,所以结果当然返回真,成功登录。
我们再尝试不使用 # 屏蔽单引号,采用手动闭合的方式:
我们尝试在用户名中输入 123' or '1'='1
, 密码同样输入 123' or '1'='1
(不能少了单引号,否则会有语法错误):
实际执行的 Sql 语句是:
-
select * from users where username='123' or '1'='1' and password='123' or '1'='1
看到了吗?两个 or 语句使 and 前后两个判断永远恒等于真,所以能够成功登录。
还有很多其他 Mysql 语句可以巧妙的绕过验证,同学们可以发散自己的思维进行尝试。
三.判断是否存在 Sql 注入漏洞
最为经典的单引号判断法:
在参数后面加上单引号,比如:
-
http://xxx/abc.php?id=1'
如果页面返回错误,则存在 Sql 注入。
原因是无论字符型还是整型都会因为单引号个数不匹配而报错。
(如果未报错,不代表不存在 Sql 注入,因为有可能页面对单引号做了过滤,这时可以使用判断语句进行注入,因为此为入门基础课程,就不做深入讲解了)
四.
union 运算符可以将两个或两个以上 select 语句的查询结果集合合并成一个结果集合显示,即执行联合查询。
输入1' union select database(),user()#
进行查询 :
- database()将会返回当前网站所使用的数据库名字.
- user()将会返回执行当前查询的用户名.
同理我们再输入 1' union select version(),@@version_compile_os#
进行查询:
- version() 获取当前数据库版本.
- @@version_compile_os 获取当前操作系统。
information_schema
是 mysql 自带的一张表,这张数据表保存了 Mysql 服务器所有数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权限等。该数据库拥有一个名为 tables 的数据表,该表包含两个字段 table_name 和 table_schema,分别记录 DBMS 中的存储的表名和表名所在的数据库。
我们输入1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#
进行查询: