gpt4 book ai didi

python - 用 scapy 在 python 中编写一个以太网桥

转载 作者:太空宇宙 更新时间:2023-11-03 14:31:52 29 4
gpt4 key购买 nike

我想做这样的事情:

            10.1.1.0/24          10.1.2.0/24

+------------+ +------------+ +------------+
| | | | | |
| | | | | |
| A d +-------+ e B f +-------+ g C |
| | | | | |
| | | | | |
+------------+ +------------+ +------------+

d e f g
10.1.1.1 10.1.1.2 10.1.2.1 10.1.2.2

所以A可以发送数据包到C通过B .

我试图通过运行 scapy 来构建这个东西节目 B那会嗅探端口ef , 并在每种情况下修改数据包中的目标 IP 和 MAC 地址,然后通过另一个接口(interface)发送它。像这样的东西:

my_macs = [get_if_hwaddr(i) for i in get_if_list()]
pktcnt = 0
dest_mac_address = discover_mac_for_ip(dest_ip) #
output_mac = get_if_hwaddr(output_interface)

def process_packet(pkt):
# ignore packets that were sent from one of our own interfaces
if pkt[Ether].src in my_macs:
return

pktcnt += 1
p = pkt.copy()
# if this packet has an IP layer, change the dst field
# to our final destination
if IP in p:
p[IP].dst = dest_ip

# if this packet has an ethernet layer, change the dst field
# to our final destination. We have to worry about this since
# we're using sendp (rather than send) to send the packet. We
# also don't fiddle with it if it's a broadcast address.
if Ether in p \
and p[Ether].dst != 'ff:ff:ff:ff:ff:ff':
p[Ether].dst = dest_mac_address
p[Ether].src = output_mac

# use sendp to avoid ARP'ing and stuff
sendp(p, iface=output_interface)

sniff(iface=input_interface, prn=process_packet)

但是,当我运行这个东西时(完整来源 here),各种​​疯狂的事情开始发生......一些数据包通过了,我什至得到了一些响应(用 ping 测试)但是有导致发送大量重复数据包的某种类型的反馈循环...

知道这里发生了什么吗?尝试这样做是不是很疯狂?

我有点怀疑反馈循环是由 B 引起的。正在对数据包进行一些自己的处理...有什么方法可以阻止操作系统在我嗅探后处理数据包吗?

最佳答案

IP数据包使用scapy桥接:

  1. 首先确保您已禁用 ip 转发,否则将注意到重复的数据包:

echo "0" > /proc/sys/net/ipv4/ip_forward <br>

  1. 第二次运行以下 python/scapy 脚本:

!/usr/bin/python2

from optparse import OptionParser
from scapy.all import *
from threading import Thread
from struct import pack, unpack
from time import sleep

def sp_byte(val):
return pack("<B", val)

def su_nint(str):
return unpack(">I", str)[0]

def ipn2num(ipn):
"""ipn(etwork) is BE dotted string ip address
"""
if ipn.count(".") != 3:
print("ipn2num warning: string < %s > is not proper dotted IP address" % ipn)

return su_nint( "".join([sp_byte(int(p)) for p in ipn.strip().split(".")]))

def get_route_if(iface):
try:
return [route for route in conf.route.routes if route[3] == iface and route[2] == "0.0.0.0"][0]
except IndexError:
print("Interface '%s' has no ip address configured or link is down?" % (iface));
return None;

class PacketCapture(Thread):

def __init__(self, net, nm, recv_iface, send_iface):
Thread.__init__(self)

self.net = net
self.netmask = nm
self.recv_iface = recv_iface
self.send_iface = send_iface
self.recv_mac = get_if_hwaddr(recv_iface)
self.send_mac = get_if_hwaddr(send_iface)
self.filter = "ether dst %s and ip" % self.recv_mac
self.arp_cache = []

self.name = "PacketCapture(%s on %s)" % (self.name, self.recv_iface)

