DNS隐蔽信道是什么

DCC是指利用DNS数据包中的可定义字段秘密传递信息的通道。其中,“DNS 协议”是目前网络上使用的标准域名解析协议;“可定义字段”是DNS 数据包中的 QNAME 字段、RDATA 字段及RawUDP字段。利用DNS数据包可以构建2种信道:存储信道及时间信道。DCC可以被用于数据泄露、命令控制(C&C, command & control)及绕过Wi-Fi连接注册等恶意行为,进而可以用于远控木马(RAT, remote access trojan)、僵尸网络(Botnet)、勒索软件(Ransomeware)、高级持续性威胁(APT, advanced persistent threat)等绝大多数网络攻击。

DNS隐蔽信道攻击

YPPMaP

  1. 被控端把要传输的内容封装(protocol wrap)在dns query请求包中,发起一次正常的dns解析请求;
  2. 当被控端向任意一台DNS服务器请求该域名下的子域名时,本地 DNS服务器无论是通过递归查询还是迭代查询,都会向外转发这个DNS请求,最终这个DNS请求都会被送到黑客控制的权威NS服务器中(这意味着黑客必须事先配置好NS以及A记录解析);
  3. NS服务器控制端解析请求报文,得到被控端传来的信息,然后将攻击控制命令通过封装在DNS响应报文中;
  4. 从而实现双方通信,所有的通信都必须由被控端(client端)主动发起,不断回传数据并接受新指令。

检测方法

分为 机器学习方法和深度学习方法.

特征构建

import os
import math
import scapy.sendrecv
from scapy.all import rdpcap
import scapy.layers.dns

def shannon(b):
    '''熵值计算'''
    slen = len(b)
    freqs = (float(b.count(c)) / slen for c in set(b))
    return round(-sum((prob * math.log(prob, 2.0) for prob in freqs)),2)

def check_pcap_file(pcap_path):
    '''校验pcap包'''
    check_result = False
    if pcap_path.endswith(("pcap","pcapng")):
        check_result = True
    return check_result

def read_pcaps(pcap_path):
    '''读取pcap包获取特征'''
    check_result = check_pcap_file(pcap_path)
    if check_result:
        pkts = rdpcap(pcap_path)

        for pkt in pkts:
            dns = pkt.lastlayer()
            attrs = [0]*17
            attrs[0] = dns.qd.qname.decode("utf-8", errors="replace") #域名
            attrs[1] = len(dns.qd.qname) # Length of the query name.
            attrs[2] = shannon(dns.qd.qname) # 域名的熵
            attrs[3] = dns.qdcount # Number of questions.
            attrs[4] = dns.qd.qtype # Query type.
            attrs[5] = dns.ancount # Number of answers.
            attrs[6] = dns.arcount # Number of additional records.
            attrs[7] = dns.nscount # Numner of Name Server count.
            if dns.ancount:
                attrs[8] = len(dns.an.rrname) #  Answer record RRName length.
                attrs[9] = shannon(dns.an.rrname) # Answer record RRName shannon entropy.
                attrs[10] = dns.an.type # Answer record type.
                attrs[11] = dns.an.ttl # Answer record TTL

                if dns.an.rdata:
                    attrs[12] = len(dns.an.rdata) # Answer RData length.
                    attrs[13] = shannon(dns.an.rdata) # Answer RData shannon entropy.

            if dns.arcount:
                attrs[14] = len(dns.ar.rrname) # Additional record RRName length.
                attrs[15] = shannon(dns.ar.rrname) # Additional record RRName shanonn entropy.
                attrs[16] = dns.ar.type # Additional record RRName type.
            print(attrs)

if __name__=="__main__":
    pcap_path = "/Users/macintosh/Desktop/scapy_udp/datasets/iodine32_cname_down.pcapng"
    read_pcaps(pcap_path)