网络行为学导论做的一个实践作业,主要是利用commview抓包和dpkt分析,与一般抓包不同的点是利用透明代理抓境外流量
第一部分:抓包
利用可翻墙的虚拟机作为透明代理,首先将虚拟机设置为桥接模式让其在局域网可见,再手动设置安卓机的网关为虚拟机的IP,在安卓机上采用了黑域以获取更纯净的流量
在宿主机利用commview进行抓包,采用了高级过滤和IP过滤两种方式
第二部分:分析
采用[dpkt][https://dpkt.readthedocs.io/en/latest/]对pcap进行读取
1 | pip install dpkt |
选取的特征如下:
流开始时间(整型),持续时间(整型),客户端IP(字符串),客户端端口(主机序),服务器IP(字符串),服务器端口(主机序),应用名称,应用行为,流的总包数,流的总字节数,平均每包字节数
1 | ["StartTime", "DurationTime", "ClientIP", "ClientPort", "ServerIP", "ServerPort", "AppName", "AppAction", "FlowPackets", "FlowBytes", "PacketsBytesAvg"] |
其中,AppName和AppAction从文件名获取,其余部分通过解析包获得,具体代码如下:
读取数据pcap包
1 | f = open(pcap_path, 'rb') |
解以太网帧,对没有IP段的包过滤
1 | for timestamp, buf in pcap: |
对传输层协议非TCP的包进行过滤
1 | if isinstance(ip.data, dpkt.tcp.TCP): # 解包,判断传输层协议是否是TCP |
对流的处理
采用启发式的方法,即对于一对IP而言,根据flags判断是否处于握手阶段
1 | def JudgeTcpState(flags): |
以下是dpkt的TCP包源码:
对于TCP流的结束,设置一个dict保存挥手状态,当第一次挥手FIN=1之后四次相同IP对的包出现,且其中还有一次FIN=1时,认为挥手成功(这样其实有很大缺陷,比如有的时候挥手异常不止四次)
1 | if ip_set in TCP_wave_dic: |
对于没有挥手成功,但已经握手的IP对,则在pcap读取完毕后,以最后一次相同IP对的时间戳进行保存
对于UDP
采用第一次出现IP对和最后一次出现IP对作为“流”进行统计
完整代码如下
1 | # -*- coding: UTF-8 -*- |
有待进一步改善的地方
IP对用set保存,则不可以判断上下行方向
默认四次挥手后不会再次收到连接,其实有可能再次握手进行传输,有的时候挥手出现错误不止四次
只会统计被捕捉到第一次挥手的包,其他tcp流不会被捕捉