Отправка пользовательского кадра / пакета в Python

1

Я прочитал много статей и нашел, как отправлять пользовательские пакеты на основе IP, используя сокет (AF_INET, SOCK_RAW, IPPROTO_RAW). Но я хочу отправить полностью настраиваемый пакет, начиная с заголовка Ethernet. Я не могу отправить пакет ARP, если я не могу сформировать заголовок Ethernet, поскольку ARP не использует IP. Пожалуйста помоги! PS Я на Windows 7, а не на Linux :(

Теги:
networking

2 ответа

0

В python самым простым способом является использование кросс-платформенной библиотеки scapy. Хорошо известно, что

Scapy

Вы можете нюхать, отправлять... много пакетов, добавлять свои собственные протоколы, использовать существующие... и работает почти на всех платформах. (В окнах используется Npcap/Winpcap)

Затем вы можете создать ARP-пакет, используя

from scapy.all import *
pkt = ARP()
pkt.show()
sendp(Ether(dst=..., src=...)/pkt)

Что создаст такие пакеты

###[ ARP ]###
hwtype= 0x1
ptype= 0x800
hwlen= 6
plen= 4
op= who-has
hwsrc= 00:50:56:00:1e:3d
psrc= 212.83.148.19
hwdst= 00:00:00:00:00:00
pdst= 0.0.0.0

Чтобы создать пакет, используйте оператор /

ether = Ether()
ether.src = "00:00:00:00:00:00"
ether.dst = "ff:ff:ff:ff:ff:ff"
arp = ARP()
[edit arp.psrc, arp.pdst, arp.hwsrc, arp.hwdst]
packet = ether/arp
sendp(packet) # sens packet on layer 2

Взгляните на документацию Scapy

  • 0
    Спасибо! Я уже использовал scapy, но я не пытался импортировать его в свои программы.
0

Конечно, нет кросс-платформенного способа делать то, что вы хотите.

Python просто передает эти значения в базовый C API. Таким образом, на платформе с полным API-интерфейсом BSD, включая packet интерфейс, вы можете просто использовать AF_PACKET и другие соответствующие флаги. (Я думаю, вы бы хотели ETH_P_ALL или ETH_P_802_2 а не IPPROTO_RAW, или вы могли бы хотеть SOCK_DGRAM... в любом случае, прочитайте свой man packet платформы и определите его на основе того, что вам действительно нужно делать.) В Linux по крайней мере большинство этих флагов должен быть доступен в модуле SOCKET; на других Unix, их часто не получают, поэтому вы должны вручную искать их в заголовках системы и использовать жестко закодированные константы в вашем коде.

К сожалению, если вы работаете в Windows, это не приносит пользы. В то время как у WinSock есть функция, они называют TCP/IP Raw Sockets, доступ к которым осуществляется через SOCK_RAW, а последние версии Python действительно раскрывают это, это просто эмуляция небольшого подмножества того, что могут делать реальные реализации сокетов BSD, и никоим образом не предлагает идти ниже уровня IP (отсюда и название функции).

Решение Microsoft для этого заключалось в том, что вы должны написать провайдер TDI с DDK, который будет реализовывать любой протокол, который вы хотели бы представить в качестве другого протокола WinSock, а затем ваш код на уровне приложения мог бы использовать этот протокол так же, как и использовать, например, TCP. Из связанного документа выше, похоже, что это устарело, но замена похожа на ту же идею, но с разными аббревиатурами (и, предположительно, с разными API).

С другой стороны, я уверен, что Windows уже поставляется с протоколами ARP, ICMP и любыми другими протоколами, необходимыми для его инструментов usermode (потому что они, очевидно, не могут быть написаны вокруг сырых пакетов). Я просто не знаю, как получить к ним доступ.


Насколько я знаю, обычной альтернативой является использование WinPcap.

Хотя это было первоначально разработано как библиотека захвата пакетов, в нем также реализован полный интерфейс сокета уровня ссылки, который вы можете использовать для отправки и приема необработанных кадров.

И для него есть обертки Python, такие как WinPcapy.

Поэтому, пока вы можете потребовать установки драйвера WinPcap, вы можете написать код ARP и т.д. В Windows на Python. Это просто отличает его от Unix.

На самом деле, один из примеров на первой странице WinPcapY, "Easy Packet send", должен начать вас:

from winpcapy import WinPcapUtils
# Build a packet buffer
# This example-code is built for tutorial purposes, for actual packet crafting use modules like dpkt
arp_request_hex_template = "%(dst_mac)s%(src_mac)s08060001080006040001" \
                           "%(sender_mac)s%(sender_ip)s%(target_mac)s%(target_ip)s" + "00" * 18
packet = arp_request_hex_template % {
    "dst_mac": "aa"*6,
    "src_mac": "bb"*6,
    "sender_mac": "bb"*6,
    "target_mac": "cc"*6,
    # 192.168.0.1
    "sender_ip": "c0a80001",
    # 192.168.0.2
    "target_ip": "c0a80002"
}
# Send the packet (ethernet frame with an arp request) on the interface
WinPcapUtils.send_packet("*Ethernet*", packet.decode("hex"))
  • 0
    Спасибо! Но я на Windows 7 :( Я был очень разочарован, когда узнал, что AF_PACKET не поддерживается o Windows. Могу ли я сделать то, что я хочу на C?
  • 0
    @ ДенисМальований У Windows есть совершенно другой способ сделать это под прикрытием, а SOCK_RAW - это просто неуклюжая эмуляция части API-интерфейса raw сокетов BSD, которой достаточно для отправки пользовательских заголовков IP. IIRC, рекомендуемый способ сделать то, что вы хотите, это использовать DDK для написания протокола и предоставления его через Winsock, а затем код вашего приложения просто обрабатывает его так же, как они обращались бы с TCPv4 или чем-то еще, за исключением того, что я думаю, что Winsock уже поставляется с ARP и другими протоколами, поэтому вам не нужно их писать. Но я уже давно устарел и запутался в этом.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню