Home > Article > Operation and Maintenance > Detailed explanation of some problems encountered in developing passive scanner plug-ins
Chrome Plug-ins
Chrome plug-ins are browser extensions that add or modify functionality to the Chrome browser. Generally, Chrome plug-ins can be written through JavaScript, HTML and CSS. There are many excellent Chrome extensions on the market with many users. Writing Chrome plug-ins is also relatively simple. Basically, if you are familiar with some front-end knowledge and then become familiar with the API of Chrome plug-ins, you can write Chrome plug-ins.
To install the Chrome plug-in, if you have not published it in the Chrome store (due to network reasons, you may not be able to download it directly from the store), you can install the Chrome plug-in through developer mode. Or you can sign up for a Chrome plug-in developer account (for only $5, you can publish 20 plug-ins).
A brief introduction to the development of Chrome plug-ins. Let’s mainly talk about the passive scanner aspects of Chrome plug-ins. For Chrome plug-ins, it is mainly through the plug-in's ability to obtain traffic passing through the browser and forward the traffic to the backend for processing.
There are two main APIs for Chrome plug-in to process network traffic: chrome.devtools.network and chrome.webRequest. However, when using the former, you need to open the Chrome developer tools, which is a bit inconvenient, so I chose the latter, which is also a common way to obtain passive traffic.
The webrequest API in the Chrome plug-in is driven by corresponding events. The life cycle diagram of the request is as follows, with 7 main events. You only need to listen for key events and process them to meet the needs of passive scanners to obtain traffic.
In fact, these events are not difficult to understand. Basically, you can know the meaning of the event through the name of the event, mainly before sending the request, before sending the request header, sending the request header, etc. event. For different events, the traffic data that can be obtained is also different.
First, consider what traffic data is more important to passive scanners. Passive scanners mainly conduct testing by collecting normal business traffic, improving the efficiency of testing and achieving better results than active scanners. Generally speaking, what passive scanners care about most is the requested URL and request headers. If it is a POST request, the request body is also required. For the scanner, the response header and response body are not that important. In fact, it can be filtered by the response status. Generally, only the request header and request body that can respond normally are needed.
For the above requirements of passive scanners, the two events onBeforeRequest and onSendHeaders in chrome.webrequest can meet the requirements. Through the former, the request body can be obtained. Through the latter, the request header can be obtained. However, there are several points to note when using onSendHeaders:
Compatibility issues
Starting from Chrome 79, extraHeaders must be specified in opt_extraInfoSpec to obtain the Origin request head. Starting from Chrome 72, extraHeaders must be specified in opt_extraInfoSpec to obtain the following request headers:
Accept-Language
Accept-Encoding
Referer
Cookie
There is no doubt that these request headers are valuable. In order to obtain these request headers, you must specify extraHeaders in opt_extraInfoSpec to obtain the corresponding request headers. At the same time, pay attention to compatibility checks, because previous versions do not need to be specified. If you also specify attributes in previous versions of the browser, an error will occur.
const headers = version >= 72 ? ["requestHeaders", "extraHeaders"] : ["requestHeaders"]; chrome.webRequest.onSendHeaders.addListener( beforeSendHeaderHandler, requestFilters, headers )
requestBody format issue
The request body in the POST request can be obtained through the onBeforeRequest event. But one thing to note is that the request body is parsed in chrome.webrequest, so what you get is not the native request body. The request body is located in fromData in requestBody, and formData actually has two forms. One is a dictionary in the form of key-value pairs. This type of request body is generally multipart/form-data or application/x-www-form-urlencoded. Generally speaking, it is generally in the form of a=xxx&b=xxx&c=xxx; the other is native bytes. This official API document does not mention it directly. You need to manually parse the data yourself.
const postbody = decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(details.requestBody.raw[0].bytes)));
Use RequestFilter to filter requests
如果你希望在事件中可以过滤特定的请求地址或者请求的资源类型,那么就可能需要使用到 RequestFilter 了。RequestFilter 里面有4个属性,比较重要的属性就是 urls 以及 types,通过这两个属性就可以过滤特定的请求 URL 以及资源类型。
但是注意一点是,RequestFilter 是在注册事件的时候配置的参数的,不可以后续直接修改。不过有一种方法是先移除监听事件,再添加新的事件。
if (!chrome.webRequest.onSendHeaders.hasListener(beforeSendHeaderHandler)) { chrome.webRequest.onSendHeaders.addListener( beforeSendHeaderHandler, requestFilters, headers ) }
Burp 插件篇
Burp 是渗透测试中不可缺少的工具之一,而 Burp 插件也让测试者如虎添翼,达到事半功倍的效果。同时,开发 Burp 插件也是为了弥补一些系统无法在 Chrome 中使用的场景来进一步地补充。
Burp 插件开发的资料网上不是特别的丰富,之前也写过一篇文章“如何写一个 Burp 插件”。其实开发 Burp 插件比较简单,只要遵守基本的规范,然后学习一下 API 的使用,基本就可以完成 Burp 插件的开发了。反倒是如果希望在 Burp 插件中开发 GUI 有点困难,因为使用 J**A 来写 GUI 比较麻烦,毕竟不能像 C# 那样,妥妥拽拽就搞定了,不过这也不是本文的重点。
其实在 Burp 中的 Extender 标签页中的 APIs 就可以看到提供的 API 接口。基本上每个函数都有参数说明的注释,不过其实学习 Burp 插件的最好的方法就是拿一个现成的插件代码看一下,就可以很好地理解这些 API 的作用了。
public interface IHttpListener{ /** * This method is invoked when an HTTP request is about to be issued, and * when an HTTP response has been received. * * @param toolFlag A flag indicating the Burp tool that issued the request. * Burp tool flags are defined in the * <code>IBurpExtenderCallbacks</code> interface. * @param messageIsRequest Flags whether the method is being invoked for a * request or response. * @param messageInfo Details of the request / response to be processed. * Extensions can call the setter methods on this object to update the * current message and so modify Burp's behavior. */ void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo); }
在这,以我开发的 Burp 插件 r-forwarder-burp 为例,使用 J**A 开发。在开发 Burp 插件需要注意几点。必须定义一个 BurpExtender 类,并且必须实现 IBurpExtender,如果还需要其他 API 可以实现多个其它接口,J**A 中的类是可以实现多个接口的。另外还需要重写父类中的 registerExtenderCallbacks 方法。同样,针对被动扫描器的需求,在 Burp 插件中我们最主要涉及的接口是 IHttpListener 接口。这个主要涉及到 HTTP
在 processHttpMessage 方法中,主要涉及到以上3个参数。toolFlag 主要指的是和请求相关的 Burp 工具,比如 Proxy 以及 Repeater。可以在 IBurpExtenderCallbacks 接口中看到相应的定义。
messageIsRequest 则表示是请求还是响应,而我们只关心请求部分。通过解析 messageInfo 则可以获取请求头以及请求体数据。
public Map<String, String> getHeaders(IHttpRequestResponse messageInfo) { Map<String, String> headers = new HashMap<>(); IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo); List<String> h = analyzeRequest.getHeaders(); for (String h1: h) { if (h1.startsWith("GET") || h1.startsWith("POST")) { continue; } else { String[] header = h1.split(":", 2); headers.put(header[0], header[1].trim()); } } return headers; } private String getBody(IHttpRequestResponse messageInfo) { IRequestInfo requestInfo = helpers.analyzeRequest(messageInfo); int bodyOffset = requestInfo.getBodyOffset(); byte[] byteRequest = messageInfo.getRequest(); byte[] byteBody = Arrays.copyOfRange(byteRequest, bodyOffset, byteRequest.length); return new String(byteBody); }
上面是简单开发的内容方面的介绍,其它方面可以直接看源代码了解更多,尤其是 GUI 开发的部分。另外想说明的一点就是如何打 jar 包。通过 maven-assembly-plugin 插件可以很方便地打包,只需要配置如下,然后通过 mvn package 即可进行打包。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration></plugin>
另外注意如果使用了外部依赖的时候,需要配置 jar-with-dependencies,这样在打包的时候就可以把依赖的 jar 包一并打进去。最后,成品的 jar 包安装之后就可以使用了。
其实,我认为在 Burp 插件开发过程中最重要的部分就是调试了。通过调试可以快速提高开发效率。以 IDE IDEA 为例,只需要以下几步就可以进行插件开发地调试:
1.配置 debug 配置项,点击 IDE 右上角就可以新增配置项。
在终端中通过上述的配置项启动 burp 插件。
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar burpsuite_community_v2.1.0.jar
2.在 Burp 中通过上面的方式安装打包好的插件。
3.在 IDE 中相应的代码打上断点,并打开 debug 就可以进行调试了。
总结
以上就是在开发被动扫描器 Chrome 插件以及 Burp 插件遇到的一些坑,在这里和大家分享一下。其实被动扫描器开发,最重要的还是一些细节方面的考虑,可以将插件的功能做到更完美。
相关文章教程推荐:web服务器安全教程
The above is the detailed content of Detailed explanation of some problems encountered in developing passive scanner plug-ins. For more information, please follow other related articles on the PHP Chinese website!