概述
python中udp W those packets flying through the network… 那些通过网络飞行的数据包 …… In this post, we go through the steps to build a UDP Host discovery tool. First, we see how we deal with raw sockets and we write a simple sniffer (to view and decode network packets). Then we multithread this process within a subnet, which will result in our scanner. 在本文中,我们将逐步构建UDP主机发现工具 。 首先,我们了解如何处理原始套接字 然后我们编写一个简单的嗅探器(以查看和解码网络数据包)。 然后,我们在子网中对该进程进行多线程处理,这将导致我们的扫描程序。 The cool thing about raw sockets is that they allow access to low-level networking information. For example, we can use it to check IP and ICMP headers, which are in layer 3 of the OSI model (the network layer). 原始套接字的有趣之处在于它们允许访问底层网络信息。 例如,我们可以使用它来检查IP和ICMP标头,它们位于OSI模型的第3层(网络层)中。 On the other hand, the cool thing about using UDP datagrams is that, differently from TCP, they do not bring much overhead when sent across an entire subnet (remember TCP handshaking). All we need to do is wait for the ICMP responses saying whether the hosts are available or closed (unreachable). 另一方面,使用UDP数据报的妙处在于,与TCP不同的是,当它们在整个子网中发送时,它们不会带来太多开销(请记住TCP 握手 )。 我们需要做的就是等待ICMP响应说出主机是可用的还是关闭的(不可达)。 ICMP is essentially a special control protocol that issues error reports and can control the behavior of machines in data transfer. ICMP本质上是一种特殊的控制协议,它发出错误报告并可以控制数据传输中机器的行为。 We start with a very simple task: with Python’s socket library, we write a very simple packet sniffer. In this sniffer, we create a raw socket, and then we bind it to the public interface. 我们从一个非常简单的任务开始:使用Python的套接字库,我们编写了一个非常简单的数据包嗅探器。 在此嗅探器中,我们创建一个原始套接字,然后将其绑定到公共接口。 The network interface should be in promiscuous mode, which means that every packet that the network card sees is captured, even those that are not destined to the host. 网络接口应处于混杂模式 ,这意味着将捕获网卡看到的每个数据包,即使不是发往主机的数据包也是如此。 One detail to remember is that things are slightly different if we are using Windows: in this case, we need to send an IOCTL package to set the interface to promiscuous mode. In addition, while Linux needs to use ICMP, Windows allows us to sniff the incoming packets independently of the protocol: 要记住的一个细节是,如果我们使用Windows,则情况会略有不同:在这种情况下,我们需要发送IOCTL程序包以将接口设置为混杂模式 。 另外,尽管Linux需要使用ICMP,但Windows允许我们独立于协议来嗅探传入的数据包: To test this script, we run the following command in one terminal window: 为了测试此脚本,我们在一个终端窗口中运行以下命令: Then, in a second window, ping or traceroute some address, for example, www.google.com. The results should look like this: 然后,在第二个窗口中ping或traceroute一些地址,例如www.google.com 。 结果应如下所示: Now we need to decode these headers. 现在我们需要解码这些标头。 A typical IP header has the following structure, where each field belongs to a variable (this header is originally written in C): 典型的IP标头具有以下结构,其中每个字段都属于一个变量(此标头最初用C编写 ): In the same way, ICMP can vary in its content but each message contains three elements that are consistent: type and code (tells the receiving host what type of ICMP message is arriving for decoding) and checksum fields. 同样,ICMP的内容也可以不同,但是每个消息都包含三个一致的元素: 类型和代码 (告诉接收主机要解码的ICMP消息类型是什么)和校验和字段。 For our scanner, we are looking for a type value of 3 and a code value of 3, which are the Destination Unreachable class and Port Unreachable errors in ICMP messages. 对于我们的扫描器,我们正在寻找类型值3和代码值3 ,它们是ICMP消息中的Destination Unreachable类和Port Unreachable 错误 。 To represent this header, we create a class, with the help of Python’s ctypes library: 为了表示此标头,我们借助Python的ctypes库创建一个类: We are now ready to write our IP/ICMP header decoder. The script below creates a sniffer socket (just as we did before) and then it runs a loop to continually read in packets and decode their information. 现在我们准备编写我们的IP / ICMP标头解码器 。 下面的脚本创建一个嗅探器套接字(就像我们之前所做的那样),然后运行循环以不断读取数据包并解码其信息。 For the IP header, the code reads the packet, unpacks the first 20 bytes to the raw buffer, and then prints the header variables. 对于IP标头,代码读取数据包,将前20个字节解压缩到原始缓冲区中,然后打印标头变量。 The ICMP header data comes right after it, so let’s sketch the following snippet: ICMP标头数据紧随其后,因此让我们绘制以下代码片段: In one terminal window, send a ping, which should return something like this (notice the ICMP type 0): 在一个终端窗口中,发送ping ,该命令应返回类似以下内容(注意,ICMP类型为0): Then compare that with the results coming from our script: 然后将其与我们脚本的结果进行比较: Now, let us look at traceroute instead: 现在,让我们看一下traceroute : We should get something like this with our script (notice the several types of ICMP responses): 我们应该通过脚本获得类似的信息(注意ICMP响应的几种类型 ): We are ready to write our full scanner. First, let’s install netaddr, which is a Python library for representing and manipulating network addresses. 我们准备编写完整的扫描仪。 首先,让我们安装netaddr ,这是一个用于表示和操作网络地址的Python库。 Netaddr supports the ability to work with IPv4 and IPv6 addresses and subnets MAC addresses, among others. This is very useful for our problem since we want to be able to use a subnet mask such as 192.168.1.0/24. Netaddr支持使用IPv4和IPv6地址以及子网MAC地址等功能。 这对于我们的问题非常有用,因为我们希望能够使用诸如192.168.1.0/24之类的子网掩码。 We can quickly test this library with the following (which should print “OK”): 我们可以使用以下命令快速测试该库(应该显示“ OK”): To finish writing our scanner, we put together everything we have done so far, and then we add a loop to spray UDP datagrams with a string signature to all the addresses within our target subnet. 为了完成我们的扫描程序的编写,我们将到目前为止已完成的所有工作放在一起,然后添加一个循环,以将带有字符串签名的UDP数据报喷射到目标子网内的所有地址。 Each packet needs to be sent in a separated thread, to make sure that we are not interfering with the sniff responses: 每个数据包都需要在单独的线程中发送,以确保我们不会干扰嗅探响应: Finally, we are ready to run our scanner: 最后,我们准备运行扫描仪: By the way, the results from our scanner can be checked against the values of the IP addresses in your router’s DHCP table. They should match! 顺便说一句,可以根据路由器的DHCP表中 IP地址的值来检查扫描仪的结果。 他们应该匹配! I hope this post sheds a bit of light on how low-level hacking works in Python, empowering hackers and developers to experiment and innovate more! 我希望这篇文章能使您对Python中的低级黑客如何工作有所了解,使黑客和开发人员有能力进行更多的实验和创新! Resources and source codes related to this tutorial are available here. 与本教程相关的资源和源代码可在此处获得 。 翻译自: https://medium.com/python-for-the-utopian/building-a-udp-scanner-in-python-84e62947aab7 python中udp
编写数据包嗅探器 (Writing a Packet Sniffer)
import os
import socket# host to listen
HOST = '192.168.1.114'def sniffing(host, win, socket_prot): while True: sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_prot) sniffer.bind((host, 0)) # include the IP headers in the captured packets
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) if win == 1:
sniffer.ioctl(socket.SIO_RCVALL, socket_RCVALL_ON) # read in a single packet
print(sniffer.recvfrom(65565))
def main(host): if os.name == 'nt':
sniffing(host, 1, socket.IPPROTO_IP) else:
sniffing(host, 0, socket.IPPROTO_ICMP)
if __name__ == '__main__':
main(HOST)> sudo python sniffer.py
> sudo python raw_socket.py('Ex00x00Txb3xecx00x005x01xe4x13J}xe1x11xc0xa8x01rx00x00vxdfxxa2x00x01srx98Tx00x00x00x008xe3rx00x00x00x00x00x10x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1f !"#$%&'()*+,-./01234567', ('74.125.225.17', 0))
('Ex00x00Txb4x1bx00x005x01xe3xe4J}xe1x11xc0xa8x01rx00x00~xd7xxa2x00x02trx98Tx00x00x00x00/xearx00x00x00x00x00x10x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1f !"#$%&'()*+,-./01234567', ('74.125.225.17', 0)) 解码IP和ICMP层 (Decoding the IP and ICMP Layers)
IP头 (The IP Header)
ICMP标头 (The ICMP Header)
import ctypesclass ICMP(ctypes.Structure):
_fields_ = [
('type', ctypes.c_ubyte),
('code', ctypes.c_ubyte),
('checksum', ctypes.c_ushort),
('unused', ctypes.c_ushort),
('next_hop_mtu',ctypes.c_ushort)
] def __new__(self, socket_buffer):
return self.from_buffer_copy(socket_buffer)
def __init__(self, socket_buffer):
pass 编写标题解码器 (Writing the Header Decoder)
import socket
import os
import struct
import ctypes
from ICMPHeader import ICMP
# host to listen on
HOST = '192.168.1.114'def main(): socket_protocol = socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind(( HOST, 0 )) sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) while True:
raw_buffer = sniffer.recvfrom(65565)[0] ip_header = raw_buffer[0:20] iph = struct.unpack('!BBHHHBBH4s4s' , ip_header) # Create our IP structure
version_ihl = iph[0] version = version_ihl >> 4 ihl = version_ihl & 0xF iph_length = ihl * 4 ttl = iph[5] protocol = iph[6] s_addr = socket.inet_ntoa(iph[8]); d_addr = socket.inet_ntoa(iph[9]); print('IP -> Version:' + str(version) + ', Header Length:' + str(ihl) +
', TTL:' + str(ttl) + ', Protocol:' + str(protocol) + ', Source:'
+ str(s_addr) + ', Destination:' + str(d_addr)) # Create our ICMP structure
buf = raw_buffer[iph_length:iph_length + ctypes.sizeof(ICMP)] icmp_header = ICMP(buf) print('ICMP -> Type:{0}, Code:{1}'.format((icmp_header.type, icmp_header.code)))
if __name__ == '__main__':
main() 测试解码器 (Testing the Decoder)
> ping www.google.comPING www.google.com (74.125.226.16) 56(84) bytes of data.
64 bytes from lga15s42-in-f16.1e100.net (74.125.226.16): icmp_seq=1 ttl=56 time=15.7 ms
64 bytes from lga15s42-in-f16.1e100.net (74.125.226.16): icmp_seq=2 ttl=56 time=15.0 ms
(...)> sudo python ip_header_decode.pyIP -> Version:4, Header Length:5, TTL:56, Protocol:1, Source:74.125.226.16, Destination:192.168.1.114
ICMP -> Type:0, Code:0
IP -> Version:4, Header Length:5, TTL:56, Protocol:1, Source:74.125.226.16, Destination:192.168.1.114
ICMP -> Type:0, Code:0
(...)> traceroute www.google.comtraceroute to www.google.com (74.125.226.50), 30 hops max, 60 byte packets
1 * * *
2 * * *
3 67.59.255.137 (67.59.255.137) 17.183 ms 67.59.255.129 (67.59.255.129) 70.563 ms 67.59.255.137 (67.59.255.137) 21.480 ms
4 451be075.cst.lightpath.net (65.19.99.117) 14.639 ms rtr102.wan.hcvlny.cv.net (65.19.99.205) 24.086 ms 451be075.cst.lightpath.net (65.19.107.117) 24.025 ms
5 64.15.3.246 (64.15.3.246) 24.005 ms 64.15.0.218 (64.15.0.218) 23.961 ms 451be0c2.cst.lightpath.net (65.19.120.194) 23.935 ms
6 72.14.215.203 (72.14.215.203) 23.872 ms 46.943 ms *
7 216.239.50.141 (216.239.50.141) 48.906 ms 46.138 ms 46.122 ms
8 209.85.245.179 (209.85.245.179) 46.108 ms 46.095 ms 46.074 ms
9 lga15s43-in-f18.1e100.net (74.125.226.50) 45.997 ms 19.507 ms 16.607 ms> sudo python ip_header_decode.pyIP -> Version:4, Header Length:5, TTL:252, Protocol:1, Source:65.19.99.117, Destination:192.168.1.114
ICMP -> Type:11, Code:0
(...)
IP -> Version:4, Header Length:5, TTL:250, Protocol:1, Source:72.14.215.203, Destination:192.168.1.114
ICMP -> Type:11, Code:0
IP -> Version:4, Header Length:5, TTL:56, Protocol:1, Source:74.125.226.50, Destination:192.168.1.114
ICMP -> Type:3, Code:3
IP -> Version:4, Header Length:5, TTL:249, Protocol:1, Source:216.239.50.141, Destination:192.168.1.114
ICMP -> Type:11, Code:0
(...)
IP -> Version:4, Header Length:5, TTL:56, Protocol:1, Source:74.125.226.50, Destination:192.168.1.114
ICMP -> Type:3, Code:3 编写扫描仪 (Writing the Scanner)
安装netaddr (Installing netaddr)
> sudo pip install netaddr
import netaddrip = '192.168.1.114'
if ip in netaddr.IPNetwork('192.168.1.0/24'):
print('OK!') 输入扫描仪 (Enter the Scanner)
import os
import time
import socket
import struct
import ctypes
import threadingfrom netaddr import IPNetwork, IPAddress
from ICMPHeader import ICMP# host to listen on
HOST = '192.168.1.114'# subnet to target (iterates through all IP address in this subnet)
SUBNET = '192.168.1.0/24'# string signature
MESSAGE = 'hellooooo'# sprays out the udp datagram
def udp_sender(SUBNET, MESSAGE): time.sleep(5)
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) for ip in IPNetwork(SUBNET):
try:
sender.sendto(MESSAGE, (str(ip), 65212)) except:
passdef main(): t = threading.Thread(target=udp_sender, args=(SUBNET, MESSAGE)) t.start() socket_protocol = socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind(( HOST, 0 )) sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # continually read in packets and parse their information
while True: raw_buffer = sniffer.recvfrom(65565)[0] ip_header = raw_buffer[0:20] iph = struct.unpack('!BBHHHBBH4s4s' , ip_header) # Create our IP structure
version_ihl = iph[0] ihl = version_ihl & 0xF iph_length = ihl * 4 src_addr = socket.inet_ntoa(iph[8]); # Create our ICMP structure
buf = raw_buffer[iph_length:iph_length + ctypes.sizeof(ICMP)] icmp_header = ICMP(buf) # check for the type 3 and code and within our target subnet
if icmp_header.code == 3 and icmp_header.type == 3:
if IPAddress(src_addr) in IPNetwork(SUBNET):
if raw_buffer[len(raw_buffer) - len(MESSAGE):] == MESSAGE:
print(f'Host up: {src_addr}')
if __name__ == '__main__':
main()> sudo python scanner.pyHost up: 192.168.1.114
(...) 漂亮整齐! ♀♀️ (Pretty neat! ????????♀️)
感谢您的阅读! (Thank you for reading!)
最后
以上就是洁净枕头为你收集整理的python中udp_在python中构建udp扫描器 编写数据包嗅探器 (Writing a Packet Sniffer) 解码IP和ICMP层 (Decoding the IP and ICMP Layers) 编写扫描仪 (Writing the Scanner) 感谢您的阅读! (Thank you for reading!)的全部内容,希望文章能够帮你解决python中udp_在python中构建udp扫描器 编写数据包嗅探器 (Writing a Packet Sniffer) 解码IP和ICMP层 (Decoding the IP and ICMP Layers) 编写扫描仪 (Writing the Scanner) 感谢您的阅读! (Thank you for reading!)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复