网络抓包是个基础技能,对于网络协议的掌握有必定的要求。iOS上实现网络抓包能够用Charles(针对http和https),tcpdump(快速分析网络包),和Wireshare。以前写过一篇介绍tcpdump抓包的入门文章,和tcpdump相比,Wireshark提供丰富的GUI交互,并且能分析全部的网络协议,关键仍是免费的,掌握好Wireshark就能应付绝大部分须要分析网络协议的场景了。html
Wireshark提供Mac版本,能够从官网下载安装,到这篇博客为止最新版本应该是2.2.1。安装好以后打开的第一个界面以下:程序员
Wireshark在第一个界面就把当前系统所包含的网卡列出来了,直接点击任何一项就能够开始监听经过该网卡的全部网络流量。算法
当咱们把iPhone经过usb链接macbook时,Wireshark并不能直接监听经过iPhone的网络流量,须要经过一个系统程序在咱们的Mac系统上,创建一个映射到iPhone的虚拟网卡,在terminal中输入以下命令便可:安全
格式是rvictl -s [设备udid],设备的udid能够经过itunes或者itools获取,执行命令以后Wireshark能当即识别新增长的rvi0网卡,也就是上图中高亮的部分,双击rvi0这一项,Wireshare即进入以下界面开始监听iPhone设备上的全部流量。使用完毕以后rvictl -x[设备udid]断开连接。服务器
此时,启动iPhone上的任意App,只要有网络流量产生,对应的网络包都会在Wireshark上述的列表中展现出来。网络
Wireshark的流量监控界面主要分为四块,由上至下第一部分(标号为1)是工具栏,经过工具栏咱们能够控制监控的行为,好比开始抓包,中止抓包,从新开始抓包,以及在包之间跳转等等。工具栏的底部有个输入框,可让咱们手动输入包的过滤条件,这部分对于熟练使用Wireshark抓包很是重要,后面会详细的讲解。session
第二部分(标号为2)是历史流量包列表展现界面,这里展现的是从抓包开始,全部经过咱们iPhone设备的流量。列表界面不一样的包有不一样的颜色,Wireshark经过颜色来区分包的类型,对于特定场景快速识别目标流量很是有用,后面也会专门讲解。架构
第三部分(标号为3)是单个包的详细信息展现面板,咱们在第二部分选中的网络包在这一部分会将其结构以可阅读的文本形式展现出来,要正确阅读这一部分的信息须要对tcp/ip协议有必定的掌握。socket
第四部分(标号为4)是单个包的二进制流信息展现面板,这一部分展现的信息是包的原始数据,也是一个网络包所包含内容的真实展示,咱们在第三部分多选中的协议头,都会在这一部分以同步高亮的形式标记出来。这一部分的展现是为了让咱们对包的真实内容作直观的判断,能具体到单个byte。tcp
初步认识上述四块主要面板以后,能够尝试开始分析网络包,在开始分析网络包以前,先要对网络包有个大体的概念。
咱们最初学习网络协议的时候,不管是OSI七层模型,仍是经典的TCP/IP五层结构,都是如下图中的左边部分的形式展现的。
这是一种经典的分层架构,确实也符合网络协议设计上的思路,但却不能表达网络包真实的包含关系。上图右边部分是我所绘制的一个包结构示意图。在我看来,这种洋葱式的结构更符合网络包的真实形态。Application是最内层的payload,除了Application这一层以外,其余层都是用本身这一层的协议header+所包含那一层的payload。能够用以下公式表示:
TCP Layer = TCP Header + Application Payload
IP Layer = IP Header + TCP Payload
...
咱们分析每一个网络包的时候要能理解每个包它所表明的抽象含义,再进一步将相关联的包串联起来,造成一次完整的网络会话。
对于iOS程序员来讲,咱们绝大部分的流量分析都集中在HTTP或者基于TCP的socket长链接。从这一层面来讲,和咱们最贴近的三层是应用层(http),传输层(tcp or udp),网络层(ip)。
对于应用层来讲主要是http协议的学习,对于http request和response格式的阅读,好比下图表示的一个http request包:
Packet详情面板以符合http协议的表述,将header中各个field清晰的罗列出来了,阅读起来很方便。
传输层咱们应用较多的是tcp,这一层的阅读主要是tcp header的学习:
典型的tcp header通常长度为20个字节,将这20个字节逐一学习一遍就能够分析大部分的tcp流量了。
网络层的分析主要是针对于IP Header,header结构以下:
这其中IP Header第十三个字节各个filed的理解,对于咱们分析tcp流量的起始和结束尤为有用,典型的IPV4 Header也是20个字节,梳理一遍就能够分析IP包了。
因此对于包结构的分析关键在于三个知识点的学习:http header, tcp header, ip header,这么一看好像也没多少东西 ;)
使用Wireshark和使用Charles最大的区别在于,Charles只捕获HTTP流量,而Wireshark捕捉的是通过目标网卡全部的流量,流量包能够在几秒内膨胀到难以阅读的数量,因此此时咱们须要使用Filter来作包的过滤,Filter规则定的越细,剔除掉的干扰信息就越多,分析起来就越快。
Wireshark的Filter分为两种,一种为Capture Filter,另外一种是Display Filter。
Capture Filter出如今初始界面,在网卡列表的上方有个输入框,容许咱们输入capture filter,一旦输入了特定的capture规则,Wireshark就只捕获符合该规则的流量包了。
Display Filter出如今流量监控界面,在工具栏的下方有个输入框,容许咱们输入display filter,display filter只是从界面上过滤掉不符合规则的包,Wireshark实际上仍是监听了这些包,一旦去掉display filter,全部的包又会出如今同一界面。
Capture Filter的规则和咱们日常使用tcpdump的filter语法是一致的,好比为了只监控http的流量,咱们能够先在初始化界面选中rvi0网卡,再在capture filter输入框里输入:
//只捕获HTTP流量 port 80 or port 443
回车以后Wireshark就开始监控咱们iPhone上全部的http和https流量了 ,很是简单,咱们还可使用其余的capture filter来捕获特定的流量,好比想分析DNS解析过程,可使用:
//只捕获DNS流量 port 53
好比只想捕获和特定服务器相关的流量:
//只捕获和特定主机的流量 host 171.10.191.10
Display Filter的语法是由Wireshark自定义的,和Capture filter的语法不能混用。好比咱们只想看某个主机的流量,可使用以下Display Filter:
ip.addr==171.10.191.10
若是只看http或者https的流量,能够用:
tcp.port == 80 || tcp.port == 443
更多的语法规则能够查看Wireshark官方文档,Wireshark实际上提供了便捷的UI操做帮助咱们来书写Display Filter,在Display Filter输入框的最右边有个Expression按钮,点击以后能够弹出以下界面:
Display Filter的语法本质上是个等是关系描述,咱们能够在search当中输入咱们感兴趣的协议好比http,再在展开的协议头里选择咱们的条件好比http.host,最后设置Relation和Value就能够生成一个Display Filter条件了。
Wireshark在大多数时候捕获的包数量都远超咱们感兴趣的数量,并且各个链接的包都混杂在一块儿,为了方便咱们识别不一样的链接会话,Wireshark默认使用一种着色规则帮助咱们来进行包类型区分。
具体的规则能够经过菜单View->Coloring Rules...查看,默认规则以下:
这里有个小技巧,如上图所示,我只将我感兴趣的协议包上了色,集中在http,tcp,udp包,这样分析起来更加直观。好比根据上图的规则,tcp三次握手中的Sync包是使用灰色标记的,这样我就能够在下图的包中迅速定位一次tcp链接的开始包位置:
固然,包的颜色也能够按照本身的视觉习惯进行定制,我我的习惯把Sync包和FIN包设置一个高亮的颜色,方便判断一次HTTP会话的起始和结束。
Wireshark默认状况下将不一样网络链接的流量都混在一块儿展现,即便给不一样协议的包上色以后,要单独查看某个特定链接的流量依然不怎么方便,咱们能够经过Wireshark提供的两种方式来实现这个目标。
当咱们选中某个包以后,右键弹出的菜单里,有个选项容许咱们将当前包所属于的完整流量单独列出来,以下图:
Wireshark支持咱们常见的四种Stream,TCP,UDP,HTTP,SSL。好比咱们选中Follow TCP Stream以后能够获得以下的详细分析输出(样本为监控iPhone手机的流量):
上图中将iPhone和Server之间某次的链接流量完整的呈现出来,包括iPhone发送了多少个包,Server回了多少个包,以及iPhone上行和下行的流量,还提供流量编解码选择,文本搜索功能等。
Flow Graph能够经过菜单Statistics->Flow Graph来生成,这样咱们能够获得另外一种形式的流量呈现:
和Follow Stream不一样的是咱们获取到的是完整的流量,从上图中能够看出从10.136.66.127(个人iPhone手机IP地址)发出的流向多个服务器的网络流量,包括DNS解析和SSL安全握手等。固然咱们也能够在上图中下方的操做区域作进一步的过滤,可使用Display Filter作进一步的流量定位。
Follow Stream更适合分析针对某一个服务器地址的流量,而Flow Graph更适合分析某个App的总体网络行为,包含从DNS解析开始到和多个服务器交互等。
其实Statistics菜单下还有更多的图表分析模式,能够根据不一样的分析目标来选择,好比Statistics->HTTP->Requests能够获得以下按主机分门别类的HTTP请求分析图,和收费的Charles的展现结果相似。
介绍完使用方式再来实际分析下HTTPS的流量。下图是我使用Wireshark在iPhone上抓包知乎App网络请求的结果:
当我使用Follow TCP Stream以后,一次完整的HTTPS会话流量就被单独过滤出来了,第一步先分析包列表界面。
经过高亮颜色找到会话的其实Sync包,继而能够快速的定位到HTTP创建链接之初的tcp三次握手所产生的三个包:
Sync: iPhone发送Sync。
Sync+Ack: Server发送Sync+Ack。
Ack: iPhone Ack。
三次握手以后是ssl handshake,ssl handshake分为如下几步:
Client Hello
这一个包是ssl握手的起始包,客户端(个人iPhone)会携带当前会话所依赖的一些关键信息:使用的tls版本(当前为tls1.2),上次的Session ID(若是能够session重用,就能够避免当前此次的安全握手),客户端所支持的加密算法套件(从下图中能够看出能够从22个suites里面挑选)等。
Server Hello
Server Hello这个包带上服务器这一端的一些信息,好比Server所选择的tls版本,或者带上能够重用的Session ID避免从新握手,在Client传过来的Cipher Suites当中挑选一个Cipher Suite进行后续的安全通话等。
Server 下发Certificate
Server同时会下发本身的Certificate,以下图所示:
从包列表界面能够看出,Certificate(大小为2407个bytes)这个包因为超过了1440个字节,被拆成了2个包,因此咱们能够在包Info里面看到[TCP segment of a reassembled PDU],咱们使用Wireshark抓包的时候常常会看到reassembled PDU,出现这种状况是由于包太大,超过了MSS,须要拆成两个来发送。
接下来几个包是Client和Server基于上面交换的信息协商最后使用的密钥。
Server Key Exchange
Client Key Exchange
Change Cipher Spec
...
Send Application Data
各个包里面所包含的详细内容分析涉及到非对称加密算法的相关知识,这里就不展开了,使用Wireshark能够将整个HTTPS的握手过程很是清晰的展示出来,感兴趣的同窗能够阅读这篇文章。
固然大部分时候咱们须要分析iPhone上HTTPS流量里的具体包内容,Wireshark虽然支持配置RSA私钥,但咱们没办法直接获取iPhone设备上各个App所使用的私钥,这种场景下咱们通常使用MITM(Man In The Middle)中间人攻击来破解HTTPS包内容,收费工具Charles能够经过代理的方式来实现此功能,免费版抓包工具mitmproxy一样也能够,Charles的使用教程比较多了,后续咱们会再写一篇mitmproxy的教程介绍如何使用破解调试HTTPS的流量。
Wireshark就介绍到这里,如今在iPhone上抓包的方式有不少,有面向全部协议的tcpdump和Wireshark,也有针对HTTP的Charles和mitmproxy,不管使用哪一个工具,前提都是咱们须要对网络协议有全面的认识,因此在学习使用这些工具的同时,要持续深刻的学习网络协议知识。