抓包,篡改数据和模拟发包,这几个任务在工作中非常常见。这里揉在一起讲述。
需要抓包的一些场景:
- 开发过程中,观察服务间 API 调用的包结构,便于开发、调试 bug
- 浏览器中研究网站 API
需要篡改数据的一些场景:
- 在浏览器上,想篡改 AJAX 请求返回的数据来影响界面的展示或者前端逻辑
- 篡改接口数据来影响 app 功能
- 开发过程中,用来修改特定的数据包以验证问题;Mock 数据以不等待别人配合等
需要模拟发包的一些场景:
- 在浏览器上,前端没有发送某个特定 API 请求的入口(如按钮、链接等),需要模拟发包来达到目的
- Ice 和娜娜有时需要去网上上一些课,看教学视频,而且被要求看满多少时间才可以。这些网站会在你看视频时定时发请求到服务器,纪录你看了多久。需要模拟发包来装作有看这些视频
思路
常规的数据流向,一般是:
发起请求
终端(手机 / PC) -----------> 代理 / 路由 ---------> 服务器
终端主要有网页浏览器和应用程序(PC 上的或者手机上的)。代理服务器可以架设在本地或者远端。
除了服务器、中间路由器这几环可能控制不了,其他部分是你可以控制的。你可以在终端或者代理服务器上做抓包、篡改数据。
在终端上
终端一般分成 PC 和手机。手机受限于操作便利性,一般只做抓包及展示,没有更高级的功能;Android 上常用 Package Capture, tPacketCapture。下面的内容仅针对 PC,按功能场景做分类。
抓包
电脑上可以用老牌抓包工具 Wireshark 来抓包。如果是在服务器上没有图形界面,可以用 tcpdump
命令先抓包保存成文件,再放到 Wireshark 上分析。也可以用本地代理来抓包,流行的有 mitmproxy、Charles 和 Fiddler。betwixt 提供了一个利用 Chrome DevTools 来分析数据包的工具,非常实用。
如果是在浏览器上,Chrome 的开发者工具是非常好用的。
篡改数据
窜改数据的工具,可以用 Charles / Fiddler 提供的 rewrite 能力。也可以用 mitmproxy 实现可编程的修改数据。它们都可以修改出站数据中的 request 和 response。
Charles / Fiddler 需要你的应用程序将其设为正向代理。mitmproxy 即支持正向代理,也支持反向代理和透明代理。
模拟发包
模拟发包的场景一般在浏览器上。对于非浏览器的请求,你可以 Postman 提供的代理先抓到包,再导出成 curl / Python 或者各语言代码。
对于浏览器上做模拟发包:
- 如果 JS 没有被混淆,可以直接看源码,找合适的切入点去用 JS 发请求。比如调用 JS 里面写好的函数。
- 有些网站不用 JS 发请求,而用 Flash 。这时候你不知道请求是如何被构造的,可以:
- 观察最终的 HTTP 请求包是怎样的,猜测字段含义并尝试构造类似请求
- 直接使用抓包工具,把 Flash 通过浏览器发出的包的内容修改了
- 有些网站直接用
<form>
来提交请求,可以修改<input>
的值,用 JS 或者直接 Chrome 开发者工具中修改
如果网站使用了 React / Vue.js 等 MVVM 框架,你没办法简单地动 JS / HTML 元素来达成模拟发包,可以这样:
- 安装 Postman Interceptor 及 Postman Chrome App。Postman 的单独 app 似乎不能连接 interceptor
- 打开 Interceptor 的拦截功能,Postman 上也点亮 interceptor
- 在 Chrome 开发者工具的 Network panel 中打勾 offline
- 此时在 Chrome 上发起的请求,并不会实际被发出,但是在 Postman 中可以看到(默认 History 中)。这时候你可以在 Postman 中修改请求体,再点发送
在代理 / 路由上
抓包
如果你给程序设置了远程代理服务器,而你又可以访问这台服务器,那你可以在这台服务器上用 tcpdump, httpry, hsiafan/httpdump 等进行抓包。
篡改数据
在路由 / 代理服务器上篡改数据,可以使终端无感知,比如手机上的 app。
mitmproxy, inaz2/proxy2, dahlia/wsgi-proxy 等工具可以实现可编程的 HTTP 代理。
模拟发包
路由 / 代理机器上,一般不运行浏览器。除此之外的模拟发包的方法,跟在终端上差别不大。可以优先考虑用 Python / Go 写程序实现。
工具参考
Wireshark
抓包界的元老级软件,应该属 tcpdump 和 Wireshark。有两个概念需要理解:
- Capture filter:表示抓包软件应该抓的内容。不在这个范围内的包被直接丢弃。目前主流用的 bpf-style capture filter
- Display filter:Wireshark 上的一个概念,类似于一个表格中的行列过滤器。它只是在展示上的做一些筛选,但是包有没有抓下来,还是看的 capture filter
httpry
httpry (GitHub|官网) 是一个 HTTP 实时抓包、展示和分析工具。它支持 bpf-style capture filter(跟 tcpdump 的包过滤表达式格式一致),可以把原始的 tcpdump 包保存下来,也能把解析好的 HTTP 包相关信息保存下来。同时它提供了一些 perl 脚本,可以用来分析保存下来的文件。
hsiafan/httpdump
hsiafan/httpdump 是个 HTTP 实时抓包展示工具,Go 语言写的,但是依赖 libpcap,没法编译成无依赖的二进制包。长时间运行发现有 CPU 占用高,不再输出内容的 bug。
$ go get github.com/hsiafan/httpdump
$ sudo httpdump -device any -level all -pretty
Chrome
在 Chrome 上装上 Postman Interceptor,搭配 Postman 独立应用或者 Chrome 应用,可以实现抓包及模拟发包。
Charles
Charles 是一个强力的抓包工具,跟 Fiddler 类似,但是比 Fiddler 好。
- 跨平台,Java 实现
- 功能清晰直观,不像 Fiddler 放得那么乱
- UI 比 Fiddler 看起来可靠
- 有简单易理解的打断点功能,也有 按规则 rewrite 包 的功能,可以用来修改 HTTP 包
Firefox
Firefox 曾经有个不错的插件 Tamper Data,但是随着 Firefox 的 Chrome 化,我已经搞不清楚如何去用这个插件了。
抓包类库参考
PyShark
PyShark 通过调用 WireShark 命令行程序 tshark 实现抓包,同时能编程化的处理抓到的数据,非常实用。可以处理以前抓包保存下来的 pcap 文件,也可以处理实时抓的流量。它应该是这套处理方法中最好的类库了。
可编程 HTTP 代理
可编程代理参考
mitmproxy
mitmproxy 是流行的可编程代理工具。
inaz2/proxy2
inaz2/proxy2 是个 Python 写的单文件 proxy,非常容易给 request / response 加 hook。
dahlia/wsgi-proxy
dahlia/wsgi-proxy 是 Python 写的 Proxy,没有开放定制的能力,需要自己改它代码。但是它是用 WSGI 运行的,可以容易上云服务。很多云服务要求被托管的 Python 程序必须用 WSGI。
HTTPS (or TLS) 抓包
在只使用了服务端证书(即非双向 TLS,一般情况下都是这样)的情况下,需要服务端密钥才能解开加密的数据。网上有大量教程讲如何操作,比如 WireShark 的。
如果你想抓本机 Chrome 的 TLS 包,简要的做法是:
- 配置
SSLKEYLOGFILE
环境变量再启动 Chrome:SSLKEYLOGFILE=/Users/kevin.lin/Desktop/sslkey.log /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
- 此时
SSLKEYLOGFILE
定位的文件会被生成 - 打开 WireShark,进入 Preference => Protocols => TLS,设置 (Pre)-Master-Secret log filename 为
SSLKEYLOGFILE
的值 - 开始抓包,此时可以看到 HTTPS 包的内容都被解出来了