對WireShark 中的UDP抓包數據進行解析
本文嘗試對 WireShark 中抓包的 UDP 數據進行解析。 但是在嘗試對 TCP 中的 FTP 數據進行解析的時候,發現除了從端口號進行區分之外, 沒有什么好的方式來進行處理。
import numpy as np
import matplotlib.pyplot as plt
from IPython import embed
from collections import Counter
import pyshark
import pcapng
from datetime import datetime
import dpkt
import socket
from dpkt.utils import mac_to_str, inet_to_str# https://zhuanlan.zhihu.com/p/582336672
# https://blog.csdn.net/simonchi/article/details/105682118#打開抓包文件cnt = 2
old_timestamp = 0
file_path = "./host_pc.pcapng"time_list_pc_to_control = []
time_list_control_to_pc = []
data_list = []joint_cmd = []
joint_fd = []
with open(file_path,"rb") as fp:pcapng_data = dpkt.pcapng.Reader(fp)for timestamp, buf in pcapng_data:eth = dpkt.ethernet.Ethernet(buf)cnt += 1## Ethernet_II 幀格式# ## 1、目標 Mac 地址# eth.dst# ## 2、源 Mac 地址# eth.src## 3、得到Ethernet II 數據幀的類型。類型字段(Type )用于標識數據字段中包含的高層協議。類型字段取值為0x0800的幀代表IP協議幀;類型字段取值為0x0806的幀代表ARP協議幀。## 0x0800: IP IP協議## IPv4: 0x0800## ARP: 0x0806## RARP: 0x0835## IPV6: 0x86DD## EtherCAT: 0x88A4# print(hex(eth.type))# 說明是ARP協議: “Address Resolution Protocol”(地址解析協議)if eth.type == 0x0806:ip = eth.data# Hardware typeprint(ip.hrd)# protocol typeprint(ip.pro)# Hardware sizeprint(ip.hln)# Protocol sizeprint(ip.pln)# Opcode request: 1 是 request, 2 是 replyprint(ip.op)# Sender MAC addressprint(mac_to_str(ip.sha))# Sender IP addressprint(inet_to_str(ip.spa))# Target MAC addressprint(mac_to_str(ip.tha))# Target IP addressprint(inet_to_str(ip.tpa))# 說明是 IPV4 協議if eth.type == 0x0800:## 4、數據字段(Data )是網絡層數據。ip = eth.data## 得到 TCP/IP 數據包tcp = ip.data# Internet Protocol version 4 的解析# Versionprint(ip.v)# Header lengthprint(ip.hl)# Differentiated Service Fieldprint( ip.df)# Total lengthprint(ip.len)# Identificationprint(ip.id)# Time to Liveprint(ip.ttl)# Protocolprint(ip.p)# Source addressprint(inet_to_str(ip.src))# Destionation addressprint(inet_to_str(ip.dst))# print(type(ip))# src = socket.inet_ntoa(ip.src)# dst = socket.inet_ntoa(ip.dst)# sport = tcp.sport# dport = tcp.dport# print(f'Source IP: {ip.src}')# print(f'Destination IP: {ip.dst}')# print(f'Source Port: {tcp.sport}')# print(f'Destination Port: {tcp.dport}')# print("[+] 源地址: {}:{} --> 目標地址:{}:{}".format(src,sport,dst,dport))# print('IP: %s -> %s (len=%d ttl=%d DF=%d MF=%d offset=%d)\n' %# (inet_to_str(ip.src), inet_to_str(ip.dst), ip.len, ip.ttl, ip.df, ip.mf, ip.offset))# 當編號為 1 時,表示上層用的是 ICMP 協議–傳輸層的協議# 當編號為 6 時,表示上層用的是 TCP 協議–傳輸層的協議# 當編號為 17 時,表示上層用的是 UDP 協議–傳輸層的協議# if(type(ip) == dpkt.ip.IP):protocol = ip.pif protocol == 1:# ICMP 的解析: Internet control message Protocolicmp_data = ip.data# 標識ICMP報文的類型,從類型值來看ICMP報文可以分為兩大類。第一類是取值為1~127的差錯報文,第2類是取值128以上的信息報文icmp_data.type# 占一字節,標識對應ICMP報文的代碼。它與類型字段一起共同標識了ICMP報文的詳細類型icmp_data.codeif protocol == 6:# Transmission Control Protocol 協議中的數據包tcp_data = ip.data# Source porttcp_data.sport# Destionation porttcp_data.dport# Sequence Numbertcp_data.seq# Acknowledgment Numbertcp_data.ack# Flagtcp_data.flags# Windowstcp_data.win# Checksumtcp_data.sum=49681# 用戶下發的 TCP 協議內容tcp_data_data = tcp_data.data# 判斷是否是 FTP協議,一個是看端口是否是21# ftp:21、20# ssh :22 # telnet:23# HTTP: 80# HTTPS: 443# TFTP: 69# DNS: 53# SNMP: 161# DHCP: 67/68if protocol == 17:# User Datagram protocol 協議中的數據包udp_data = ip.data# Destionation portudp_data.dport# Source portudp_data.sport# Lengthudp_data.ulen# 用戶下發的UDP協議內容udp_data_data = udp_data.data# 用戶下發數據的長度len(udp_data_data)# 解析在 UDP 中的數據if((protocol == 17) and (ip.dst == b'\xc0\xa8\nx') and (tcp.dport == 2095) ):a = str(ip.data.data)b = a.split(",")# 得到對應的時間戳time_list_pc_to_control.append(timestamp)data_list.append(float(b[1]))