手机 App 抓包
要实现对 App 的网络数据抓包,需要监控 App 与服务器交互之间的网络节点,监控其中任意一个网络节点(网卡),获取所有经过网卡中的数据,对这些数据按照网络协议进行解析,这就是抓包的基本原理
但是中间网络节点,不受我们控制,所以基本无法实现抓包的,只能在客户端和服务端进行抓包
通常我们监控本地网卡数据,如下图:
本地网络
指的是WIFI的路由,如果直接抓路由器的包还是比较麻烦的,因此我们会在 手机
和 本地路由
之间加一层 代理服务
,这样只要抓代理服务的网络数据即可:
Linux 抓包
Linux 抓包是通过 注册一种虚拟的底层网络协议 来完成对网络报文(准确的说是网络设备)消息的处理权
- 当网卡接收到一个网络报文之后,它会遍历系统中所有已经注册的网络协议(例如,以太网协议,x25协议处理模块)来尝试进行报文的解析处理(这一点和一些文件系统的挂载相似,就是让系统中所有的已经注册的文件系统来进行尝试挂载,如果哪一个认为自己可以处理,那么就完成挂载)
- 当抓包模块把自己伪装成一个网络协议的时候,系统在收到报文的时候就会给这个伪协议一次机会,让它来对网卡收到的报文进行一次处理,此时该模块就会趁机对报文进行窥探,也就是把这个报文完完整整的复制一份,假装是自己接收到的报文,汇报给抓包模块
具体是使用 libpcap 获取被监听网络接口的数据
在 Linux 内核中,使用网络过滤器的数据包捕获是通过附加钩子来完成的:
- 可以根据需要在路径中的不同位置指定钩子,后跟内核网络数据包
- 可以在此处找到组织结构图,其中包含路线后跟包裹以及钩子的可能区域
钩子 hook 是通过以下结构定义的:
1 | typedef unsigned int nf_hookfn(void *priv, |
- 钩子函数 hook 的签名中有一个
nf_hook_state
结构体,用于描述 hook 的状态信息,关键条目如下:
1 | struct nf_hook_state { |
相关 API 如下:
1 | int nf_register_net_hook(struct net *net, const struct nf_hook_ops *ops); /* 用于注册挂钩点 */ |
1 | int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, |
1 | int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg, |
Linux 抓包的具体实现就是依靠该 hook 机制完成的,当网络过滤器捕获数据时,就可以依靠抓包程序的 hook 把数据包传输到对应的软件中