首页 > 解决方案 > DNS 标头作为原始数据与 scapy 一起发送

问题描述

我正在尝试使用 python 在 linux 机器上设置一个套接字服务器,作为我的网络团队的一个辅助项目。机器将监听 53 端口,并使用 scapy 响应 dns 查询。

现在,询问部分一切正常,至少我认为,当我将服务器设置为我的 dns 服务器并尝试使用互联网时,我并没有真正进入该部分,但是当我尝试 tcpdump 时,它看起来像一个普通数据包。

无论如何,当我从服务器响应客户端时,数据包正在发送,其中包含我需要的所有标头,包括 DNS、DNSQR 和 DNSRR,正如我在 tcpdump 中看到的那样。但是,当客户端收到数据包时,它只有 IP 和 UDP 标头,因为其余部分作为原始数据发送。

正如我之前提到的,我尝试查看 wireshark 和 tcpdump 并看到服务器和客户端之间发送的差异,我看到从服务器端,回复数据包被标记为 malformed packet

我不完全确定是否是这种情况,正如我在互联网上看到的那样,这只是因为我没有完全欺骗它。

代码:

客户端数据包:

pkt = IP(dst='<Server IP>')/UDP(dport=53,sport=RandShort())/DNS(rd=1,qd=DNSQR(qname='dns.google'))

服务器数据包:

def build_dns_response(src_addr,og_sport,dns_qtype,dns_qname,response_type=True,response_name=None):
    '''
    a function that will build a DNS response packet back to the sender, according to the parameters that are recieved.
    dns_qname = url/ip that the sender asked for.
    og_sport = original source port, will be used as the dport of this packet
    src_addr = source address of the original packet, will be used as the destination of this packet.
    dns_qtype = the question type of the original request, 1 stands for type A, and 12 for PTR
    response_type = will indicate if the server responds with an answer of 'ok' or 'name-error' on the 'rcode' field,True for ok,False for name-error
    response_name = the response that the server will send as a result of the dns request, in case that a request matches to a database query.
    '''
    if response_type is True:
        pkt = IP(src='<Server IP>',dst=src_addr)/\
                                UDP(sport=53,dport=og_sport)/\
                                DNS(opcode=0,rd=1,rcode='ok',nscount=1,ancount=1,qd=DNSQR(qname=dns_qname,qtype=dns_qtype),an=DNSRR(rrname=dns_qname,type=dns_qtype,rdata=response_name))

服务器发送的数据包:

###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 1
  flags     = 
  frag      = 0
  ttl       = 64
  proto     = udp
  chksum    = None
  src       = <Server IP>
  dst       = <client IP >
  \options   \
###[ UDP ]### 
     sport     = domain
     dport     = 25151
     len       = None
     chksum    = None
###[ DNS ]### 
        id        = 0
        qr        = 0
        opcode    = QUERY
        aa        = 0
        tc        = 0
        rd        = 1
        ra        = 0
        z         = 0
        ad        = 0
        cd        = 0
        rcode     = ok
        qdcount   = 1
        ancount   = 1
        nscount   = 1
        arcount   = 0
        \qd        \
         |###[ DNS Question Record ]### 
         |  qname     = 'dns.google.'
         |  qtype     = A
         |  qclass    = IN
        \an        \
         |###[ DNS Resource Record ]### 
         |  rrname    = 'dns.google.'
         |  type      = A
         |  rclass    = IN
         |  ttl       = 0
         |  rdlen     = None
         |  rdata     = 8.8.8.8
        ns        = None
        ar        = None

客户端收到的数据包:

###[ IP ]###
  version   = 4
  ihl       = 5
  tos       = 0x0
  len       = 82
  id        = 1
  flags     =
  frag      = 0
  ttl       = 64
  proto     = udp
  chksum    = 0x6686
  src       = <Server IP>
  dst       = <Client IP>
  \options   \
###[ UDP ]###
     sport     = domain
     dport     = 25151
     len       = 62
     chksum    = 0xf99
###[ Raw ]###
        load      = '\x00\x00\x01\x00\x00\x01\x00\x01\x00\x01\x00\x00\x03dns\x06google\x00\x00\x01\x00\x01\x03dns\x06google\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x04\x08\x08\x08\x08'

我想值得一提的是,整个对话是从主机 PC 到托管在其上的 vm。

提前感谢您的帮助!

标签: pythonsocketsdnsscapy

解决方案


推荐阅读