Certified Secure Advisory 14-01-2015-0.1 - PolarSSL
CVE 2015-1182
During a routine research session, Certified Secure found a "Use of uninitialized memory" vulnerability in the PolarSSL (https://polarssl.org) library. The vulnerability is present in the asn1_get_sequence_of routine that is used to parse ASN.1 sequences from X.509 certificates.
The vulnerability can be exploited using a specially crafted X.509 certificate.
Feedback received from PolarSSL on 14-01-2015: Upon receiving our advisory PolarSSL indicated they have independently found the same vulnerability during an internal audit process. A patch for this vulnerability will be released on 19-01-2015, see the official PolarSSL advisory.
Impact
When a user controlled X.509 certificate is parsed by the PolarSSL library, the vulnerability allows for Remote Code Execution and a Denial of Service. The most common vulnerable scenario is a server using the PolarSSL library to verify client certificates.
In this scenario a malicious client can exploit the server by presenting a crafted X.509 certificate. The vulnerability is triggered during parsing and before the actual validation of the certificate. Other scenarios include a malicious server presenting a crafted server certificate (exploiting the connecting clients) and any other (direct) callers of the X.509 parsing routines of the PolarSSL library
Vulnerable Versions
Confirmed in PolarSSL >= PolarSSL 1.0
Upgrading
Apply the official patch from the PolarSSL advisory
Upgrade for OpenVPN-NL will be made available at https://openvpn.fox-it.com
Unofficial patch for PolarSSL 1.3.9 available here
Projects using PolarSSL
This vulnerability may impact projects using the PolarSSL library.
https://polarssl.org/kb/generic/projects-using-polarssl
- OpenVPN-NL: OpenVPN-NL <= 2.3.5-nl2 confirmed vulnerable. Client Certificate parsed during SSL/TLS handshake. When tls-auth is configured the attacker requires a valid ta.key.The crafted certificate may be a self signed certificate (exploited before certificate validation)
- OpenVPN Connect: OpenVPN Connect for Android confirmed vulnerable in versions <= 1.1.14, OpenVPN Connect for iOS confirmed vulnerable in versions <= 1.0.5. To exploit a client the attacker needs to control the server or perform a successful MiTM attack. When tls-auth is configured the attacker requires a valid ta.key.
- OpenVPN Generic: Suspected vulnerable when compiled with unpatched PolarSSL (not the default, untested).
- PowerDNS: Unaffected since no X.509 certificates or ASN.1 parsed.
- Remaining: Unknown. Vulnerable when crafted X.509 certificates may be parsed.
Nitty Gritty
library/asn1parse.c:asn1_get_sequence_of:
int asn1_get_sequence_of( unsigned char **p, const unsigned char *end, asn1_sequence *cur, int tag) { int ret; size_t len; asn1_buf *buf; /* Get main sequence tag */ if( ( ret = asn1_get_tag( p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) return( ret ); if( *p + len != end ) return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); while( *p < end ) { buf = &(cur->buf); buf->tag = **p; if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) return( ret ); buf->p = *p; *p += buf->len; /* Allocate and assign next pointer */ if( *p < end ) { cur->next = (asn1_sequence *) polarssl_malloc( sizeof( asn1_sequence ) ); if( cur->next == NULL ) return( POLARSSL_ERR_ASN1_MALLOC_FAILED ); cur = cur->next; } } /* Set final sequence entry's next pointer to NULL */ cur->next = NULL; if( *p != end ) return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); return( 0 ); }
The above routine parses a sequence of ASN.1 variables from a X.509 certificate (starting a *p, ending at end). When the structure for the "cur->next" variable is allocated (line 32-33) it is NOT zero initialized but IS added to the result linked list (line 38). When an error in asn1_get_tag is triggered on the next iteration (line 23-24) the routine will return. The last "next" pointer of the resulting linked list is never initialized.
library/x509_crt.c:x509_crt_free
seq_cur = cert_cur->ext_key_usage.next; while( seq_cur != NULL ) { seq_prv = seq_cur; seq_cur = seq_cur->next; polarssl_zeroize( seq_prv, sizeof( x509_sequence ) ); polarssl_free( seq_prv ); }
Upon freeing the X.509 certificate the parsed ASN.1 sequences are freed. This can bee seen in the code above. The linked list is iterated and every item is zeroed and de-allocated. Since the last "next" pointer is uninitialized this will zero and free an arbitrary memory location.
This vulnerability is exploitable [1,2] using (at least) two different methods. The "contents" of the uninitialized memory can directly be controlled by carefully manipulating the heap allocations. This in turn can be used to "zeroize" an arbitrary memory location and/or trigger a free() on an arbitrary memory location. This will lead to remote code execution and/or a denial of service.
References:
[1]: The poisoned NUL byte, 2014 edition
[2]: Understanding the heap by breaking it
Timeline
14-01-2015: Initial disclosure to whitehat@polarssl.org
14-01-2015: Feedback from PolarSSL received
15-01-2015: Disclosure timeline received from PolarSSL
16-01-2015: Informed NCSC-CERT of upcoming disclosure
19-01-2015: Public Disclosure
20-01-2015: Update with OpenVPN Connect and PowerDNS statements
20-01-2015: Include CVE number
Contact
Certified Secure
https://www.certifiedsecure.com
research@certifiedsecure.com
- Security is serious fun -