用 scapy 在 python 中编写以太网桥

问题描述

我想做这样的事情:

            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就可以通过BC发包了.

So that Acan send packets to C through B.

我试图通过在 B<上运行 scapy 程序来构建这个东西/code> 将嗅探端口 ef,并在每种情况下修改数据包中的目标 IP 和 MAC 地址,然后通过另一个接口将其发送.比如:

I attempted to build this thing by running a scapy program on B that would sniff ports e and f, and in each case modify the destination IP and MAC address in the packet and then send it along through the other interface. Something like:

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)

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

However, when I run this thing (full source here) all sorts of crazy things start to happen... Some of the packets get through, and I even get some responses (testing with ping) but there's some type of feedback loop that's causing a bunch of duplicate packets to get sent...

有什么想法吗?尝试这样做是不是很疯狂?

Any ideas what's going on here? Is it crazy to try to do this?

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

I'm kind of suspicious that the feedback loops are being caused by the fact that B is doing some processing of its own on the packets... Is there any way to prevent the OS from processing a packet after I've sniffed it?


解决方案

这样做有点疯狂,但消磨时间也不错.你会学到很多有趣的东西.但是,您可能想考虑将数据包挂低一点 - 我不认为 scapy 能够真正拦截数据包 - libpcap 所做的一切都是让您混杂并让您看到所有内容,因此您和内核都得到相同的东西.如果您转身重新发送它,那可能是您的数据包风暴的原因.

It is kinda crazy to do this, but it's not a bad way to spend your time. You'll learn a bunch of interesting stuff. However you might want to think about hooking the packets a little lower - I don't think scapy is capable of actually intercepting packets - all libpcap does is set you promisc and let you see everything, so you and the kernel are both getting the same stuff. If you're turning around and resending it, thats likely the cause of your packet storm.

但是,您可以设置一些创造性的防火墙规则,将每个接口彼此隔开,并以这种方式传递数据包,或者使用类似 转移套接字 将数据包从内核中偷走,这样你就可以随心所欲了.

However, you could set up some creative firewall rules that partition each interface off from each-other and hand the packets around that way, or use something like divert sockets to actually thieve the packets away from the kernel so you can have your way with them.

相关文章