Maison > Article > Opération et maintenance > Explication détaillée de certains problèmes rencontrés lors du développement de plug-ins de scanner passif
Plug-ins Chrome
Les plug-ins Chrome sont des extensions de navigateur qui ajoutent ou modifient des fonctionnalités au navigateur Chrome. . Généralement, les plug-ins Chrome peuvent être écrits via JavaScript, HTML et CSS. Il existe de nombreuses excellentes extensions Chrome sur le marché avec de nombreux utilisateurs. L'écriture de plug-ins Chrome est également relativement simple, si vous maîtrisez certaines connaissances frontales et que vous vous familiarisez ensuite avec l'API des plug-ins Chrome, vous pouvez écrire des plug-ins Chrome.
Pour installer le plug-in Chrome, si vous ne l'avez pas publié dans le Chrome Store (pour des raisons de réseau, vous ne pourrez peut-être pas le télécharger directement depuis le Store), vous pouvez installer le plug-in Chrome -en mode développeur. Ou vous pouvez créer un compte de développeur de plug-ins Chrome (pour seulement 5 $, vous pouvez publier 20 plug-ins).
Une brève introduction au développement du plug-in Chrome Parlons principalement du scanner passif du plug-in Chrome. Pour les plug-ins Chrome, cela s'explique principalement par la capacité du plug-in à obtenir le trafic transitant par le navigateur et à le transmettre au backend pour traitement.
Le plug-in Chrome dispose principalement de deux API pour traiter le trafic réseau : chrome.devtools.network et chrome.webRequest. Cependant, lorsque vous utilisez le premier, vous devez ouvrir les outils de développement Chrome, ce qui est un peu gênant, j'ai donc choisi le second, qui est également un moyen courant d'obtenir du trafic passif.
L'API webrequest du plug-in Chrome est pilotée par les événements correspondants. Le diagramme du cycle de vie de la requête est le suivant, avec 7 événements principaux. Il vous suffit d'écouter les événements clés et de les traiter pour répondre aux besoins des scanners passifs pour obtenir du trafic.
En fait, ces événements ne sont pas difficiles à comprendre, en gros, vous pouvez connaître la signification de l'événement grâce au nom de l'événement, principalement avant d'envoyer la demande, avant. envoi de l'en-tête de requête, envoi de l'en-tête de requête, etc. Pour différents événements, les données de trafic pouvant être obtenues sont également différentes.
Tout d'abord, réfléchissez aux données de trafic qui préoccupent le plus un scanner passif. Les scanners passifs effectuent principalement des tests en collectant le trafic professionnel normal, améliorant ainsi l'efficacité des tests et obtenant de meilleurs résultats que les scanners actifs. De manière générale, ce qui importe le plus aux scanners passifs, ce sont l'URL demandée et les en-têtes de requête. S'il s'agit d'une requête POST, le corps de la requête est également requis. Pour le scanner, l'en-tête et le corps de la réponse ne sont pas si importants. En fait, ils peuvent être filtrés par l'état de la réponse. Généralement, seuls l'en-tête et le corps de la requête qui peuvent répondre normalement sont nécessaires.
Pour les exigences ci-dessus des scanners passifs, les deux événements onBeforeRequest et onSendHeaders dans chrome.webrequest peuvent répondre aux exigences. Grâce au premier, le corps de la demande peut être obtenu. Grâce à ce dernier, l'en-tête de la requête peut être obtenu. Cependant, il y a plusieurs points à noter lors de l'utilisation de onSendHeaders :
Problèmes de compatibilité
À partir de Chrome 79, extraHeaders doit être spécifié dans opt_extraInfoSpec pour obtenir l'en-tête de la requête Origin. À partir de Chrome 72, extraHeaders doit être spécifié dans opt_extraInfoSpec pour obtenir les en-têtes de requête suivants :
Accept-Language
Accept-Encoding
Referer
Cookie
Il ne fait aucun doute que ces en-têtes de requête sont précieux. Afin d'obtenir ces en-têtes de requête, vous devez spécifier extraHeaders dans opt_extraInfoSpec pour obtenir les en-têtes de requête correspondants. Dans le même temps, faites attention à la vérification de la compatibilité, car il n'est pas nécessaire de spécifier la version précédente. Si vous spécifiez également l'attribut dans la version précédente du navigateur, une erreur sera signalée.
const headers = version >= 72 ? ["requestHeaders", "extraHeaders"] : ["requestHeaders"]; chrome.webRequest.onSendHeaders.addListener( beforeSendHeaderHandler, requestFilters, headers )
Problème de format de requestBody
Le corps de la requête dans la requête POST peut être obtenu via l'événement onBeforeRequest. Mais une chose à noter est que le corps de la requête est analysé dans chrome.webrequest, donc ce que vous obtenez n'est pas le corps de la requête natif. Le corps de la requête se trouve dans fromData dans requestBody, et formData a en fait deux formes. L'une est un dictionnaire sous la forme de paires clé-valeur. Ce type de corps de requête est généralement multipart/form-data ou application/x-www-form. -urlencoded. De manière générale, il se présente généralement sous la forme de a=xxx&b=xxx&c=xxx ; ce document officiel de l'API ne le mentionne pas directement.
const postbody = decodeURIComponent(String.fromCharCode.apply(null, new Uint8Array(details.requestBody.raw[0].bytes)));
Utilisez RequestFilter pour filtrer les demandes
如果你希望在事件中可以过滤特定的请求地址或者请求的资源类型,那么就可能需要使用到 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服务器安全教程
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!