📜 ⬆️ ⬇️

BIND vulnerability allows you to “drop” any server: how and why it works



Almost a month ago, on January 11, 2017, the developers of the most popular open source DNS server BIND released fixes for four new vulnerabilities that allow a remote attacker to crash a DNS server. Among the vulnerabilities is CVE-2016-9147, which will be discussed further. The attack does not require special conditions except for the need for the attacker to see the outgoing traffic from the vulnerable server.

We set out to create rules (NAD) to detect the exploitation of these vulnerabilities over the network - in order to do this, we had to get deeper into the BIND code and write our own exploits. Our analysis will help you understand how everything works within such a popular DNS server, as well as learn about the mistakes made by the project developers and possible solutions to these problems.
')

What is the problem


Under the greatest risk are recursive servers with DNSSEC support, therefore, we will consider the case of recursive query later.

The description of the patch states that a certain combination of DNSSEC records in response to a recursive query can cause a denial of service to the server or, in a simple way, crash. In addition, the developers add that this combination of fields is not found in normal DNS traffic.

To further understand the problem, you need to examine the publicly available patch for this CVE. The patch fixes just a few lines of code in one of the modules responsible for handling DNS responses.

--- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -6984,15 +6984,19 @@ answer_response(fetchctx_t *fctx) { * a CNAME or DNAME). */ INSIST(!external); - if ((rdataset->type != - dns_rdatatype_cname) || - !found_dname || - (aflag == - DNS_RDATASETATTR_ANSWER)) + /* + * Don't use found_cname here + * as we have just set it + * above. + */ + if (cname == NULL && + !found_dname && + aflag == + DNS_RDATASETATTR_ANSWER) { have_answer = ISC_TRUE; - if (rdataset->type == - dns_rdatatype_cname) + if (found_cname && + cname == NULL) cname = name; name->attributes |= DNS_NAMEATTR_ANSWER; 

As we can see, the patch corrects the logical error in the condition

 if ((rdataset->type != dns_rdatatype_cname) || !found_dname || (aflag == DNS_RDATASETATTR_ANSWER))  if (cname == NULL && !found_dname && aflag == DNS_RDATASETATTR_ANSWER) 

Execution of all three expressions has become mandatory for changing the have_answer variable to true. This is necessary to determine if the packet contained the answer to our query:



Thus, it becomes obvious that the exploitation of the vulnerability occurs through the incomplete fulfillment of the condition from the patch. Let's try to understand what combination of records in the package is necessary for operation.

We write exploits


You can get into the branch with the vulnerable code through the following short condition

 6968 if (found) { 

The found variable is set in five code blocks from the same function, which handle different variations of the answers, such as name redirection by CNAME or DNAME records, response to a request with the ANY type, etc.:


 6891 if (rdataset->type == type && !found_cname) { 6892 /* 6893 * We've found an ordinary answer. 6894 */ 



 6899 } else if (type == dns_rdatatype_any) { 6900 /* 6901 * We've found an answer matching 6902 * an ANY query. There may be 6903 * more. 6904 */ 



 6907 } else if (rdataset->type == dns_rdatatype_rrsig 6908 && rdataset->covers == type 6909 && !found_cname) { 6910 /* 6911 * We've found a signature that 6912 * covers the type we're looking for. 6913 */ 



 6917 } else if (rdataset->type == 6918 dns_rdatatype_cname 6919 && !found_type) { 6920 /* 6921 * We're looking for something else, 6922 * but we found a CNAME. 6923 * 



 6955 } else if (rdataset->type == dns_rdatatype_rrsig 6956 && rdataset->covers == 6957 dns_rdatatype_cname 6958 && !found_type) { 6959 /* 6960 * We're looking for something else, 6961 * but we found a SIG CNAME. 6962 */ 



Recall a small hint in the patch description:

“Named mishandled some responses where there was a result of failure. (CVE-2016-9147) ”


Which says that one of the records should be an RRSIG . RRSIG is one of the DNSSEC mechanisms that ensures the integrity of the DNS data in the response. For records of any type (A, AAAA, NS, DNAME, CNAME, etc.), the corresponding RRSIG record is transmitted in the response, which contains a digital signature. In order to understand for which type of RRSIG signature contains, there is a Type Covered field in RRSIG .



Only 2 out of 5 conditions are related to the detection of RRSIG in the DNS response:

 6907 } else if (rdataset->type == dns_rdatatype_rrsig 6908 && rdataset->covers == type 6909 && !found_cname) { 6910 /* 6911 * We've found a signature that 6912 * covers the type we're looking for. 6913 */ 6914 found = ISC_TRUE; 6915 found_type = ISC_TRUE; 6916 aflag = DNS_RDATASETATTR_ANSWERSIG; 

This check is triggered if we find RRSIG with a signature for the record we are looking for (for which the request was sent).

 6955 } else if (rdataset->type == dns_rdatatype_rrsig 6956 && rdataset->covers == 6957 dns_rdatatype_cname 6958 && !found_type) { 6959 /* 6960 * We're looking for something else, 6961 * but we found a SIG CNAME. 6962 */ 6963 found = ISC_TRUE; 6964 found_cname = ISC_TRUE; 6965 aflag = DNS_RDATASETATTR_ANSWERSIG; 6966 } 

This condition is similar to the first, only the RRSIG record should cover the CNAME type.

We came close to the conclusion that the operation of this error requires a single RRSIG entry in ANSWER_SECTION . Indeed, this situation should not occur in normal DNS traffic, since RRSIG can not be tied to another record.

We try to reproduce the topology with a recursive DNS server and send a response from a single RRSIG record to a recursive query that covers either a CNAME or a type from a DNS query.



As expected, we see an emergency termination of the Named daemon:



What is the result


The considered vulnerability is quite simple and dangerous by the fact that its operation does not require difficult conditions. BIND developers constantly fix serious DNS server vulnerabilities that can disrupt its operation.

Positive Technologies experts carefully studied all the vulnerabilities fixed by developers, replicated them in real conditions and developed IDS signatures to detect exploitation.



Author : Kirill Shipulin, Specialist of the Attack Detection Methods Research Group
Positive Technologies

Source: https://habr.com/ru/post/321428/


All Articles