1、SOCKET通信-服务端-收+发
import socket
def start_server(host='localhost', port=65432):
# 创建一个 TCP/IP socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: #ipv4 TCP协议
# 绑定到主机和端口
s.bind((host, port))
# 监听连接
s.listen()
print(f"服务器在 {host}:{port} 等待连接...")
conn, addr = s.accept() # 等待客户端连接
with conn:
print(f"连接来自 {addr}")
while True:
data = conn.recv(1024) # 接收数据
if not data:
break
print(f"接收到: {data.decode('utf-8')}")
conn.sendall(data) # 回送相同的数据给客户端
# 分块接收大文件
# filename='xxxxxxx'
# with open(filename, 'wb') as file:
# while True:
# chunk = conn.recv(1024)
# if not chunk:
# break
# file.write(chunk)
if __name__ == "__main__":
start_server()
2、socket通信-客户端-收+发
import socket
import scapy
from scapy.all import sniff
from scapy.all import rdpcap
def Callback(packet):
print('src:%s----->dst:%s' % (packet[IP].src, packet[IP].dst))
print('TTL:%s' % packet[IP].ttl)
print(packet.show()) # 内置的show()函数打印数据包内容
def count_packets(pkt):
global icmp_count
if pkt.haslayer('ICMP'):
icmp_count += 1
def start_client(host='192.168.xx.xx', port=2332):
# 创建一个 TCP/IP socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
# 连接到服务器
s.connect((host, port))
# 发送数据
message = "Hello, Server! I am Client"
s.sendall(message.encode('utf-8'))
#sendall可以一次性全部传完,
#send每次只能传输MTU的大小,剩余丢弃,需手工循环
# #发送大文件,分块发送
# file = open("data.bin", "rb")
# while True:
# data = file.read(1024)
# if not data:
# break
# conn.sendall(data)
# file.close()
# print("文件传输完成!")
# 接收回送的数据
data = s.recv(1024)
print(f"从服务器接收到: {data.decode('utf-8')}")
s.close()
if __name__ == "__main__":
start_client()
#抓包
#监听 WLAN 接口的流量包(网卡名可以在 更改适配器选项 里面看),监听时间是 60s
# filter = 'src host 192.168.1.5 && dst port 2332'
# pkt = sniff(iface='Red Hat VirtIO Ethernet Adapter #2', filter=filter, timeout=60, prn=count_packets)
# print(pkt)
3、scapy-sniff抓包
from scapy.all import *
import scapy.all as scapy
from scapy.all import sniff
from scapy.all import rdpcap
def Callback(packet):
print('src:%s----->dst:%s' % (packet[IP].src, packet[IP].dst))
print('TTL:%s' % packet[IP].ttl)
# print(packet.show()) # 内置的show()函数打印数据包内容
print(packet.summary()) # 内置的summary()函数打印数据包内容
def count_packets(pkt):
global icmp_count
if pkt.haslayer('ICMP'):
icmp_count += 1
conf.bufsize=104857600 #增大缓存,防止丢包
# filter = 'src host 192.168.1.5 && src port 2332'
filter = 'tcp && src host 192.168.1.5 || dst host 192.168.1.5'
pkt = sniff(iface='Red Hat VirtIO Ethernet Adapter #2', filter=filter, timeout=30, prn=Callback)
print(pkt)
pkt.summary()
# pkt[1].src
# pkt[1].dst
# pkt[1].show()
# IP in pkt #判断是否存在IP层
print(len(pkt))
print("源mac地址为:" + pkt[0][Ether].src)
print("目的mac地址为:" + pkt[0][Ether].dst)
print("源IP地址为:" + pkt[0][IP].src)
print("目的IP地址为:" + pkt[0][IP].dst)
# for pkt_i in pkt:
# print("源mac地址为:" + pkt_i[Ether].src)
# print("目的mac地址为:" + pkt_i[Ether].dst)
# print("源IP地址为:" + pkt_i[IP].src)
# print("目的IP地址为:" + pkt_i[IP].dst)
4、scapy-其他功能
from scapy.all import *
#dpdk
#pyshark--需要winshark支持--pass
#写 pcap
# 构造报文,并写到文件中,
pkt=Ether()/IP(dst='192.168.8.1')/TCP(dport=80)
pkt.summary()
pkt[1].src
pkt[1].dst
pkt[1].show()
IP in pkt #判断是否存在IP层
wrpacp('F://pkt.pcap',pkt)
#读入 pcap
# 该函数返回的f是一个scapy.plist.PacketList(可以看做一个list进行运算)类型可以通过f[i]来读取
f=scapy.rdpcap('path_pcap')
# 使用f[0].show()或f[0].display()进行数据包格式化打印。
# 该方法将数据全部读入内存--数据包大的时候容易卡顿
# f[0]指第一层,通过f[0].payload可以得到该层协议的载荷部分,通过重复调用payload方法可以找到自己需要的层,并对其下的字段进行提取分析。
f[0].show()
f[0].payload.src #获取数据包的源ip地址
# session()
# 该方法将读入的数据包列表分为对话组存储,以源IP和目的IP为分化标准,但是当源IP和目的IP位置变换的时候将会被视为不同的分组,
########################################################################
# 在wireshark抓个包并导出pcap / pcapng文件,直接对此文件进行分析
import scapy.all as scapy
def count_packets(pkt):
global icmp_count
for packet in pkt:
if packet.haslayer('ICMP'):
icmp_count += 1
# pkt = scapy.rdpcap("./test.pcap")
pkt = scapy.rdpcap("./test.pcapng")
icmp_count = 0
count_packets(pkt)
print(pkt)
sum = len(pkt)
icmp_percent = (icmp_count / sum) * 100
print("流量包的总数: %d\nICMP包的数量: %d; 占比:%.2f%%" % (sum, icmp_count, icmp_percent))
from scapy.all import sniff
from scapy.all import rdpcap
def Callback(packet):
print('src:%s----->dst:%s' % (packet[IP].src, packet[IP].dst))
print('TTL:%s' % packet[IP].ttl)
print(packet.show()) # 内置的show()函数打印数据包内容
def count_packets(pkt):
global icmp_count
if pkt.haslayer('ICMP'):
icmp_count += 1
############################################
#抓包
pkt = sniff(iface='Realtek RTL8852AE WiFi 6 802.11ax PCIe Adapter', timeout=60, prn=count_packets)
# sniff(filter='src host 192.168.1.124 && dst port 80',count=4, prn=Callback)
print(pkt)
#分析数据
sum = len(pkt)
icmp_count = 0
icmp_percent = (icmp_count / sum) * 100
print("一分钟内抓取到的流量包的总数: %d\nICMP包的数量: %d; 占比:%.2f%%" % (sum, icmp_count, icmp_percent))
############################################
#保存数据
wrpcap=("d:\\test.pcap",pkt)
#将pkt命名为test.pcap,放在d盘下
show(pkt)
#可以使用show函数输出数据包的详细内容
############################################
#读取数据
pcaps = rdpacp("d:\\test.pcap")
print(len(pcaps))
for pkt in pcaps:
print("源mac地址为:" + pkt[Ether].src)
print("目的mac地址为:" + pkt[Ether].dst)
print("源IP地址为:" + pkt[IP].src)
print("目的IP地址为:" + pkt[IP].dst)
5、pyshark数据包分析
import pyshark
# 本程序有两个要点,
# 第一个要点是读取wireshark数据包(当然也可以从网卡直接捕获改个函数就行),这个使用pyshark实现。
# pyshark是tshark的一个python封装,至于tshark可以认为是命令行版的wireshark,随wireshark一起安装。
# 第二个要点是追踪流,追踪流在wireshark中是“tcp.stream eq 70”之类的形式,
class wireshark_analysis_script():
# 此函数的作用是封装一下pyshark.FileCapture
def read_packets_from_file(self, packets_file_path, tshark_path, display_filter):
packets_file_obj = pyshark.FileCapture(input_file=packets_file_path, tshark_path=tshark_path, display_filter=display_filter)
return packets_file_obj
# 此函数的作用是从传送过来的所有数据包中,抽取并返回{ip_server,ip_client,port_server,port_client}四元组
def get_target_client_ip_port(self, packets_file_obj):
for tmp_packet in packets_file_obj:
ip_server = tmp_packet.ip.src
port_server = tmp_packet.tcp.srcport
ip_client = tmp_packet.ip.dst
port_client = tmp_packet.tcp.dstport
stream_value = tmp_packet.tcp.stream
yield {"ip_server": ip_server, "port_server": port_server, "ip_client": ip_client, "port_client": port_client,"stream_value":stream_value}
# 此函数的作用是读取传过来的所有数据包应用层的数据,并打印
def follow_tcp_stream(self, packets_file_obj, ip, port):
for tmp_packet in packets_file_obj:
highest_layer_name = tmp_packet.highest_layer
#追踪流时会有握手挥手tcp将其排除
if highest_layer_name != "TCP":
if ((tmp_packet.ip.dst == ip) and (tmp_packet.tcp.dstport == port)):
print("server(%s:%s)->client(%s:%s): %s" % (tmp_packet.ip.src, tmp_packet.tcp.srcport, tmp_packet.ip.dst, tmp_packet.tcp.dstport, tmp_packet[highest_layer_name].get_field('data')))
elif ((tmp_packet.ip.src == ip) and (tmp_packet.tcp.srcport == port)):
print("client(%s:%s)->server(%s:%s): %s" % (tmp_packet.ip.src, tmp_packet.tcp.srcport, tmp_packet.ip.dst, tmp_packet.tcp.dstport, tmp_packet[highest_layer_name].get_field('data')))
if __name__ == '__main__':
# 要读取的wireshark数据包的所在的路径
packets_file_path = 'E:\江苏移动-hzy工作资料\\5GC学习资料\\01-中兴5GC资料\python-tasks\\test.pcap'
# tshark程序所在的路径,tshark随wireshark安装
tshark_path = 'D:\Program Files\HWEnsp\Wireshark\Wireshark.exe'
# 过滤器表达式,与在wireshark中使用时的写法完全相同
# first_step_filter = 'telnet contains "hello baidu"'
first_step_filter = 'frame contains "hello baidu"'
# 用于存放要追踪流的ip和端口
target_client_ip_port = []
# 实例化类
wireshark_analysis_script_instance = wireshark_analysis_script()
# 使用first_step_filter过滤器表达式,过滤出要追踪流的数据包
first_step_obj = wireshark_analysis_script_instance.read_packets_from_file(packets_file_path, tshark_path, first_step_filter)
print('first_step_obj: len=',len(first_step_obj))
# 从要追踪流的数据包中抽取出ip和端口
target_client_ip_port = wireshark_analysis_script_instance.get_target_client_ip_port(first_step_obj)
first_step_obj.close()
# 遍历要追踪流的ip+端口组合
for target_client_ip_port_temp in target_client_ip_port:
# stream的值
stream_value = target_client_ip_port_temp['stream_value']
ip_client = target_client_ip_port_temp['ip_client']
port_client = target_client_ip_port_temp['port_client']
# tcp.stream eq 70形式。为了排除tcp其实可以再直接加上and telnet
second_step_filter = 'tcp.stream eq %s' % (stream_value)
second_step_obj = wireshark_analysis_script_instance.read_packets_from_file(packets_file_path, tshark_path, second_step_filter)
print("[%s:%s]" % (ip_client, port_client))
# 调用follow_tcp_stream将认为是同一个流的所有数据包的应用层数据打印
wireshark_analysis_script_instance.follow_tcp_stream(second_step_obj, ip_client, port_client)
second_step_obj.close()
6、pyshark数据练习
#pyshark数据包解析
import pyshark
caps=pyshark.FileCapture('test.pcap',tshark_path='D:\Program Files\HWEnsp\Wireshark\Wireshark.exe')
dir(caps[0])
for x in caps:
# print(cap)
print('ETH Source:',x.eth.get_field_by_showname('Source'))
print('ETH Destination:',x.eth.get_field_by_showname('Destination'))
print('IP Source:',x.ip.get_field_by_showname('Source'))
print('IP Destination:',x.ip.get_field_by_showname('Destination'))
print('TCP Source Port:',x.tcp.get_field_by_showname('Source Port'))
print('TCP Destination Port:',x.tcp.get_field_by_showname('Destination Port'))
def print_conversation_header(pkt):
try:
# protocol = pkt.transport_layer
# src_addr = pkt.ip.src
# src_port = pkt[pkt.transport_layer].srcport
# dst_addr = pkt.ip.dst
# dst_port = pkt[pkt.transport_layer].dstport
# print ('%s %s:%s --> %s:%s' % (protocol, src_addr, src_port, dst_addr, dst_port))
print(pkt.show())
except AttributeError as e:
#ignore packets that aren't TCP/UDP or IPv4
pass
caps=pyshark.FileCapture('test.pcap',tshark_path='D:\Program Files\HWEnsp\Wireshark\Wireshark.exe')
caps.apply_on_packets(print_conversation_header, timeout=100)
####################################################################################################
from pyshark import FileCapture
# 创建FileCapture对象来捕获文件中的数据包
caps=pyshark.FileCapture('test.pcap',tshark_path='D:\Program Files\HWEnsp\Wireshark\Wireshark.exe')
# 遍历每个数据包
for packet in caps:
# 打印每个数据包的一些基本信息,例如源IP和目标IP
if packet['ip']:
print("Source IP:", packet['ip'].src)
print("Destination IP:", packet['ip'].dst)
else:
print("No IP layer found in this packet.")
# 关闭FileCapture对象
caps.close()