Packet Capture, Tamper Data and Simulating Request

 16th August 2022 at 9:45am

抓包,篡改数据和模拟发包,这几个任务在工作中非常常见。这里揉在一起讲述。

需要抓包的一些场景:

  • 开发过程中,观察服务间 API 调用的包结构,便于开发、调试 bug
  • 浏览器中研究网站 API

需要篡改数据的一些场景:

  • 在浏览器上,想篡改 AJAX 请求返回的数据来影响界面的展示或者前端逻辑
  • 篡改接口数据来影响 app 功能
  • 开发过程中,用来修改特定的数据包以验证问题;Mock 数据以不等待别人配合等

需要模拟发包的一些场景:

  • 在浏览器上,前端没有发送某个特定 API 请求的入口(如按钮、链接等),需要模拟发包来达到目的
  • Ice 和娜娜有时需要去网上上一些课,看教学视频,而且被要求看满多少时间才可以。这些网站会在你看视频时定时发请求到服务器,纪录你看了多久。需要模拟发包来装作有看这些视频

思路

常规的数据流向,一般是:

                   发起请求
终端(手机 / PC) -----------> 代理 / 路由 ---------> 服务器

终端主要有网页浏览器和应用程序(PC 上的或者手机上的)。代理服务器可以架设在本地或者远端。

除了服务器、中间路由器这几环可能控制不了,其他部分是你可以控制的。你可以在终端或者代理服务器上做抓包、篡改数据。

在终端上

终端一般分成 PC 和手机。手机受限于操作便利性,一般只做抓包及展示,没有更高级的功能;Android 上常用 Package Capture, tPacketCapture。下面的内容仅针对 PC,按功能场景做分类。

抓包

电脑上可以用老牌抓包工具 Wireshark 来抓包。如果是在服务器上没有图形界面,可以用 tcpdump 命令先抓包保存成文件,再放到 Wireshark 上分析。也可以用本地代理来抓包,流行的有 mitmproxyCharlesFiddlerbetwixt 提供了一个利用 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。

实验时发现,云服务往往不支持这种方式的代理。因为你向代理发请求时是不会带 Host 的,而云服务它往往是一批机器服务成千上万个免费的二级域名(如 <app_name>.leanapp.cn),这导致它无法判断这个请求是针对哪个服务的,所以不能服务。

HTTPS (or TLS) 抓包

在只使用了服务端证书(即非双向 TLS,一般情况下都是这样)的情况下,需要服务端密钥才能解开加密的数据。网上有大量教程讲如何操作,比如 WireShark 的

如果你想抓本机 Chrome 的 TLS 包,简要的做法是:

  1. 配置 SSLKEYLOGFILE 环境变量再启动 Chrome:
    SSLKEYLOGFILE=/Users/kevin.lin/Desktop/sslkey.log /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
  2. 此时 SSLKEYLOGFILE 定位的文件会被生成
  3. 打开 WireShark,进入 Preference => Protocols => TLS,设置 (Pre)-Master-Secret log filename 为 SSLKEYLOGFILE 的值
  4. 开始抓包,此时可以看到 HTTPS 包的内容都被解出来了