一款用于chrome的抓包重放插件。
项目地址: https://github.com/17307/ptTools
需求
原本是想在chrome上实现一个类似于Firefox的编辑重发顺便带点hackbar的插件。前端好难。体验了女朋友的webstorm,真好用!
在此记录下这个插件的风风雨雨。还是学到了一些知识的。
使用方式
F12打开后,选到pttools标签。
选择监听方式,感觉 Listen ALL的监听方式要废掉了。
选择view即可修改HTTP请求。对于POST的HTTP请求,可以添加body的参数。
下面截图和实际暂时不太一样,正在进行功能增加。
点击 Edit
编辑内容。
发送即可。
使用中的注意事项:
在进行POST的时候,将以application/x-www-form-urlencoded的类型添加参数。
如无特殊需求,请自行删除content-length的内容。
重放某些攻击不生效可能原因是请求了缓存,通常对于图片会发生这种情况。可以勾选Network选项卡种的Disable cache。
前置知识
chrome中request的生命周期
这些是官方文档的内容。https://developer.chrome.com/extensions/webRequest
插件流程
细节
与其说是细节,不如说是自己踩的坑。
插件中的CSP
由于我用了vue的框架,可是在使用过程中,一直受到了chrome插件的CSP策略的限制,无法引入vue的库。首先要在 manifest.json 中配置一下CSP的策略。(必须指定具体的URL)
1 | "content_security_policy": "style-src 'self' 'unsafe-inline' https://unpkg.com;script-src 'self' 'unsafe-eval' https://cdn.jsdelivr.net https://vuejs.org https://unpkg.com;object-src 'self' ;", |
三个监听函数
onBeforeRequest
请求即将发生时触发。此事件在进行任何TCP连接之前发送,可用于取消或重定向请求。官方文档说了它用于取消或重定向,就真的只能用于取消和重定向,天真的我一开始还想改动些东西。
1 | chrome.webRequest.onBeforeRequest.addListener(callback_beforeRequest, filter, extraInfoSpec); |
The webRequest.RequestFilter
filter
allows limiting the requests for which events are triggered in various dimensions:
- URLs
URL patterns such as
*://www.google.com/foo*bar
.
- Types
Request types such as
main_frame
(a document that is loaded for a top-level frame),sub_frame
(a document that is loaded for an embedded frame), andimage
(an image on a web site). See webRequest.RequestFilter.
- Tab ID
The identifier for one tab.
- Window ID
The identifier for a window.
onBeforeSendHeaders
即将发生请求并准备好初始标头时触发。该事件旨在允许扩展添加,修改和删除请求标头,也可以用于取消发送。
1 | chrome.webRequest.onBeforeSendHeaders.addListener(callback_onBeforeSendHeaders, filter, extraInfoSpec2); |
The following headers are currently not provided to the
onBeforeSendHeaders
event. This list is not guaranteed to be complete nor stable.
- Authorization
- Cache-Control
- Connection
- Content-Length
- Host
- If-Modified-Since
- If-None-Match
- If-Range
- Partial-Data
- Pragma
- Proxy-Authorization
- Proxy-Connection
- Transfer-Encoding
Starting from Chrome 72, the following request headers are not provided and cannot be modified or removed without specifying
'extraHeaders'
inopt_extraInfoSpec
:
- Accept-Language
- Accept-Encoding
- Referer
- Cookie
注意引用的第一条,一些请求头是无法通过 onBeforeSendHeaders获得的。但是,如果你在回调函数中添加了这些请求头,这个是可以生效的!
onSendHeaders
在所有扩展程序都有机会修改请求标头后触发,并显示最终版本。这个只能用于监听,而无法修改或者取消。所以这个是我的监听模块的主要信息来源。
1 | chrome.webRequest.onSendHeaders.addListener(callback_onsendheaders, filter, extraInfoSpec3); |
第四个监听函数
上面的三个监听函数,用于 ALL TAB下的监听。其实还有一个函数,但他不是监听函数,可以将他理解为获取chrome中network的记录。上面三个监听函数均用于 background.js 中,而这个监听只能用于 devtool 中。
chrome.devtools.network.onRequestFinished
https://developer.chrome.com/extensions/devtools_network
1 | function startListenCurrentTab() { |
这个模块只能获得当前审计tab的网络活动。
重放
关于重放的方法,在Hackbar中学到了很多。(学习插件最好的办法就是看别人的插件)
GET
对于GET,可以直接使用这个方法。感觉类似于 location
1 | chrome.tabs.update(tabid, {url: url}); |
POST
对于post,一开始还想用ajax,然而发现在添加某些请求头的时候,出现各种问题。而且,还无法将response显示到当前页面(即无法重放后,然浏览器当前页面跳转,不知道是不能这么做,还是我不会,请大佬指教下。)后来想到了注入js,实现一个表单。
看了hackbar后,发现原来还有这种函数:chrome.tabs.executeScript。这个函数文档就不放了。
1 | chrome.tabs.executeScript(tabid, {code: 'let post_data = "' + encodeURIComponent(post_data) + '"; let url = "' + encodeURIComponent(url) + '"'}, function () { |
在上面可以发现我调用了2次executeScript函数。第一次用于定义变量,传递变量到要执行的js。第二次用于执行js文件。
这里遇到的一个坑,无法直接传递 object 这种类型的变量,貌似只能传递 str 类型的(可能是我不会)。所以要先把变量序列号 JSON.stringify 。然后在 post_data.js 中再进行解析 JSON.parse() 。
再次监听
上面的GET或者POST都只是用来修改 请求参数的。而无法修改请求头,所以需要再次监听,以达到修改请求头。
1 | chrome.webRequest.onBeforeSendHeaders.addListener( |
(1) 这个是我当时测试baidu时候发生的。我修改了到 https://www.baidu.com的 user-agent。发现它回了一个 location(url.replace('https','http'))
。导致我当前页面又去访问了 http://www.baidu.com。可是我如果不修改这个请求的User-Agent。这个请求又会给我一个301,让我跳转到HTTPS的百度域名,于是二者疯狂循环。
(2) 如果我不做这个限定,就会导致每一个在当前tab下的请求,都回修改我上次修改的内容。
(3) 对于post表单的形式,必须指定 Content-Type 为 application/x-www-form-urlencoded 。否则后台无法正常解析。这里以后可以加上更多的格式,如 form-data,json等。
(4) 第四个坑上述代码没有表示出来,那就是 Content-Length,这个内容必须删除或者给正确的值,否则只能发送指定长度的内容。当然这是我逻辑的问题。
TO-DO
完善未知bug。[优先]
添加更多的POST的请求type。
修改HTTP请求后,无法保留原始请求。(对vue不熟悉,还没有找到解决办法)
current tab增加response预览功能。
等我学会前端,我就把它做的更酷炫。
目前写的第三个插件,而且是个业余爱好者,如有意见或建议,欢迎提出。