SQL注入学习笔记
SQL注入学习笔记
宏观视角的注入:5种不同类型的注入
这五种不同类型注入的分类,是通过注入是否成功回显方式不同判断标准来分类的
- 布尔型注入
- 联合查询:使用union字段
- 时间盲注:基于时间延迟的注入
- 报错型注入
- 可多语句查询注入
举例说明
布尔型注入
页面只返回True和False两种类型页面。利用页面返回不同,逐个猜数据
http://test.com?id=1 and substring(version(), 1, 1) = 5
如果数据库版本是5.x那么就可以正常返回页面
联合查询注入
判断是否入住成功的标准就是是否查询了其他的信息出来。这个是最快捷的获取任何想要的数据的方法,但是有一个前提,就是该请求能返回sql查询的结果
http://test.com?id=1 UNION select 1,2,3,4 from INFORMATION_SCHEMA
基于时间的盲注
如果一个请求没有任何的返回,或者说,是否成功结果都是相同的,那我们就没法用布尔或者联合查询来判断这里是否能够注入,于是我们就需要时间盲注
Select * from user where id = 1 and sleep(3)
这条语句如果成功执行,会在3秒后执行查询,如果我们在前端感知到确实有时间上的延迟,说明sql注入成功了
报错型注入
这类注入比较少见,需要前端能够显示部分sql的报错信息,而这需要后端直接就把报错结果返回给前端
典型的就是group by的duplicate key的报错
多语句查询注入
最危险的注入类型,能够执行多条语句,这意味着我们也可以执行更新数据库的操作
http://test.com?id=1; update set name = ‘1’ where id = 1
SQL注入最关键的两个步骤
- 发现可以注入的点。如报错型,如果我们输入1可以正常查询,输入1‘则会报错,说明这里有sql注入问题
- 构造原始的注入语句。通过猜测后端的sql语句,尝试闭合原有语句并执行自己的内容
利用时间盲注绕过无报错(布尔)无回显(联合)场景
定义:通过注入特定语句,通过页面对请求的物理反馈,来判断注入是否成功,如注入sleep语句来观察页面的加载时间来判断注入点。
适用于无法从页面上获取注入结果,甚至连注入语句是否成功执行都不知道的情景
也就是说我们可以在sleep之前拼接我们真正想要判断的信息,如果时间延迟了,说明前面的判断是正确的,如果没有延迟,说明sleep之前的判断是失败的
时间盲注的常用函数:substr,count,ascii,length,left,sleep
- 一般的步骤,首先需要判断这里存在时间盲注,所以一般一开始不是and sleep(3),而是or sleep(3),如果确实感到有时间上的延迟,确认有时间盲注。(或者你确定前面的条件一定为真,也可以直接中and sleep(3))
- 如果有时间盲注,则在sleep之前加入自己想要判断的条件,如搜索是否有个叫user的数据库
举例:
获取数据库长度
获取数据库名称
HTTP头注入
针对HTTP请求的头部信息,如果不加以过滤或者转义,在直接与数据库交互的过程中,就容易发生SQL注入。如有的webapp会从头部信息中获取用户的访问记录,IP,hostname等信息
比如server会从头部中获取user-agent信息插入数据库。
我们猜测,后端的注入语句是"insert into user values(" + use-agent + “)”
那我们可以尝试修改user-agent头部,将x替换成 1); sleep(3)#
如果有时间延迟,则说明注入成功
如果语句是"insert into user values(" + use-agent + “,” + ip_address + “)”,还能成功注入吗?
如果语句是"insert into user values(" + ip_address + “,” + use-agent + “)”,还能成功注入吗?
报错型注入
MySql的报错注入主要是利用MySql的一些逻辑漏洞,如BigInt大整数溢出等。
可以将MySql的报错注入划分为以下类型:
- BigInt等数据类型溢出
- Xpath语法错误
- count() + rand() + group_by()导致重复
- 空间数据类型函数错误
前置知识:预备函数
- rand(N):返回一个随机数,如果传入参数,则N相同时,产生的随机序列也想通
- floor(x):返回一个不大于x的整数
- count:返回数据集的数量