使用scapy修改源MAC的发包工具

Zss 发表于:

需要复现一个问题,据开发分析很有可能是因为开启wds后,由于源mac的地址存放过多,导致的问题

需要使用udp的数据包,发送成千上万个不同源mac的数据包给AP,手动来修改这些数据包的mac是不现实的,太多了

所以编写一个自动生成不同的源mac的脚本来生成这些数据包并且将其发送给AP来复现这问题

主要是使用到了scapy这个库,这个对于数据包的处理太强大了,还需要多总结一下用法,毕竟是测试网络相关的东西,这个库来说太有用了

通过配置文件的方式来获取配置,包括一些端口,ip,和生成的mac数量,还有一些循环次数设置。。。

其中在配置文件的读取的时候一个很大的坑就是编码的问题,在读取的时候先看文件的编码是什么?utf-8一定在都读取时需要encoding=’utf-8’,

在pycham中创建的配置文件默认是utf-8,在使用记事本打开修改后保存,又发生编码的问题导致无法读取,所以在创建ini文件的时候还是选择右键创建txt吧

文件:

批量修改源MAC数据包发送

config

配置文件:

[CONFIG]
mode=1
#mode:0表示为无限发送,1表示为有线数量发送

packet_group=31
#packet_group:当mode为0不生效,当mode为1时表示发送多少组相同的数据包组,单位为:组

packet_sleep=0.05
#packet_sleep:每个数据包之间的发送间隔时间,单位为:秒

eth_dst=50:7b:9d:c7:e6:11
#eth_dst:数据包的目的mac

mac_number=20
#mac_number:生成多少个不同的mac到一组数据包组中,生成的mac为源mac,单位为:个

interfa_name=Realtek PCIe FE 系列控制器
#interfa_name:发送数据的网卡描述,复制无线网卡的描述

ip_src=192.168.99.151
#ip_src:数据包的源ip

ip_dst=192.168.99.101
#ip_dst:数据包的目的ip

port_src=1778
#port_src:数据包的源端口

port_dst=1187
#prot_dst:数据包的目的端口

代码:

#coding:gbk
from scapy.all import *
import random
from configparser import ConfigParser

class Configinfo():
    def __init__(self,config_file):
        readconfig = ConfigParser()
        readconfig.read(config_file)
        try:
            code = 'gbk'
            self.mode = readconfig.get('CONFIG','mode').encode(code)
            self.interfa_name = readconfig.get('CONFIG', 'interfa_name').encode(code)
            self.packet_group = readconfig.get('CONFIG','packet_group').encode(code)
            self.packet_sleep = readconfig.get('CONFIG','packet_sleep').encode(code)
            self.mac_number = readconfig.get('CONFIG','mac_number').encode(code)
            self.eth_dst = readconfig.get('CONFIG', 'eth_dst').encode(code)
            self.ip_src = readconfig.get('CONFIG', 'ip_src').encode(code)
            self.ip_dst = readconfig.get('CONFIG', 'ip_dst').encode(code)
            self.port_src = readconfig.get('CONFIG', 'port_src').encode(code)
            self.port_dst = readconfig.get('CONFIG', 'port_dst').encode(code)
            self.data = readconfig.get('CONFIG', 'data').encode(code)
        except Exception as e:
            print '读取发生错误:%s'%e
            exit()

    def get_mode(self):
        return self.mode

    def get_packet_group(self):
        return self.packet_group

    def get_packet_sleep(self):
        return self.packet_sleep

    def get_mac_number(self):
        return self.mac_number

    def get_interfa_name(self):
        return self.interfa_name

    def get_eth_dst(self):
        return self.eth_dst

    def get_ip_src(self):
        return self.ip_src

    def get_ip_dst(self):
        return self.ip_dst

    def get_port_src(self):
        return self.port_src

    def get_port_dst(self):
        return self.port_dst

    def get_data(self):
        return self.data


def read_config(file_path):
    _config = Configinfo(file_path)
    config_info = (_config.get_mode(),_config.get_packet_group(),_config.get_packet_sleep(),_config.get_mac_number(),_config.get_interfa_name(),_config.get_eth_dst(),_config.get_ip_src(),_config.get_ip_dst(),_config.get_port_src(),_config.get_port_dst(),_config.get_data())
    return config_info


class Send_pack():
    def __init__(self):
        self.str_list = ['a','b','c','d','e','f','0','1','2','3','4','5','6','7','8','9']

    def send_one(self,config_info):
        mode,packet_group,packet_sleep,mac_number,interfa_name,eth_dst,ip_src,ip_dst,port_src,port_dst,data = config_info

        if int(mode) == 1:
            pack_list = []
            print '-' * 50
            print '正在生成mac... 数量:%d'%(int(mac_number))
            print '-' * 50
            for i in range(1,int(mac_number)+1):
                eth_src = random.choice(self.str_list)+random.choice(self.str_list)+':'+random.choice(self.str_list)+random.choice(self.str_list)+':'+random.choice(self.str_list)+random.choice(self.str_list)+':'+random.choice(self.str_list)+random.choice(self.str_list)+':'+random.choice(self.str_list)+random.choice(self.str_list)+':'+random.choice(self.str_list)+random.choice(self.str_list)
                eth = Ether(dst=eth_dst,src='%s'%eth_src)
                ip = IP(src=ip_src, dst=ip_dst)
                udp = UDP(sport=int(port_src),dport=int(port_dst))
                raw = Raw(data)
                pack = eth/ip/udp/raw
                pack_list.append(pack)
            for i in range(1,int(packet_group)+1):
                print '-'*50
                print '正在进行第%d次发送...每组的源mac均相同'%i
                print '-'*50
                try:
                    sendp(pack_list,inter=float(packet_sleep), count=1,iface=interfa_name)
                    print '发送完成...'
                    print '-' * 50
                except Exception as e:
                    print '错误:', e
                    raw_input('回车结束')
                    exit()

        elif int(mode) == 0:
            index = 1
            while 1:
                pack_list = []
                for i in range(1, int(mac_number) + 1):
                    eth_src = random.choice(self.str_list) + random.choice(self.str_list) + ':' + random.choice(
                        self.str_list) + random.choice(self.str_list) + ':' + random.choice(
                        self.str_list) + random.choice(self.str_list) + ':' + random.choice(
                        self.str_list) + random.choice(self.str_list) + ':' + random.choice(
                        self.str_list) + random.choice(self.str_list) + ':' + random.choice(
                        self.str_list) + random.choice(self.str_list)
                    eth = Ether(dst=eth_dst, src='%s' % eth_src)
                    ip = IP(src=ip_src, dst=ip_dst)
                    udp = UDP(sport=int(port_src), dport=int(port_dst))
                    raw = Raw(data)
                    pack = eth / ip / udp / raw
                    pack_list.append(pack)
                    pack_list.append(pack)
                print '-'*50
                print '正在进行第%d次发送...每组的源mac均不同'%index
                print '-'*50
                try:
                    sendp(pack_list,inter=float(packet_sleep), count=1,iface=interfa_name)
                    print '发送完成...'
                    print '-' * 50
                    index += 1
                except Exception as e:
                    print '错误:',e
                    raw_input('回车结束')
                    exit()

        else:pass


if __name__ == '__main__':
    print '-' * 50
    print(ifaces)
    print '-' * 50
    print('选择需要发包的网卡型号复制到config.ini的interfa_name中')
    print '-' * 50
    raw_input('输入回车,开始发包!!!')
    config_info = read_config('config.ini')
    send_pack = Send_pack()
    send_pack.send_one(config_info)