CSRF自動化檢測

CSRF自動化檢測:html

這裏主要是對POST型form表單的檢測git

1. 根據URL獲取form表單組成的數組web

2. 遍歷表單數組,對比不設置cookie與設置了cookie兩種狀況下的表單是否還存在,若是還存在就去除數組中的該表單。ajax

由於不設置cookie沒有登陸態也能獲取的表單、也能進行的操做對於CSRF來講沒有意義。chrome

3. 遍歷表單數組,在設置cookie的狀況下訪問兩次頁面,檢測表單是否有所變化,若是有變化,去除數組中的該表單。數組

由於變化緣由一般是由token引發的。token在每一次的頁面中都不一樣。cookie

 

接下來就是根據各類黑名單來過濾掉大概率不存在CSRF的form表單。less

4. 去除沒有提交按鈕的表單。ui

關鍵字:submit、button等url

5. 去除placeholder屬性中含有跳、搜、查、找等關鍵字的數組,placeholder爲input中預顯示的內容

6. 去除cgi中包含search find login reg等關鍵字的數組。

7. 去除帶有驗證碼的表單

img標籤中帶有關鍵字  vcode,yzm,verifyCode,captcha

8. 去除帶有token關鍵字的表單。

 

餘下的表單可初步斷定爲該url中存在csrf的表單。

 

這套程序並不完整,能夠說是簡陋,只是一天就寫出來的東西。

還須要檢測GET型重要操做的CSRF,再用chrome-headless webkit檢測ajax的GET/POST CSRF,纔可以覆蓋到大部分業務。

拋磚引玉吧,小夥子給我玉唄

 

代碼以下:

#coding:utf-8
import requests
import re
'''
獲取URL中的表單
'''


class csrfCheck:
    '''
    輸入原生cookie,返回cookie拆分紅的字典類型
    '''
    def tranCookie(self,rawC):
        '''將原生的一大串cookie(從Burpsuite中截取出來)轉換爲字典'''
        cookie={}
        cookies=rawC.split("; ")
        for i in cookies:
            name=i.split("=",1)[0]
            value=i.split("=",1)[1]
            cookie[name]=value
        return cookie

    def getForms(self,url,cookie):
        '''輸入url與cookie字典,返回頁面中的表單html代碼 數組'''


        headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
        q=requests.get(url,headers=headers,cookies=cookie)
        rep=q.content
        #print rep

        q_nocookie=requests.get(url,headers=headers)
        rep_nocookie=q_nocookie.content

        forms=re.findall("<form[\s\S]*?</form>",rep)

        # 對比各個表單在沒有cookie的狀況下是否存在
        # 若是不用cookie也能獲取表單
        # 那麼csrf沒意義,不是須要檢測的form,過濾掉
        for i in forms:
            link=re.findall("<form[\s\S]*?>",i)[0]

            if link in rep_nocookie:
                forms.remove(i)
                print "goout 1"


        '''
        以一樣的url和cookie請求,檢測在兩次請求中表單是否有變化。
        若是有變化,則應該是token每次刷新頁面都不一樣的緣由引發的。
        因此排除掉。
        後續若是發現其餘引發form變化的非token因素,修改此過濾條件。
        '''
        q_recheckToken=requests.get(url,headers=headers,cookies=cookie)
        rep_recheckToekn=q_recheckToken.content

        for form in forms:
            if form not in rep_recheckToekn:
                forms.remove(form)
                print "goout 2"



        return forms


    def filter(self,forms):
        '''根據條件過濾去大機率不存在csrf的表單'''
        '''去除沒有提交按鈕的表單'''
        for form in forms:
            if "submit" not in form.lower() and "button" not in form.lower():
                forms.remove(form)
                print "goout 3"


        '''去除帶驗證碼的表單'''
        yzmFile=open("yzm.txt","r")
        yzmtext=yzmFile.readlines()
        yzmFile.close()
        #遍歷表單
        for form in forms:
            #是否有驗證碼的標記位
            ifVcode=0
            imgs=re.findall("<img.*?>",form)
            #遍歷表單中的圖片標籤
            for img in imgs:
                if ifVcode==1:
                    break
                #遍歷關鍵字對圖片標籤進行檢測
                for key in yzmtext:
                    #轉換爲小寫字母,不區分大小寫
                    if key.strip() in img.lower():
                        forms.remove(form)
                        print "goout 4"
                        ifVcode=1
                        break

        '''去除placeholder(input中的預期信息)符合黑名單的'''
        '''在驗證cookie有無影響時已經去除了一遍,這裏雙重驗證'''
        phFile=open("placeholder.txt","r")
        phtext=phFile.readlines()
        phFile.close()
        for form in forms:
            #placeholder是否符合黑名單的標記位
            ifPlaceholder=0
            phs=re.findall("placeholder=\".*?\"",form)
            #遍歷表單中的placeholder屬性
            for ph in phs:
                if ifPlaceholder==1:
                    break
                #遍歷關鍵字對placeholder進行檢測
                for key in phtext:
                    #轉換爲小寫字母,不區分大小寫
                    if key.strip() in ph.lower():
                        forms.remove(form)
                        print "goout 5"
                        ifPlaceholder=1
                        break

        '''去除cgi中存在search login等黑名單的表單'''
        '''在驗證cookie有無影響時已經去除了一遍,這裏雙重驗證'''
        cgiFile=open("cgi.txt","r")
        cgitext=cgiFile.readlines()
        cgiFile.close()
        for form in forms:
            #cgi是否符合黑名單的標記位
            ifCgi=0
            formTitle=re.findall("<form[\s\S]*?>",form)[0]
            cgis=re.findall("\".*?\"",formTitle)
            for cgi in cgis:
                if ifCgi==1:
                    break
                for key in cgitext:
                    if key.strip() in cgi.lower():
                        forms.remove(form)
                        print "goout 6"
                        ifCgi=1
                        break

        '''
        檢測是否存在token的關鍵字,後續應該將檢測的地方定位到更精確的位置
        縮小檢測範圍,減小漏報
        '''
        tokenFile=open("token.txt","r")
        tokentext=tokenFile.readlines()
        tokenFile.close()
        #檢測token關鍵字
        for form in forms:
            for key in tokentext:
                if key.strip() in form.lower():
                    forms.remove(form)
                    print "goout 7"
                    break

    def show(self,forms):
        for form in forms:
            print form
    def main(self,url,rawCookie):

        cookie=self.tranCookie(rawCookie)
        forms=self.getForms(url,cookie)
        self.filter(forms)
        return forms
if __name__ == '__main__':
    url="http://檢測的URL"
    rawCookie='''你的cookie原生字符串'''
    csrf=csrfCheck()
    result=csrf.main(url,rawCookie)
    if len(result) == 0:
        print "NO CSRF"
    else:
        print "CSRF!!"
        print url
        print re.findall("<form[\s\S]*?>",result)[0]
        #csrf.show(result)

 

placeholder.txt

跳
搜
查
找
登陸
註冊
search
find
login
reg

cgi.txt

search
find
login
reg

yzm.txt  驗證碼黑名單

captcha
vcode
yzm
verifyCode
驗證碼

token.txt   token黑名單

token
g_tk
csrf
相關文章
相關標籤/搜索