CSRF自动化检测

CSRF自动化检测:

这里主要是对POST型form表单的检测

1. 根据URL获取form表单组成的数组

2. 遍历表单数组,对比不设置cookie与设置了cookie两种情况下的表单是否还存在,如果还存在就去除数组中的该表单。

因为不设置cookie没有登录态也能获取的表单、也能进行的操作对于CSRF来说没有意义。

3. 遍历表单数组,在设置cookie的情况下访问两次页面,检测表单是否有所变化,如果有变化,去除数组中的该表单。

因为变化原因通常是由token引起的。token在每一次的页面中都不同。

接下来就是根据各种黑名单来过滤掉大几率不存在CSRF的form表单。

4. 去除没有提交按钮的表单。

关键字:submit、button等

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[sS]*?</form>",rep)

        # 对比各个表单在没有cookie的情况下是否存在
        # 如果不用cookie也能获取表单
        # 那么csrf没意义,不是需要检测的form,过滤掉
        for i in forms:
            link=re.findall("<form[sS]*?>",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[sS]*?>",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[sS]*?>",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
原文地址:https://www.cnblogs.com/huim/p/8512132.html