xorl %eax, %eax

CVE-2009-0025/0265: BIND DNS SSL/TLS Validation Bypass

leave a comment »

This is almost exactly the same vulnerability as the one described previously for NTP. ISC BIND is the most popular DNS server on the internet. This vulnerability affects BIND prior to 9.6.0-P1 release and consequently 9.5.1-P1. The following code is taken from 9.6.0 release of the popular DNS server.
The bugs can be easily located. Here is the first one (lib/dns/opensslrsa_link.c):

288 static isc_result_t
289 opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
290         dst_key_t *key = dctx->key;
291         int status = 0;
292 #if USE_EVP
293         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
294         EVP_PKEY *pkey = key->keydata.pkey;
307 #if USE_EVP
308         status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
328         if (status == 0)
329                 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
331         return (ISC_R_SUCCESS);
332 }

Similarly to the NTP vulnerability, this is just an API routine call misuse. A quick look at EVP_VerifyFinal()‘s man page (which is called at line 308) reveals the following regarding its return value:

EVP_VerifyFinal() returns 1 for a correct signature, 0 for failure and -1 if some other error occurred.
The error codes can be obtained by ERR_get_error(3).

This means that it only checks for failures and not for invalid signatures. Using an invalid signature this function will still exit with SUCCESS status. This was simply patched like this:

                            RSA_size(rsa), rsa);
-       if (status == 0)
+       if (status != 1)
                return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
        return (ISC_R_SUCCESS);

The second vulnerability of this nature can be found at the equivalent DSA implementation (the previously discussed was the RSA one) which is located at lib/dns/openssldsa_link.c. The bug is more or less the same:

213 static isc_result_t
214 openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
215         dst_key_t *key = dctx->key;
216         DSA *dsa = key->keydata.dsa;
217         int status = 0;
277         status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
278 #endif
279         DSA_SIG_free(dsasig);
280         if (status == 0)
281                 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
283         return (ISC_R_SUCCESS);
284 }

Once again the API call at line 277 (DSA_do_verify()) which is responsible for verifying the given signature is incorrectly handled when it is checked only against 0 at line 280. From its man page we can read the following:

Return Values
DSA_do_verify() returns 1 for a valid signature, 0 for an incorrect signature 
and -1 on error. The error codes can be obtained by err_get_error(3).

The patch was of course…:

        status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
-       if (status == 0)
+       if (status != 1)
                return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
        return (ISC_R_SUCCESS);

Obviously, this affects only the BIND setups that utilize the DNSSEC protocol which uses encryption during the transactions. However, it is still an important vulnerability since it is on the most widely deployed DNS server. You can easily check wether you have DNSSEC enabled like this:

1. Determine if Sun's BIND server is installed and if the version is affected:
Solaris 9 Systems:
# pkginfo SUNWinamd || echo "BIND server not installed"
# /usr/lib/dns/named -v
Solaris 10 Systems and OpenSolaris:
# pkginfo SUNWbind || echo "BIND server not installed"
# /usr/sbin/named -v2.
2. Determine if BIND is configured and enabled by checking for the following process:
# ps -e | grep named && echo "BIND is running"
3. Determine if BIND is configured to use DNSSEC:
# grep -i "dnssec-enable.*yes" /etc/named.conf
4. Determine that BIND is accepting DSA-only signed responses:
# grep -i "disable-algorithms.*dsa" /etc/named.conf

Written by xorl

March 13, 2009 at 17:09

Posted in vulnerabilities

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s