第一次看懂 SQL 注入利用流程:从判断字段数到获取数据库信息
前两天学习了 SQL 注入为什么会产生以及数字型注入和字符型注入的区别。
本来以为学会这些就差不多了,结果继续往后看发现:真正有意思的部分才刚刚开始。
因为攻击者发现注入点之后,并不是直接就能看到数据库里的内容。
他们需要一步一步摸清数据库结构,最终才能获取想要的数据。
今天就来梳理一下 SQL 注入最经典的利用流程。
一、一个完整的 SQL 注入过程
很多人以为攻击过程是这样的:
发现漏洞
↓
直接获取数据
实际上更像这样:
每一步都有自己的作用。
二、第一步:判断是否存在注入
假设网站链接:
http://test.com/news.php?id=1
后台执行:
SELECT * FROM news WHERE id=1;
如果在参数后面添加一个单引号: ?id=1'
变成:
SELECT * FROM news WHERE id=1';
SQL 语法可能出现错误。
如果页面报错,就说明这里可能存在 SQL 注入。
很多渗透测试人员第一步都会尝试这种简单测试。
三、第二步:判断字段数量
确定存在注入之后,需要知道查询结果有多少列。
为什么要知道列数?
因为后面使用 UNION 查询时,列数必须一致!!!
例如:
SELECT id,title,time FROM news;
这里实际上有三列:
id
title
time
攻击者通常会逐步测试:
ORDER BY 1
ORDER BY 2
ORDER BY 3
ORDER BY 4
如果执行到:
ORDER BY 4
页面报错。
说明原始查询最多只有三列。
因此可以判断:
字段数 = 3
这一步非常重要。
后面的所有操作都建立在字段数正确的基础上。
四、第三步:什么是 UNION 联合查询
这一步是我今天最大的收获。
很多教程上来就写: UNION SELECT 1,2,3
但不解释为什么。
实际上 UNION 的作用非常简单:把两条查询结果拼接到一起。
例如:
第一条查询:
SELECT name FROM users;
结果:
Tom
Jack
Lucy
第二条查询:
SELECT city FROM users;
结果:
Beijing
Shanghai
Guangzhou
使用 UNION:SELECT name FROM users UNION SELECT city FROM users;
结果会被合并。
所以攻击者就能借助 UNION 把自己构造的数据插入到网页返回结果中。
五、第四步:寻找回显位
知道字段数以后。
攻击者会尝试:UNION SELECT 1,2,3
如果网页显示:
2
说明第二列的数据会显示在页面上。
如果显示:
3
说明第三列可以回显。
这种能够显示到页面的位置叫:回显位
找到回显位之后。
攻击者就能把数据库信息显示出来。
六、第五步:获取数据库信息
找到回显位以后。
攻击者会把数字替换成数据库函数。
例如:database()
作用:获取当前数据库名称
例如返回:security
说明当前数据库名字叫:security
还可以获取:version() 查看数据库版本。
user() 查看数据库运行账户。
这样攻击者就逐渐掌握了目标数据库的信息。
七、为什么攻击者总能获取数据
以前我一直以为:
数据库被入侵是因为攻击者掌握了什么特殊权限。
学习之后发现并不是。
很多情况下数据库根本没有被破解。
攻击者只是利用了程序本身提供的查询功能。
程序允许执行 SQL。
攻击者控制了 SQL 的内容。
于是原本用于查询新闻、查询商品的功能,就被拿来查询数据库信息了。
八、总结
今天最大的收获就是理解了 SQL 注入利用链。
以前看到各种 Payload 总觉得特别复杂。
现在发现其实逻辑非常清晰:
先确定有没有注入。
再确定字段数。
然后寻找回显位。
最后逐步获取数据库信息。
整个过程就像摸黑找路。
攻击者并不是一下子就知道数据库结构。
而是通过一次次测试慢慢获得信息。
