Analysis of ISC BIND TKEY Query Response Handling DoS (CVE-2016-9131)

Another TKEY record-related bug in BIND has been fixed with a patch from the Internet Systems Consortium (ISC) that was released just after the New Year. This bug may take down BIND recursive servers by sending a simple query response with TKEY record, thereby causing a denial of service (DoS).

This potential DoS vulnerability is caused by an assertion failure in Resolver.c when caching the DNS response with TKEY Record. In this post we will analyze the BIND source codes and expose the root cause of this vulnerability.

The TKEY record (record type 249) is used to operate the secret keys information shared between DNS resolvers and servers. It is not supposed to be in the DNS ANY query response, which responds to the DNS query with Type ANY, nor stored or cached by DNS recursive servers. This bug is caused by a mismatch error when DNS recursive servers try to cache the TKEY record in the DNS ANY query response.

The following code snippet was taken from BIND version 9.10.4-P4. Comments added by me have been highlighted.

Resolver.c:

5246     static inline isc_result_t

5247     cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,

5248         isc_stdtime_t now)

5249     {

               … 

  // caching the TKEY Record in the DNS ANY query response

5620        result = dns_db_addrdataset(fctx->cache,

5621               node, NULL, now,

5622               rdataset,

5623               options,

5624               addedrdataset);

 

db.c:

749     isc_result_t

750     dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,

751          isc_stdtime_t now, dns_rdataset_t *rdataset,

752          unsigned int options, dns_rdataset_t *addedrdataset)

753     {

754      /*

755       * Add 'rdataset' to 'node' in version 'version' of 'db'.

756       */

757    

758      REQUIRE(DNS_DB_VALID(db));

759      REQUIRE(node != NULL);

760      REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||

761       ((db->attributes & DNS_DBATTR_CACHE) != 0 &&

762        version == NULL && (options & DNS_DBADD_MERGE) == 0));

763      REQUIRE((options & DNS_DBADD_EXACT) == 0 ||

764       (options & DNS_DBADD_MERGE) != 0);

765      REQUIRE(DNS_RDATASET_VALID(rdataset));

766      REQUIRE(dns_rdataset_isassociated(rdataset));

             //db->rdclass comes from the ANY query which is "1", rdataset->rdclass is the "Class" property of TKEY record, which is "0xff", they doesn't match and assertion failure occurs.

767      REQUIRE(rdataset->rdclass == db->rdclass);

Following is the image showing the abortion of the affected DNS server:

Please note that authentication is NOT required to exploit this vulnerability.

Fortinet released IPS signature ISC.BIND.TKEY.Query.Reponse.Handling.DoS to address this vulnerability.

 

https://blog.fortinet.com/feed