背景:
将设备流量镜像到我的个人PC上进行一个初步的应急分析,希望我的电脑能够解析镜像后数据包,输出:
时间、原IP:原端口、 目标IP:目标端口、网络协议
调研过程:
发现基本上、在windows中都是使用WinPcap进行开发
介绍的文章比较多,如freebuf介绍
https://www.freebuf.com/articles/network/103526.html
linux 主要使用 libpcap
https://blog.csdn.net/achejq/article/details/54969500
PF_RING
https://www.jianshu.com/p/6d3f3cdc2411?from=timeline
winpcap支持上层使用各种语言,如c、python、.net、java等,为了简单,选择python作为开发语言
安装过程
Python 2.7 版本
win7 X64
首先安全windows python依赖
下载地址: https://www.microsoft.com/en-us/download/confirmation.aspx?id=44266
安装python 2.7.13
下载地址: https://www.python.org/downloads/windows/
安装winpcap
如果提示ssl报错(参考 https://www.cnblogs.com/zengguowang/p/8399332.html),请使用如下命令安装
pip --trusted-host pypi.python.org install winpcapy
安装pcapy
pip --trusted-host pypi.python.org install pcapy
会报错,找不到pcap.h , 解决方法参考 https://stackoverflow.com/questions/22996098/trouble-installing-pcapy-on-windows-7-cannot-open-include-file-pcap-h
需要下载 winpcap development 工具包, 下载地址 https://www.winpcap.org/devel.htm
然后安装时,指定winpcap的include 和lib文件夹路径
pip --trusted-host pypi.python.org install pcapy --global-option="build_ext" --global-option="-IC:\software\WpdPack_4_1_2\WpdPack\Include" --global-option="-LC:\software\WpdPack_4_1_2\WpdPack\lib\x64"
即可完成安装
还需要安装winpcap 程序,下载地址:https://www.winpcap.org/install/default.htm
python
>>> from winpcapy import WinPcapUtils
如果不报错表示安装成功
解析数据包需要用到dpkt
pip install dpkt
https://dpkt.readthedocs.io/en/latest/installation.html
查看当前网卡信息
C:\Users\admin>python
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (
Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from winpcapy import WinPcapDevices
>>> WinPcapDevices.list_devices()
{u'\\Device\\NPF_{50E6683F-DC79-4672-8A26-D17A3E7373EC}': u'Intel(R) PRO/1000 MT
Network Connection', u'\\Device\\NPF_{DED65524-4F16-41A0-B7DD-0570F966052F}': u
'Microsoft'}
从中可以看出,Intel(R) PRO/1000 MT Network Connection 是我们的目标网卡
抓取数据结果
from winpcapy import WinPcapUtils
import time
import json
import dpkt
from dpkt.compat import compat_ord
def mac_addr(address):
"""Convert a MAC address to a readable/printable string
Args:
address (str): a MAC address in hex form (e.g. '\x01\x02\x03\x04\x05\x06')
Returns:
str: Printable/readable MAC address
"""
return ':'.join('%02x' % compat_ord(b) for b in address)
fd = open('logs.txt','a')
def packet_callback_1(win_pcap, param, header, pkt_data):
eth = dpkt.ethernet.Ethernet(pkt_data)
#eth = dpkt.ethernet.Ethernet(pkt_data)
# Make sure the Ethernet data contains an IP packet
if not isinstance(eth.data, dpkt.ip.IP):
print('Non IP Packet type not supported %s\n' % eth.data.__class__.__name__)
return
# Now unpack the data within the Ethernet frame (the IP packet)
# Pulling out src, dst, length, fragment info, TTL, and Protocol
ip = eth.data
# Pull out fragment information (flags and offset all packed into off field, so use bitmasks)
#do_not_fragment = bool(ip.off & dpkt.ip.IP_DF)
#more_fragments = bool(ip.off & dpkt.ip.IP_MF)
#fragment_offset = ip.off & dpkt.ip.IP_OFFMASK
# Print out the info
#print 'IP: %s -> %s \n' % (inet_to_str(ip.src), inet_to_str(ip.dst))
# print("%s,%.6d len:%d" % (timestr, header.contents.ts.tv_usec, header.contents.len))
# print("%s,%.6d len:%d %s -> %s" % (timestr, header.contents.ts.tv_usec, header.contents.len ,src_ip, dst_ip))
if eth.data.data.__class__.__name__ == 'TCP' or eth.data.data.__class__.__name__ == 'UDP':
ip_frame = pkt_data[14:]
# Parse ips
src_ip = ".".join([str(ord(b)) for b in ip_frame[0xc:0x10]])
dst_ip = ".".join([str(ord(b)) for b in ip_frame[0x10:0x14]])
local_tv_sec = header.contents.ts.tv_sec
ltime = time.localtime(local_tv_sec)
timestr = time.strftime("%H:%M:%S", ltime)
tcp = ip.data
#print('packaage: %s:%d->%s:%d %s' % ( src_ip,tcp.sport, dst_ip ,tcp.dport , eth.data.data.__class__.__name__))
data['s_ip'] = src_ip
data['s_port'] = tcp.sport
data['d_port'] = tcp.dport
data['d_type'] = eth.data.data.__class__.__name__
data['d_ip'] = dst_ip
data['t_time'] = timestr
data['len'] = header.contents.len
print data
fd.write(json.dumps(data) + '\n')
WinPcapUtils.capture_on("*Intel(R) PRO/1000 MT Network Connection*", packet_callback_1)