如何使用 RAW-SOCKETS 打开端口?

How can I open a Port with RAW-SOCKETS?

我正在 Python3 中使用 AF_PACKET 处理 RAW-Sockets。

如果我发送此 DNS 查询数据包 -> 我会得到答复,但是:

如何使用 AF_Packet 和 RAW_SOCKETS 打开端口?

#!/usr/bin/python3.9
# -*- coding: utf-8 -*-

import socket
import time
from struct import pack

ETH_P_ALL = 3

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))

def dns_query():
    s.bind(("enp4s0", 0))

    frame = [
        ### Ether Frame ###
        pack('6B', *(0x10, 0xfe, 0xed, 0x57, 0xef, 0xdc)),
        s.getsockname()[4],
        pack('!H', 0x0800),
        #########################

        ### IPv4 Header ###
        pack('B', 0x45),
        pack('B', 0x00),
        pack('!H', 0x003C),
        pack('!H', 0xcdaf),
        pack('B', 0x00),
        pack('B', 0x00),
        pack('B', 0x40),
        pack('B', 0x11),
        pack('!H', 0xea55),
        pack('4B', *(0xc0, 0xa8, 0x00, 0x02)),
        pack('4B', *(0x01, 0x01, 0x01, 0x01)),

        ### UDP ###
        # Source-Port
        pack('!H', 0xe1c7),  # Port 57799
        # Destination-Port
        pack('!H', 0x0035),  # Port 53
        pack('!H', 0x0028),
        pack('!H', 0x0000),

        ### DNS ###
        pack('!H', 0x26d9),
        pack("!H", 0x0120),
        pack("!H", 0x0001),
        pack("!H", 0x0000),
        pack("!H", 0x0000),
        pack("!H", 0x0000),

        pack("B", 0x03),
        pack("!3B", *(0x77, 0x77, 0x77)),
        pack("B", 0x07),
        pack("!7B", *(0x6f, 0x72, 0x65, 0x69, 0x6C, 0x6C, 0x79)),
        pack("B", 0x02),
        pack("!H", 0x6465),
        pack("B", 0x00),
        pack("!H", 0x0001), # A-Record
        pack("!H", 0x0001)
    ]
    s.sendall(b''.join(frame))
    time.sleep(1)
    s.close()


dns_query()

没有办法“用 AF_PACKET 打开一个端口”。这里的问题是你告诉远程系统你正在从端口 UDP 57799 调用,但你的本地 OS 内核知道没有打开这样的端口。

可以用AF_INET数据报(UDP)套接字单独打开一个端口,bind它获得一个端口号,然后使用那个AF_PACKET 代码中的端口号。如果您在操作时保持另一个 UDP 套接字打开,这应该可以防止 ICMP 错误,但 DNS 响应数据报很可能会堆积在 UDP 套接字的队列中,等待您将它们拉下来(因为内核本身也会看到它们并且知道它们是针对您的 UDP 套接字的)。这非常好,因为您这样做是为了教育/探索目的,但不是可行的生产机制。

最重要的是,您正试图表现得像内核,但没有办法告诉内核您正试图为它完成它的工作。