Socket通信和数据抓包分析-python

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()

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值