python-3.x 从pcapng文件读取域名

68de4m5k  于 2023-02-26  发布在  Python
关注(0)|答案(1)|浏览(244)

我想从DNS数据包中提取域名(请求/响应)从.pcapng文件。下面的代码我用什么

def extract_domain_name(pkt):
     try:
        if pkt.dns.qry_name:
            #print (pkt.ip.src, pkt.dns.qry_name)
            return pkt.dns.qry_name
     except AttributeError as e:
        #ignore packets that aren't DNS Request
        pass
     try:
        if pkt.dns.resp_name:
            print (pkt.ip.src, pkt.dns.resp_name)
            return pkt.dns.resp_name
     except AttributeError as e:
        #ignore packets that aren't DNS Response
        pass
        

def process_pcapng_file(filename):
    # Open the pcapng file
    cap = pyshark.FileCapture(filename)

    # Extract the domain names from the DNS packets
    domains = set()
    for pkt in cap:
        #print (pkt)
        if 'DNS' in pkt:
            #domain = pkt.dns.qry_name
            domain = extract_domain_name(pkt)
            if domain is not None:
                domains.add(domain)

它只从查询数据包中提取域名,而不是从查询和响应中提取域名。2问题是什么呢?3然而,
我尝试使用不带try:if pkt.dns.resp_name:,但得到了AttributeError

cl25kdpy

cl25kdpy1#

感谢您发布样本采集;这很有用。
我认为您的代码对我有效而对您无效的原因是,在您的示例捕获中,仅有的回复是SERVFAIL消息:

$ tcpdump -nn -r sample.pcap port domain | awk '{print $7}' | sort | uniq -c
  38365 A?
  38393 ServFail

对于SERVFAIL消息,pkt.dns似乎没有resp_name属性。
它只从查询数据包中提取域名,而不是从查询和响应中提取域名
只是为了明确:在示例捕获中,* 没有有效查询响应 *,因此pkt.dns.resp_name从未定义过。
这里有几件事需要考虑:
1.如果您的逻辑有效:

if pkt.dns.qry_name:
  return pkt.dns.qry_name
if pkt.dns.resp_name:
  return pkt.dns.resp_name

您永远不会到达第二个if语句,因为查询响应还包括原始查询(因此您将始终返回pkt.dns.qry_name)。
1.您真的关心resp_name吗?在所有情况下,pkt.dns.resp_name要么匹配pkt.dns.qry_name,要么不存在。
在我看来,您可以将代码简化为:

def process_pcapng_file(filename):
    cap = pyshark.FileCapture(filename)

    return set(
        pkt.dns.qry_name
        for pkt in cap
        if pkt.highest_layer == "DNS" and pkt.dns.qry_name
    )

但是如果你想使用现有的extract_domain_name函数,你需要反向检查resp_nameqry_name

def extract_domain_name(pkt):
    try:
        if pkt.dns.resp_name:
            return pkt.dns.resp_name
    except AttributeError:
        pass

    try:
        if pkt.dns.qry_name:
            return pkt.dns.qry_name
    except AttributeError:
        pass

您可以通过将异常处理替换为hasattr来缩短时间:

def extract_domain_name(pkt):
    if hasattr(pkt.dns, "resp_name") and pkt.dns.resp_name:
        return pkt.dns.resp_name

    if hasattr(pkt.dns, "qry_name") and pkt.dns.qry_name:
        return pkt.dns.qry_name

相关问题