0

0

关于开发被动扫描器插件遇到的一些问题的详解

王林

王林

发布时间:2019-12-09 13:15:01

|

2882人浏览过

|

来源于freebuf

转载

关于开发被动扫描器插件遇到的一些问题的详解

Chrome 插件

chrome 插件是向 chrome 浏览器添加或修改功能的浏览器拓展程序。一般通过 javascript, html 以及 css 就可以编写 chrome 插件了。市面上有很多非常优秀的 chrome 插件拥有非常多的用户。chrome 插件的编写也比较简单,基本上你熟悉一点前端知识,然后熟悉一下 chrome 插件的 api,你就可以编写 chrome 插件。

Chrome 插件的安装,如果你没有发布在 Chrome 商店的话(因为网络原因,可能没办法直接从商店下载),可以通过开发者模式安装 Chrome 插件。或者你也可以注册 Chrome 插件的开发者账号(只需要 5 美元,就可以发布 20 个插件)。

简单地介绍了一下 Chrome 插件的开发,咱们主要还是聊一下关于 Chrome 插件关于被动扫描器的方面的内容。对于 Chrome 插件,主要是通过插件的能力去获取经过浏览器的流量,并将流量转发给后端来进行处理。

Chrome 插件关于网络流量的处理地 API 主要有两个:chrome.devtools.network 以及 chrome.webRequest。但是前者使用的时候需要打开 Chrome 开发者工具,这个有一点不太方面,所以选择了后者,这也是对于被动流量获取一种常见的方式。

Chrome 插件中的 webrequest API 是以相应的事件驱动的,其中请求的生命周期图如下,主要有7个事件。只需要监听关键事件进行处理就可以满足被动扫描器获取流量的需求了。

12.png

其实这些事件不难理解,基本通过事件的名称就可以知道事件的含义了,主要就是请求发送前,发送请求头之前,发送请求头等等事件。对于不同的事件,可以获取的流量数据也是不尽相同的。

首先,考虑一下,对于被动扫描器来说,哪些流量数据是比较关心的。被动扫描器主要是通过收集业务的正常流量来进行测试,提高测试的效率,并能取得比主动扫描器更好的效果。那么一般来说,被动扫描器最关心的就是请求的 URL 以及请求头了,如果是 POST 请求,还需要请求体。对于扫描器来说,响应头和响应体则没那么重要,其实可以通过响应状态过滤一下,一般只需要能够正常响应的请求头以及请求体即可。

对于被动扫描器上述的需求,chrome.webrequest 中的 onBeforeRequest 以及 onSendHeaders 这两个事件可以满足需求。通过前者,可以获取请求体。通过后者则可以获取请求头。不过在使用 onSendHeaders 的时候,有好几点需要注意:

兼容问题

从 Chrome 79 开始,必须要在 opt_extraInfoSpec 中指定 extraHeaders 才可以获取 Origin 请求头。从 Chrome 72 开始,必须要在 opt_extraInfoSpec 中指定 extraHeaders 才可以获取 以下请求头:

Accept-Language

Accept-Encoding

Referer

Cookie

毫无疑问,这些请求头都是有价值的。为了获取这些请求头,你必须在 opt_extraInfoSpec 中指定 extraHeaders 才可以获取相应的请求头。同时,注意做兼容性检查,因为之前的版本的是不需要指定的,如果你在之前版本的浏览器也指定了属性,就会产生报错。

const headers = version >= 72 ? ["requestHeaders", "extraHeaders"] : ["requestHeaders"];
chrome.webRequest.onSendHeaders.addListener(
beforeSendHeaderHandler, requestFilters, headers
)

requestBody 的格式问题

可以通过 onBeforeRequest 事件来获取 POST 请求中的请求体。但有一点注意,chrome.webrequest 中把请求体进行了解析,所以你获取的不是原生的请求体。请求体位于 requestBody 中的 fromData,而 formData 其实是有两种形式,一种是键值对形式的字典,这种一般对于请求体类型为 multipart/form-data 或者 application/x-www-form-urlencoded 而言,一般即为 a=xxx&b=xxx&c=xxx 这种形式;另外一种则是原生的字节,这个官方的 API 文档没有直接提到,你需要自己手工解析数据。

const postbody = decodeURIComponent(String.fromCharCode.apply(null,                                      
new Uint8Array(details.requestBody.raw[0].bytes)));

使用 RequestFilter 去过滤请求

如果你希望在事件中可以过滤特定的请求地址或者请求的资源类型,那么就可能需要使用到 RequestFilter 了。RequestFilter 里面有4个属性,比较重要的属性就是 urls 以及 types,通过这两个属性就可以过滤特定的请求 URL 以及资源类型。

但是注意一点是,RequestFilter 是在注册事件的时候配置的参数的,不可以后续直接修改。不过有一种方法是先移除监听事件,再添加新的事件。

if (!chrome.webRequest.onSendHeaders.hasListener(beforeSendHeaderHandler)) {
  chrome.webRequest.onSendHeaders.addListener(
    beforeSendHeaderHandler, requestFilters, headers
  )
}

Burp 插件篇

奇布塔
奇布塔

基于AI生成技术的一站式有声绘本创作平台

下载

Burp 是渗透测试中不可缺少的工具之一,而 Burp 插件也让测试者如虎添翼,达到事半功倍的效果。同时,开发 Burp 插件也是为了弥补一些系统无法在 Chrome 中使用的场景来进一步地补充。

Burp 插件开发的资料网上不是特别的丰富,之前也写过一篇文章“如何写一个 Burp 插件”。其实开发 Burp 插件比较简单,只要遵守基本的规范,然后学习一下 API 的使用,基本就可以完成 Burp 插件的开发了。反倒是如果希望在 Burp 插件中开发 GUI 有点困难,因为使用 J**A 来写 GUI 比较麻烦,毕竟不能像 C# 那样,妥妥拽拽就搞定了,不过这也不是本文的重点。

其实在 Burp 中的 Extender 标签页中的 APIs 就可以看到提供的 API 接口。基本上每个函数都有参数说明的注释,不过其实学习 Burp 插件的最好的方法就是拿一个现成的插件代码看一下,就可以很好地理解这些 API 的作用了。

13.png

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
     * IBurpExtenderCallbacks 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 接口中看到相应的定义。

cff69840f4e1a1811d817ad58e6c975.png

messageIsRequest 则表示是请求还是响应,而我们只关心请求部分。通过解析 messageInfo 则可以获取请求头以及请求体数据。

public Map getHeaders(IHttpRequestResponse messageInfo) {    
Map headers = new HashMap<>();
    IRequestInfo analyzeRequest = helpers.analyzeRequest(messageInfo);
    List 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 即可进行打包。


    org.apache.maven.plugins
    maven-assembly-plugin
    
        
            package
            
                single
            
        
    
    
        
            jar-with-dependencies
        
    

另外注意如果使用了外部依赖的时候,需要配置 jar-with-dependencies,这样在打包的时候就可以把依赖的 jar 包一并打进去。最后,成品的 jar 包安装之后就可以使用了。

其实,我认为在 Burp 插件开发过程中最重要的部分就是调试了。通过调试可以快速提高开发效率。以 IDE IDEA 为例,只需要以下几步就可以进行插件开发地调试:

1.配置 debug 配置项,点击 IDE 右上角就可以新增配置项。

cab434a3349bdb3e0bd08f9ef81e8ef.png

在终端中通过上述的配置项启动 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服务器安全教程

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

557

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

395

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

756

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

478

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

474

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

1051

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

659

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

554

2023.09.20

菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

0

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.9万人学习

Django 教程
Django 教程

共28课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号