• 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
  • 相关阅读:
    eclipse技巧总结
    java中的全等和相似
    curl命令
    tr命令
    Ubuntu下安装支付宝安全控件
    Firefox about
    Ubuntu Terminal Shortcut
    ulimit
    ajax post(copy part)
    getopt
  • 原文地址:https://www.cnblogs.com/huim/p/8512132.html
Copyright © 2020-2023  润新知