如何在拦截和修改内容时桥接两个不同的网络接口(例如 eth0 和 wlan0)?
请让我知道是否有很好的库或工具来做到这一点。如果没有一个人将如何在 Python 或 C ++ 中做到这一点?我想尽可能地做到这一点。
有人可以提供一个最小的工作示例吗?
因此,经过大量的研究和尝试其他实现,我终于组装了一个适合我的版本。它保留了两个接口的 MAC 地址列表,因此可以防止循环。此外,通过保留 L2Socket 并重用它,它比其他实现更快。
仍然有很多人可以调整,但这里是:
#!/usr/bin/python2
import signal
from threading import Thread,Lock
from scapy.all import *
def usage():
print 'Usage: scapy_bridge.py host1_intece host2_interfcae'
print ''
print 'Example: sudo python scapy_bridge.py eth1 eth2'
print ' Sets up a bridge between the hosts connected on eth1 and eth2'
cl Sniffer():
def __init__(self, input_intece, output_intece, sniffer_name):
self.input_intece = input_intece
self.output_intece = output_intece
self.sniffer_name = sniffer_name
self.output_socket = L2Socket(output_intece)
self.output_mac = get_if_hwaddr(self.output_intece)
def add_mac(self, list, mac):
if mac not in list:
list.append(mac)
def process_packet(self, pkt):
global macs_if1, macs_if2
handle_packet = True
if Ether in pkt:
src_mac = pkt[Ether].src
dst_mac = pkt[Ether].dst
if self.sniffer_name == '1to2':
if src_mac in macs_if2:
handle_packet = False
else:
self.add_mac(macs_if1, src_mac)
else:
if src_mac in macs_if1:
handle_packet = False
else:
self.add_mac(macs_if2, src_mac)
print 'MAC table 1: ' + str(macs_if1)
print 'MAC table 2: ' + str(macs_if2)
if handle_packet:
p = pkt.copy()
print 'MSGLEN=%d' % len(p)
if len(p) > 1400:
p.show()
frags = fragment(p)
for frag in frags:
self.output_socket.send(frag)
else:
self.output_socket.send(p)
def stopper_check(self, pkt):
return not still_running_lock.locked()
def sniffloop(self):
sniff(iface=self.input_intece, prn=self.process_packet, stop_filter=self.stopper_check)
# ==================================== MAIN
# global list of running threads
threads = []
# MAC table
macs_if1 = []
macs_if2 = []
# global lock to signal that we're still running
still_running_lock = Lock()
# catch Ctl-c and clean up threads
def signal_handler(signal, frame):
print 'Cleaning up sniff threads...'
still_running_lock.release()
try:
for t in threads: t.join()
except:
p
print 'exiting.'
sys.exit(0)
if __name__ == '__main__':
if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) != 3:
usage()
sys.exit(-1)
(host1_intece, host2_intece) = sys.argv[1:]
sniffer1 = Sniffer(host1_intece, host2_intece, '1to2')
sniffer2 = Sniffer(host2_intece, host1_intece, '2to1')
threads.append( Thread(target=sniffer1.sniffloop) )
threads.append( Thread(target=sniffer2.sniffloop) )
# set our "state" to running by acquiring the lock
still_running_lock.acquire()
for t in threads: t.start()
signal.signal(signal.SIGINT, signal_handler)
signal.pause()
编辑:我想补充一点,如果你想弄乱数据包,透明模式下的 mitmproxy 和 iptables 似乎是一个完美的解决方案,也不需要任何客户端配置。(即它是透明的)
Python 具有scapy
库(在 Debian & amp;Ubuntu 上以python-scapy
的形式提供),可以简化低级网络数据的检索,处理和重新注入。
这里有一个简单的示例,它将所有数据从一个接口转发到另一个接口,修改 HTTP GET 请求以指向 example.com 域。
#!/usr/bin/env python
import scapy.all as scapy
import re
OWN_IP_ON_RECV_IFACE="192.168.1.128"
RECV_IFACE="wlan0"
SEND_IFACE="eth0"
def modify_packet(packet):
# example
if packet.haslayer(scapy.TCP) and packet[scapy.TCP].dport == 80 and packet[TCP].payload:
data = str(packet[scapy.TCP].payload)
modified_data = re.sub("\r\nHost: .+\r\n", "\r\nHost: example.com\r\n", data)
packet[scapy.TCP].payload = modified_data
print "Packet modified!"
return packet
def packet_received(packet):
if packet.haslayer(scapy.IP) and packet[scapy.IP].dst != OWN_IP_ON_RECV_IFACE and packet[scapy.IP].src != OWN_IP_ON_RECV_IFACE:
modified_packet = modify_packet(packet[scapy.IP])
packet_to_send = scapy.Ether() / modified_packet
scapy.sendp(packet_to_send, iface=SEND_IFACE)
print "Packet sent"
scapy.sniff(iface=RECV_IFACE, store=0, prn=packet_received)
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(36条)