self.fw_count = 0

def run(self):

print("%s: waiting packets (%s) on interface %s" % (self.name, self.filter, self.recv_iface))

sniff(count = 0, prn = self.process, store = 0, filter = self.filter, iface = self.recv_iface)

def process(self, pkt):

# only bridge IP packets
if pkt.haslayer(Ether) and pkt.haslayer(IP):

dst_n = ipn2num(pkt[IP].dst)

if dst_n & self.netmask != self.net:
# don't forward if the destination ip address
# doesn't match the destination network address
return

# update layer 2 addresses
rmac = self.get_remote_mac(pkt[IP].dst)
if rmac == None:
print("%s: packet not forwarded %s %s -) %s %s" % (self.name, pkt[Ether].src, pkt[IP].src, pkt[Ether].dst, pkt[IP].dst))
return

pkt[Ether].src = self.send_mac
pkt[Ether].dst = rmac

#print("%s: forwarding %s %s -> %s %s" % (self.name, pkt[Ether].src, pkt[IP].src, pkt[Ether].dst, pkt[IP].dst))

sendp(pkt, iface = self.send_iface)

self.fw_count += 1

def get_remote_mac(self, ip):

mac = ""

for m in self.arp_cache:
if m["ip"] == ip and m["mac"]:
return m["mac"]

mac = getmacbyip(ip)
if mac == None:
print("%s: Could not resolve mac address for destination ip address %s" % (self.name, ip))
else:
self.arp_cache.append({"ip": ip, "mac": mac})

return mac

def stop(self):
Thread._Thread__stop(self)
print("%s stopped" % self.name)


if __name__ == "__main__":
parser = OptionParser(description = "Bridge packets", prog = "brscapy", usage = "Usage: brscapy -l <intf> (--left= <intf>) -r <inft> (--right=<intf>)")
parser.add_option("-l", "--left", action = "store", dest = "left", default = None, choices = get_if_list(), help = "Left side network interface of the bridge")
parser.add_option("-r", "--right", action = "store", dest = "right", default = None, choices = get_if_list(), help = "Right side network interface of the bridge")

args, opts = parser.parse_args()

if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)

lif = args.left
rif = args.right

lroute = get_route_if(lif)
rroute = get_route_if(rif)

if (lroute == None or rroute == None):
print("Invalid ip addressing on given interfaces");
exit(1)

if (len(lroute) != 5 or len(rroute) != 5):
print("Invalid scapy routes")
exit(1)

conf.verb = 0

lthread = PacketCapture(rroute[0], rroute[1], lif, rif)
rthread = PacketCapture(lroute[0], lroute[1], rif, lif)

lthread.start()
rthread.start()

try:
while True:
sys.stdout.write("FORWARD count: [%s -> %s %d] [%s <- %s %d]\r" % (lif, rif, lthread.fw_count, lif, rif, rthread.fw_count))
sys.stdout.flush()
sleep(0.1)
except KeyboardInterrupt:
pass

lthread.stop()
rthread.stop()

lthread.join()
rthread.join()

在我的电脑上:

# ./brscapy.py --help
Usage: brscapy -l <intf> (--left= <intf>) -r <inft> (--right=<intf>)

Bridge packets

Options:
-h, --help show this help message and exit
-l LEFT, --left=LEFT Left side network interface of the bridge
-r RIGHT, --right=RIGHT
Right side network interface of the bridge

# ./brscapy.py -l e0 -r e2
PacketCapture(Thread-1 on e0): waiting packets (ether dst 00:16:41:ea:ff:dc and ip) on interface e0
PacketCapture(Thread-2 on e2): waiting packets (ether dst 00:0d:88:cc:ed:15 and ip) on interface e2
FORWARD count: [e0 -> e2 5] [e0 <- e2 5]

关于python - 用 scapy 在 python 中编写一个以太网桥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9337545/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com