{"id":18705235,"url":"https://github.com/safe6sec/burpdevnote","last_synced_at":"2025-11-09T05:30:33.129Z","repository":{"id":105279523,"uuid":"439645044","full_name":"safe6Sec/burpDevNote","owner":"safe6Sec","description":"burp插件开发笔记","archived":false,"fork":false,"pushed_at":"2021-12-26T07:55:41.000Z","size":9,"stargazers_count":11,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-28T06:28:00.450Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/safe6Sec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-18T15:08:44.000Z","updated_at":"2024-11-01T12:40:55.000Z","dependencies_parsed_at":"2023-05-22T06:30:37.633Z","dependency_job_id":null,"html_url":"https://github.com/safe6Sec/burpDevNote","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe6Sec%2FburpDevNote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe6Sec%2FburpDevNote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe6Sec%2FburpDevNote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/safe6Sec%2FburpDevNote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/safe6Sec","download_url":"https://codeload.github.com/safe6Sec/burpDevNote/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239568042,"owners_count":19660601,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T12:10:14.250Z","updated_at":"2025-11-09T05:30:33.075Z","avatar_url":"https://github.com/safe6Sec.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# burpDevNote\nburp插件开发笔记，简单记一下方便查阅。刚入门最好的建议就是模仿，多看别人写的，尝试着修改，尝试着自己写一个。\n\n\n\n\n\n## 基础知识\n\nburp suite支持三种编程语言开发的插件:\n\n- Java\n- python\n- ruby\n\n我选java\n\n官方各种示例代码：https://portswigger.net/burp/extender\n\n官方API文档：https://portswigger.net/burp/extender/api/\n\n\n\nmaven依赖\n\n```xml\n\t\t \u003cdependency\u003e\n            \u003cgroupId\u003enet.portswigger.burp.extender\u003c/groupId\u003e\n            \u003cartifactId\u003eburp-extender-api\u003c/artifactId\u003e\n            \u003cversion\u003e1.7.22\u003c/version\u003e\n        \u003c/dependency\u003e\n```\n\n\n\n- 所有的burp插件都必须实现IBurpExtender这个接口\n- 实现类的包名称必须是burp\n- 实现类的名称必须是BurpExtender，burp插件入口\n- 实现类比较是public的\n- 实现类必须有默认构造函数（public，无参），如果没有定义构造函数就是默认构造函数\n\n\n\n### callbacks对象的作用\n\n通过 callbacks 这个实例对象，传递给插件一系列burp的原生方法。我们需要实现的很多功能都需要调用这些方法。当前拓展用来和burp进行交互，如各种注册，设置拓展名字，获取helper，添加菜单等等。\n\n\n\n### 需要主动注册的对象\n\n\n\n也就是需要写在registerExtenderCallbacks方法里面的\n\n他们的共通特定是：会被burp主程序主动调用或者主动通知，burp主程序必须知道它们的存在，才能完成对应的功能。\n\n#### 各种事件监听器\n\nExtensionStateListener\n\nHttpListener\n\nProxyListener\n\nScannerListener\n\nScopeChangeListener\n\n#### 各种对象构造工厂\n\nContextMenuFactory\n\nMessageEditorTabFactory\n\nIntruderPayloadGeneratorFactory\n\n#### 其他\n\nScannerInsertionPointProvider\n\nScannerCheck\n\nIntruderPayloadProcessor\n\nSessionHandlingAction\n\nMenuItem\n\n\n\n## 关键对象\n\n\n\n### IExtensionHelpers\n\n用途：主要用来处理数据包\n\n初始化,一般写在registerExtenderCallbacks方法里面\n\n```java\nIExtensionHelpers helpers = callbacks.getHelpers();\n```\n\nRequest和Response获取\n\n```\nIRequestInfo analyzeRequest = helpers.analyzeRequest(requestOrResponse);\nIResponseInfo analyzeResponse = helpers.analyzeResponse(requestOrResponse);\n```\n\n获取header\n\n```\nIRequestInfo analyzeRequest = helpers.analyzeRequest(requestOrResponse);\n\t\t\tList\u003cString\u003e headers = analyzeRequest.getHeaders();\n```\n\n获取body\n\n```java\n\tint bodyOffset = -1;\n\t\tif(isRequest) {\n\t\t\tIRequestInfo analyzeRequest = helpers.analyzeRequest(requestOrResponse);\n\t\t\tbodyOffset = analyzeRequest.getBodyOffset();\n\t\t}else {\n\t\t\tIResponseInfo analyzeResponse = helpers.analyzeResponse(requestOrResponse);\n\t\t\tbodyOffset = analyzeResponse.getBodyOffset();\n\t\t}\n\t\tbyte[] byte_body = Arrays.copyOfRange(requestOrResponse, bodyOffset, requestOrResponse.length);\n//not length-1\n\t\t//String body = new String(byte_body); //byte[] to String\n\t\treturn byte_body;\n```\n\n\n\n修改http包\n\n```\nbyte[] RequestOrResponse = helpers.buildHttpMessage(headers, body);\n```\n\n\n\n具体看大佬封装的工具类https://github.com/bit4woo/burp-api-common/blob/master/src/main/java/burp/HelperPlus.java\n\n\n\n\n\n### IHttpListener\n\n用途：任何组件产生的请求和响应都会触发http监听器，有点被动扫描的味道。\n\n必须实现processHttpMessage方法\n\n```java\nprocessHttpMessage(int toolFlag,boolean messageIsRequest,IHttpRequestResponse messageInfo)\n```\n\ntoolFlag\n\n不同的toolFlag代表了不同的burp组件,一共如下\n\n https://portswigger.net/burp/extender/api/constant-values.html#burp.IBurpExtenderCallbacks\n\n![image-20211220212403938](https://gitee.com/safe6/img/raw/master/image-20211220212403938.png)\n\nmessageIsRequest，判断当前是不是request\n\nIHttpRequestResponse，具体的消息体对象。可用`helpers#analyzeRequest`对消息体进行解析,messageInfo是整个HTTP请求和响应消息体的总和，各种HTTP相关信息的获取都来自于它，HTTP流量的修改都是围绕它进行的。\n\n\n\n\n\n```java\npackage burp;\n\nimport java.io.PrintWriter;\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class BurpExtender implements IBurpExtender, IHttpListener\n{//所有burp插件都必须实现IBurpExtender接口，而且实现的类必须叫做BurpExtender\n\tprivate IBurpExtenderCallbacks callbacks;\n\tprivate IExtensionHelpers helpers;\n\n\tprivate PrintWriter stdout;\n\tprivate PrintWriter stderr;\n\tprivate String ExtenderName = \"burp extender api drops by bit4woo\";\n\n\t@Override\n\tpublic void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)\n\t{//IBurpExtender必须实现的方法\n\t\tstdout = new PrintWriter(callbacks.getStdout(), true);\n\t\tstderr = new PrintWriter(callbacks.getStderr(), true);\n\t\tcallbacks.printOutput(ExtenderName);\n\t\t//stdout.println(ExtenderName);\n\t\tthis.callbacks = callbacks;\n\t\thelpers = callbacks.getHelpers();\n\t\tcallbacks.setExtensionName(ExtenderName); \n\t\tcallbacks.registerHttpListener(this); //如果没有注册，下面的processHttpMessage方法是不会生效的。处理请求和响应包的插件，这个应该是必要的\n\t}\n\n\t@Override\n\tpublic void processHttpMessage(int toolFlag,boolean messageIsRequest,IHttpRequestResponse messageInfo)\n\t{\n\t\tif (toolFlag == IBurpExtenderCallbacks.TOOL_PROXY){\n\t\t\t//不同的toolFlag代表了不同的burp组件 https://portswigger.net/burp/extender/api/constant-values.html#burp.IBurpExtenderCallbacks\n\t\t\tif (messageIsRequest){ //对请求包进行处理\n\t\t\t\tIRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo); \n\t\t\t\t//对消息体进行解析,messageInfo是整个HTTP请求和响应消息体的总和，各种HTTP相关信息的获取都来自于它，HTTP流量的修改都是围绕它进行的。\n\t\t\t\t\n\t\t\t\t/*****************获取参数**********************/\n\t\t\t\tList\u003cIParameter\u003e paraList = analyzeRequest.getParameters();\n\t\t\t\t//获取参数的方法\n\t\t\t\t//当body是json格式的时候，这个方法也可以正常获取到键值对；但是PARAM_JSON等格式不能通过updateParameter方法来更新。\n\t\t\t\t//如果在url中的参数的值是 key=json格式的字符串 这种形式的时候，getParameters应该是无法获取到最底层的键值对的。\n\n\t\t\t\tfor (IParameter para : paraList){// 循环获取参数，判断类型，进行加密处理后，再构造新的参数，合并到新的请求包中。\n\t\t\t\t\tString key = para.getName(); //获取参数的名称\n\t\t\t\t\tString value = para.getValue(); //获取参数的值\n\t\t\t\t\tint type = para.getType();\n\t\t\t\t\tstdout.println(\"参数 key value type: \"+key+\" \"+value+\" \"+type);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t/*****************修改并更新参数**********************/\n\t\t\t\tIParameter newPara = helpers.buildParameter(\"testKey\", \"testValue\", IParameter.PARAM_BODY); //构造新的参数\n\t\t\t\tbyte[] new_Request = messageInfo.getRequest();\n\t\t\t\tnew_Request = helpers.updateParameter(new_Request, newPara); //构造新的请求包\n\t\t\t\tmessageInfo.setRequest(new_Request);//设置最终新的请求包\n\t\t\t\t\n\t\t\t\t/*****************删除参数**********************/\n\t\t\t\tfor (IParameter para : paraList){// 循环获取参数，判断类型，进行加密处理后，再构造新的参数，合并到新的请求包中。\n\t\t\t\t\tString key = para.getName(); //获取参数的名称\n\t\t\t\t\tif (key.equals(\"aaa\")) {\n\t\t\t\t\t\tnew_Request = helpers.removeParameter(new_Request, para); //构造新的请求包\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\n\t\t\t\t/*****************获取header**********************/\n\t\t\t\tList\u003cString\u003e headers = analyzeRequest.getHeaders();\n\n\t\t\t\tfor (String header : headers){// 循环获取参数，判断类型，进行加密处理后，再构造新的参数，合并到新的请求包中。\n\t\t\t\t\tstdout.println(\"header \"+header);\n\t\t\t\t\tif (header.startsWith(\"referer\")) {\n\t\t\t\t/*****************删除header**********************/\n\t\t\t\t\t\theaders.remove(header);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t/*****************新增header**********************/\n\t\t\t\theaders.add(\"myheader: balalbala\");\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t/*****************获取body 方法一**********************/\n\t\t\t\tint bodyOffset = analyzeRequest.getBodyOffset();\n\t\t\t\tbyte[] byte_Request = messageInfo.getRequest();\n\t\t\t\t\n\t\t\t\tString request = new String(byte_Request); //byte[] to String\n\t\t\t\tString body = request.substring(bodyOffset);\n\t\t\t\tbyte[] byte_body = body.getBytes();  //String to byte[]\n\t\t\t\t\n\t\t\t\t/*****************获取body 方法二**********************/\n\t\t\t\t\n\t\t\t\tint len = byte_Request.length;\n\t\t\t\tbyte[] byte_body1 = Arrays.copyOfRange(byte_Request, bodyOffset, len);\n\t\t\t\t\n\t\t\t\tnew_Request = helpers.buildHttpMessage(headers, byte_body); \n\t\t\t\t//如果修改了header或者数修改了body，不能通过updateParameter，使用这个方法。\n\t\t\t\tmessageInfo.setRequest(new_Request);//设置最终新的请求包\n\t\t\t}\n\t\t}\n\t\telse{//处理响应包\n\t\t\tIResponseInfo analyzedResponse = helpers.analyzeResponse(messageInfo.getResponse()); //getResponse获得的是字节序列\n\t\t\tshort statusCode = analyzedResponse.getStatusCode();\n\t\t\tList\u003cString\u003e headers = analyzedResponse.getHeaders();\n\t\t\tString resp = new String(messageInfo.getResponse());\n\t\t\tint bodyOffset = analyzedResponse.getBodyOffset();//响应包是没有参数的概念的，大多需要修改的内容都在body中\n\t\t\tString body = resp.substring(bodyOffset);\n\n\t\t\tif (statusCode==200){\n\t\t\t\tString newBody= body+\"\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\u0026\";\n\t\t\t\tbyte[] bodybyte = newBody.getBytes();\n\t\t\t\tmessageInfo.setResponse(helpers.buildHttpMessage(headers, bodybyte));\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n\n\n### IContextMenuFactory\n\n![image-20211220215113980](https://gitee.com/safe6/img/raw/master/image-20211220215113980.png)\n\n用途：注册右键菜单，必须实现createMenuItems方法。\n\n如下创建菜单，添加点击事件\n\n```java\n@Override\n\tpublic List\u003cJMenuItem\u003e createMenuItems(IContextMenuInvocation invocation) {\n\t\t\n\t\tArrayList\u003cJMenuItem\u003e menu_item_list = new ArrayList\u003cJMenuItem\u003e();\n\n\t\t//常用\n\t\tJMenuItem printEmails = new JMenuItem(\"Print Emails\");\n\t\tprintEmails.addActionListener(new printEmails(invocation));\n\t\tmenu_item_list.add(printEmails);\n\n\t\tJMenuItem printCookie = new JMenuItem(\"find last cookie of Url\");\n\t\tprintCookie.addActionListener(new printCookies(invocation));\n\t\tmenu_item_list.add(printCookie);\n\n\t\tJMenuItem scan = new JMenuItem(\"scan this url\");\n\t\tscan.addActionListener(new printCookies(invocation));\n\t\tmenu_item_list.add(scan);\n\t\t\n\t\treturn menu_item_list;\n\n\t}\n```\n\n\n\n- 鼠标右键的创建\n- 从Scanner issues中收集邮箱地址\n- 从Proxy history中查找最新cookie\n- 发起扫描任务、发起爬行任务\n- 查询和更新scope\n\n```java\npackage burp;\n\nimport java.awt.MenuItem;\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\nimport java.io.PrintWriter;\nimport java.lang.reflect.Array;\nimport java.net.URL;\nimport java.net.URLDecoder;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport javax.swing.JMenuItem;\n\n\npublic class BurpExtender implements IBurpExtender, IContextMenuFactory\n{//所有burp插件都必须实现IBurpExtender接口，而且实现的类必须叫做BurpExtender\n\tprivate IBurpExtenderCallbacks callbacks;\n\tprivate IExtensionHelpers helpers;\n\n\tprivate PrintWriter stdout;\n\tprivate PrintWriter stderr;\n\tprivate String ExtenderName = \"burp extender api drops by bit4woo\";\n\n\t@Override\n\tpublic void registerExtenderCallbacks(IBurpExtenderCallbacks callbacks)\n\t{//IBurpExtender必须实现的方法\n\t\tstdout = new PrintWriter(callbacks.getStdout(), true);\n\t\tstderr = new PrintWriter(callbacks.getStderr(), true);\n\t\tcallbacks.printOutput(ExtenderName);\n\t\t//stdout.println(ExtenderName);\n\t\tthis.callbacks = callbacks;\n\t\thelpers = callbacks.getHelpers();\n\t\tcallbacks.setExtensionName(ExtenderName); \n\t\tcallbacks.registerContextMenuFactory(this);\n\t}\n\n\t@Override\n\tpublic List\u003cJMenuItem\u003e createMenuItems(IContextMenuInvocation invocation) {\n\t\t\n\t\tArrayList\u003cJMenuItem\u003e menu_item_list = new ArrayList\u003cJMenuItem\u003e();\n\n\t\t//常用\n\t\tJMenuItem printEmails = new JMenuItem(\"Print Emails\");\n\t\tprintEmails.addActionListener(new printEmails(invocation));\n\t\tmenu_item_list.add(printEmails);\n\n\t\tJMenuItem printCookie = new JMenuItem(\"find last cookie of Url\");\n\t\tprintCookie.addActionListener(new printCookies(invocation));\n\t\tmenu_item_list.add(printCookie);\n\n\t\tJMenuItem scan = new JMenuItem(\"scan this url\");\n\t\tscan.addActionListener(new printCookies(invocation));\n\t\tmenu_item_list.add(scan);\n\t\t\n\t\treturn menu_item_list;\n\n\t}\n\t\n\tpublic class printEmails implements ActionListener{\n\t\tprivate IContextMenuInvocation invocation;\n\n\t\tpublic printEmails(IContextMenuInvocation invocation) {\n\t\t\tthis.invocation  = invocation;\n\t\t}\n\t\t\n\t\t@Override\n\t\tpublic void actionPerformed(ActionEvent event) {\n\t\t\tIScanIssue[]  issues =  callbacks.getScanIssues(null);\n\n\t\t\tfinal String REGEX_EMAIL = \"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\\\.[a-zA-Z0-9-.]+\";\n\t\t\tPattern pDomainNameOnly = Pattern.compile(REGEX_EMAIL);\n\n\t\t\tfor (IScanIssue issue:issues) {\n\t\t\t\tif (issue.getIssueName().equalsIgnoreCase(\"Email addresses disclosed\")) {\n\t\t\t\t\tString detail = issue.getIssueDetail();\n\t\t\t\t\tMatcher matcher = pDomainNameOnly.matcher(detail);\n\t\t\t\t\twhile (matcher.find()) {//多次查找\n\t\t\t\t\t\tString email = matcher.group();\n\t\t\t\t\t\tSystem.out.println(matcher.group());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic class printCookies implements ActionListener{\n\t\tprivate IContextMenuInvocation invocation;\n\n\t\tpublic printCookies(IContextMenuInvocation invocation) {\n\t\t\tthis.invocation  = invocation;\n\t\t}\n\t\t\n\t\t@Override\n\t\tpublic void actionPerformed(ActionEvent event) {\n\t\t\ttry {\n\t\t\t\tIHttpRequestResponse[] messages = invocation.getSelectedMessages();\n\t\t\t\tbyte[] req = messages[0].getRequest();\n\t\t\t\tString currentShortUrl = messages[0].getHttpService().toString();\n\t\t\t\tstdout.println(currentShortUrl);\n\t\t\t\t\n\t\t\t\t/*******************从Proxy history中查找最新cookie***************************/\n\t\t        IHttpRequestResponse[]  historyMessages = callbacks.getProxyHistory();\n\t\t        int len =  historyMessages.length;\n\t\t        for (int index=len; index \u003e=0; index--) {\n\t\t        \tIHttpRequestResponse item = historyMessages[index];\n\t\t        \t\n\t\t            String hisShortUrl = item.getHttpService().toString();\n\t\t            if (currentShortUrl.equals(hisShortUrl)) {\n\t\t\t            IRequestInfo hisanalyzedRequest = helpers.analyzeRequest(item);\n\t\t\t            List\u003cString\u003e headers = hisanalyzedRequest.getHeaders();\n\n\t\t\t            for (String header:headers) {\n\t\t\t            \tif (header.startsWith(\"Cookie:\")) {\n\t\t\t            \t\tstdout.println(\"找到cookie---\"+header);\n\t\t\t            \t}\n\t\t\t            }\n\t\t            }\n\t\t        }\n\t\t\t} catch (Exception e) {\n\t\t\t\tcallbacks.printError(e.getMessage());\n\t\t\t}\n\t\t}\n\t}\n\t\n\tpublic class scan implements ActionListener{\n\t\tprivate IContextMenuInvocation invocation;\n\n\t\tpublic scan(IContextMenuInvocation invocation) {\n\t\t\tthis.invocation  = invocation;\n\t\t}\n\t\t\n\t\t@Override\n\t\tpublic void actionPerformed(ActionEvent event) {\n\t\t\ttry {\n\t\t\t\tIHttpRequestResponse[] messages = invocation.getSelectedMessages();\n\t\t\t\tfor (IHttpRequestResponse message:messages) {\n\t\t\t\t\tbyte[] req = message.getRequest();\n\t\t\t\t\tIRequestInfo analyzedRequest = helpers.analyzeRequest(req);\n\t\t\t\t\tURL url = analyzedRequest.getUrl();\n\t\t\t\t\tIHttpService service = message.getHttpService();\n\t\t\t\t\tboolean useHttps = service.getProtocol().equalsIgnoreCase(\"https\");\n\t\t\t\t\t/******************发起扫描任务************************/\n\t\t\t\t\tcallbacks.doActiveScan(service.getHost(), service.getPort(), useHttps, req);\n\t\t\t\t\tstdout.println(url.toString()+\"被加入了扫描队列\");\n\t\t\t\t\t/******************发起爬行任务************************/\n\t\t\t\t\tcallbacks.sendToSpider(url);\n\t\t\t\t\t\n\t\t\t\t\t/******************查询URL是否在scope中************************/\n\t\t\t\t\tif (callbacks.isInScope(url)) {\n\t\t\t\t\t\t/******************从scope中移除************************/\n\t\t\t\t\t\tcallbacks.excludeFromScope(url);\n\t\t\t\t\t}\n\t\t\t\t\tURL shortUrl = new URL(service.toString());\n\t\t\t\t\t/******************加入scope中************************/\n\t\t\t\t\tcallbacks.includeInScope(shortUrl);\n\t\t\t\t}\n\t\t\t} catch (Exception e) {\n\t\t\t\tcallbacks.printError(e.getMessage());\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n### IMessageEditorTab\n\n用途：有点像repeater模块，主要就是用来展示和编辑request和response。\n\n\n\n\n\n```java\n//添加一个editor，用于显示HTTP数据包\n\t\tIMessageEditor editor = BurpExtender.getCallbacks().createMessageEditor(this, false);\n\t\tcontentPane.add(editor.getComponent(), BorderLayout.CENTER);\n\t\t\n\t\t\tJButton btnNewButton = new JButton(\"displayRequest\");\n\t\tbtnNewButton.addActionListener(new ActionListener() {\n\t\t\tpublic void actionPerformed(ActionEvent e) {\n\t\t\t\teditor.setMessage(getRequest(), true);//调用IMessageEditorController的函数来显示请求包\n\t\t\t}\n\t\t});\n```\n\n\n\n```java\n public Tags(final IBurpExtenderCallbacks callbacks, String name) {\n        this.callbacks = callbacks;\n        this.tagName = name;\n\n        SwingUtilities.invokeLater(new Runnable() {\n\n\n            @Override\n            public void run() {\n\n\n                jPanel = new JPanel();\n\n               splitPanel = new JSplitPane(0);\n                splitPanel.setDividerLocation(0.5D);\n                jTabbedPane = new JTabbedPane();\n                jTabbedPane1 = new JTabbedPane();\n                request  = callbacks.createMessageEditor(Tags.this, false);\n                response = callbacks.createMessageEditor(Tags.this,false);\n                jTabbedPane.addTab(\"Request\",request.getComponent());\n                jTabbedPane.addTab(\"Response\",response.getComponent());\n                splitPanel.add(jTabbedPane);\n                splitPanel.setTopComponent(jTabbedPane1);\n                splitPanel.setBottomComponent(jTabbedPane);\n                jPanel.add(splitPanel);\n\n//                // 设置自定义组件并添加标签\n                callbacks.customizeUiComponent(jPanel);//根据Burp的UI样式自定义UI组件，包括字体大小、颜色、表格行距等。\n                callbacks.addSuiteTab(Tags.this);\n\n            }\n        });\n    }\n```\n\n\n\n### IBurpCollaboratorClientContext\n\n如何与burp自生DNSlog进行交互\n\n```java\nIBurpCollaboratorClientContext ccc = callbacks.createBurpCollaboratorClientContext();\n\n//返回结果类似：053bsqoev8gezev8oq59zylgv71xpm, 053bsqoev8gezev8oq59zylgv71xpm.burpcollaborator.net\npublic static String[] getFullDnsDomain(){\n    String subdomain = ccc.generatePayload(false);\n    String interactionID = subdomain;\n    String server = ccc.getCollaboratorServerLocation();\n    String fullPayload = subdomain+\".\"+server;\n    String[] result = {interactionID,fullPayload};\n    return result;\n}\n```\n\n\n\n\n\n## 插件解析\n\n解析P喵呜大佬写的，shiro被动扫描插件。\n\n前提：了解shiro反序列化漏洞原理，了解burp插件开发。\n\n\n\nhttps://github.com/pmiaowu/BurpShiroPassiveScan.git\n\n\n\n找到入口类开始看，发现继承了IScannerCheck。\n\nIScannerCheck和IHttpListener有点相似，简单说下我理解的区别，如有不对欢迎指出。\n\nIHttpListener有点像proxy抓包拦截，能在收到某某request或者response就马上进行处理。而IScannerCheck则是发现你请求了某某url之后，单独对这个url进行漏洞扫描。\n\n![image-20211226144135012](https://gitee.com/safe6/img/raw/master/image-20211226144135012.png)\n\n\n\n先看关键注册方法，主要是一些初始化操作\n\n![image-20211226144243446](https://gitee.com/safe6/img/raw/master/image-20211226144243446.png)\n\n\n\n初始化关键对象\n\n![image-20211226144619862](https://gitee.com/safe6/img/raw/master/image-20211226144619862.png)\n\n初始化两个用于存放扫描url和domain的对象\n\n![image-20211226144729787](https://gitee.com/safe6/img/raw/master/image-20211226144729787.png)\n\n这两个对象主要是用了单例各种维护一个了map\n\n![](https://gitee.com/safe6/img/raw/master/image-20211226145014584.png)\n\n\n\n初始化插件界面，设置插件名称，注册扫描，打印一些作者信息。\n\n![image-20211226145255622](https://gitee.com/safe6/img/raw/master/image-20211226145255622.png)\n\n\n\n看看插件界面代码，就是表格加req和res\n\n![](https://gitee.com/safe6/img/raw/master/image-20211226151549825.png)\n\n\n\n接下来看，被动扫描。核心代码都在这。\n\n![image-20211226152831719](https://gitee.com/safe6/img/raw/master/image-20211226152831719.png)\n\n先判断域名有没有被扫描过\n\n![image-20211226153017814](https://gitee.com/safe6/img/raw/master/image-20211226153017814.png)\n\n再检测url有没有被扫描过（此处有重复代码的感觉，离谱）\n\n![image-20211226153117727](https://gitee.com/safe6/img/raw/master/image-20211226153117727.png)\n\n\n\n都没有扫描过，则加到前面初始化的map里面去。(大佬居然管这个叫数组，有点离谱，问题不大)\n\n![image-20211226153559483](https://gitee.com/safe6/img/raw/master/image-20211226153559483.png)\n\n\n\n开始核心的各种检测\n\n![image-20211226155021186](https://gitee.com/safe6/img/raw/master/image-20211226155021186.png)\n\n\n\n后面就是一些添加issues，爆破key什么的，不想看了。\n\n突然发现写这种东西，对我完全没任何好处。而且还及其浪费时间，疯狂截图，各种写。\n\n\n\n## 致谢\n\n感谢大佬开源，向大佬致敬。\n\n- https://github.com/bit4woo/burp-api-drops\n- https://xz.aliyun.com/t/7065\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsafe6sec%2Fburpdevnote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsafe6sec%2Fburpdevnote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsafe6sec%2Fburpdevnote/lists"}