Wireshark-dev: Re: [Wireshark-dev] Mu Dynamics, Inc. Security Advisories MU-201202-01 and MU-20
From: Gerald Combs <gerald@xxxxxxxxxxxxx>
Date: Wed, 21 Mar 2012 15:16:02 -0700
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 The GNUTLS libraries that we ship with the Windows installers come from the OpenSUSE build system: https://build.opensuse.org/package/show?package=mingw32-gnutls&project=windows%3Amingw%3Awin32 I submitted a request to update GNUTLS and Libtasn1 to the most recent releases that we can ship... https://bugzilla.novell.com/show_bug.cgi?id=753440 ...and by "that we can ship" I mean that GNUTLS 3.0 changed its license from LGPLv2.1+ / GPLv3+ to LGPLv3+ / GPLv3+. The compatibility matrix at http://www.gnu.org/licenses/gpl-faq.html#AllCompatibility suggests that this would require changing Wireshark's license. A while back someone suggested adding support for Mozilla's Network Security Services library: https://bugzilla.redhat.com/show_bug.cgi?id=348461 It might be a good time to revisit that. On 3/20/12 7:14 PM, Security wrote: > Hello Open Source Distributors, > > Any libgnutls and libtasn1 packages you may have in your > environments should be updated to the latest versions in order to > correct the below vulnerabilities we released today. Various > popular packages such as Wireshark / tshark use these packages and > could also be affected. > > http://www.gnu.org/software/gnutls/security.html > http://blog.mudynamics.com/2012/03/20/gnutls-and-libtasn1-vulns/ > > Regards, Matthew Hall Mu Dynamics Research Team Mu Dynamics, Inc. > > Mu Dynamics, Inc. Security Advisories MU-201202-01 and MU-201202-02 > for GnuTLS and Libtasn1 > > TLS record handling vulnerability in GnuTLS [MU-201202-01] ASN.1 > length decoding vulnerability in Libtasn1 [MU-201202-02] > > 20 March 2012 > > http://blog.mudynamics.com/2012/03/20/gnutls-and-libtasn1-vulns/ > http://labs.mudynamics.com/advisories.html > > Affected Products/Versions: > > * libgnutls up to 3.0.16. * libtasn1 up to 2.11. > > Product Overview: > > GnuTLS is an open source implementation of SSL, TLS and DTLS, with > APIs for encrypted network communications, along with X.509, PKCS > #12, OpenPGP, and other security data types. > > Analysis: > > Details for TLS record handling vulnerability in GnuTLS > [MU-201202-01]: > > The block cipher decryption logic in GnuTLS assumed that a record > containing any data which was a multiple of the block size was > valid for further decryption processing, leading to a heap > corruption vulnerability. > > The bug can be reproduced in GnuTLS 3.0.14 by creating a corrupt > GenericBlockCipher struct with a valid IV, while everything else is > stripped off the end, while the handshake message length retains > its original value: > > struct { opaque IV[SecurityParameters.record_iv_length]; // > corrupt: below items not sent /* block-ciphered struct { opaque > content[TLSCompressed.length]; opaque > MAC[SecurityParameters.mac_length]; uint8 > padding[GenericBlockCipher.padding_length]; uint8 padding_length; > }; */ } GenericBlockCipher; > > This will cause a segmentation fault, when the > ciphertext_to_compressed function tries to give decrypted data to > _gnutls_auth_cipher_add_auth for HMAC verification, even though the > data length is invalid, and it should have returned > GNUTLS_E_DECRYPTION_FAILED or GNUTLS_E_UNEXPECTED_PACKET_LENGTH > instead, before _gnutls_auth_cipher_add_auth was called. > > Since the error was not returned soon enough, all of the various > operations ciphertext_to_compressed performs: i.e. setting the IV, > removing the padding, setting the "true" data length with the > padding stripped, checking the padding size and padding payload and > verifying HMAC could all reference undefined, unallocated, or > uninitialized memory. > > There could be similar ways to reproduce this for AEAD ciphers due > to the various flows through this code, but we did not attempt to > do this, and see it as a topic for further investigation. > > Below we trace the execution of the ciphertext_to_compressed > function from lib/gnutls_cipher.c. The unsafe operations and missed > opportunities to return before the heap corruption happens are > marked with "***** ... *****" : > > 433 static int 434 ciphertext_to_compressed (gnutls_session_t > session, 435 gnutls_datum_t > *ciphertext, 436 uint8_t * > compress_data, 437 int compress_size, > 438 uint8_t type, record_parameters_st > * params, 439 uint64* sequence) 440 > { ... 511 case CIPHER_BLOCK: 512 if > (ciphertext->size < MAX(blocksize, tag_size) || (ciphertext->size % > blocksize != 0)) ***** UNSAFE ***** 513 return > gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); 514 515 > /* ignore the IV in TLS 1.1+ 516 */ 517 if > (explicit_iv) 518 { 519 > _gnutls_auth_cipher_setiv(¶ms->read.cipher_state, 520 > ciphertext->data, blocksize); 521 522 ciphertext->size > -= blocksize; 523 ciphertext->data += blocksize; 524 > 525 if (ciphertext->size == 0) ***** UNSAFE ***** 526 > { 527 gnutls_assert (); 528 > return GNUTLS_E_DECRYPTION_FAILED; 529 } 530 > } ... 537 if ((ret = 538 > _gnutls_cipher_decrypt (¶ms->read.cipher_state.cipher, 539 > ciphertext->data, ciphertext->size)) < 0) 540 return > gnutls_assert_val(ret); 541 542 pad = > ciphertext->data[ciphertext->size - 1] + 1; /* pad */ 543 544 > if ((int) pad > (int) ciphertext->size - tag_size) 545 > { 546 gnutls_assert (); 547 > _gnutls_record_log 548 ("REC[%p]: Short record > length %d > %d - %d (under attack?)\n", 549 > session, pad, ciphertext->size, tag_size); ***** Message Appears > During The Attack ***** 550 /* We do not fail here. We > check below for the 551 * the pad_failed. If zero > means success. 552 */ 553 pad_failed = > GNUTLS_E_DECRYPTION_FAILED; ***** Execution Continues Anyway ***** > 554 pad %= blocksize; 555 } 556 557 > length = ciphertext->size - tag_size - pad; 558 559 /* > Check the padding bytes (TLS 1.x) */ ... 577 /* Pass the > type, version, length and compressed through 578 * MAC. > 579 */ 580 preamble_size = 581 > make_preamble (UINT64DATA(*sequence), type, 582 > length, ver, preamble); 583 ret = > _gnutls_auth_cipher_add_auth (¶ms->read.cipher_state, preamble, > preamble_size); 584 if (ret < 0) 585 return > gnutls_assert_val(ret); 586 587 ret = > _gnutls_auth_cipher_add_auth (¶ms->read.cipher_state, > ciphertext->data, length); ***** UNSAFE, crashes here ***** 588 > if (ret < 0) 589 return gnutls_assert_val(ret); ***** > Crashes Before Error Is Returned ***** ... > > The segmentation fault appears as follows in GDB: > > Program received signal SIGSEGV, Segmentation fault. 0x003b9946 in > _nettle_sha256_compress (state=0x807f128, input=0x808f000 <Address > 0x808f000 out of bounds>, k=0x3cdb60) at sha256-compress.c:111 111 > sha256-compress.c: No such file or directory. in sha256-compress.c > (gdb) bt #0 0x003b9946 in _nettle_sha256_compress > (state=0x807f128, input=0x808f000 <Address 0x808f000 out of > bounds>, k=0x3cdb60) at sha256-compress.c:111 #1 0x003b961b in > nettle_sha256_update (ctx=0x807f128, length=4294916861, > data=0x808effc "") at sha256.c:92 #2 0x003b336d in > nettle_hmac_sha256_update (ctx=0x807f050, length=4294967280, > data=0x8082b09 '\017' <repeats 16 times>) at hmac-sha256.c:43 #3 > 0x0021a749 in wrap_nettle_hmac_update (_ctx=0x807f050, > text=0x8082b09, textsize=4294967280) at mac.c:231 #4 0x00158233 in > _gnutls_hmac (handle=0x807ef9c, text=0x8082b09, textlen=4294967280) > at ./gnutls_hash_int.h:73 #5 0x00158b35 in > _gnutls_auth_cipher_add_auth (handle=0x807ef78, text=0x8082b09, > textlen=-16) at gnutls_cipher_int.c:190 #6 0x001473de in > ciphertext_to_compressed (session=0x807d810, ciphertext=0xbfffe8a4, > compress_data=0x8083da4 "", compress_size=16384, type=22 '\026', > params=0x807ed48, sequence=0x807efcc) at gnutls_cipher.c:587 #7 > 0x00145cdc in _gnutls_decrypt (session=0x807d810, > ciphertext=0x8082af9 "\252\257C/7\301\362\352h|d\275#\312\027\312", > '\017' <repeats 16 times>, ciphertext_size=32, data=0x8083da4 "", > max_data_size=16384, type=GNUTLS_HANDSHAKE, params=0x807ed48, > sequence=0x807efcc) at gnutls_cipher.c:159 ... (gdb) > > The segmentation fault appears as follows in Valgrind Memcheck: > > ==29586== Invalid read of size 1 ==29586== at 0x40274B9: memcpy > (mc_replace_strmem.c:497) ==29586== by 0x42BC5A6: > nettle_sha256_update (sha256.c:92) ==29586== by 0x42B636C: > nettle_hmac_sha256_update (hmac-sha256.c:43) ==29586== by > 0x411C748: wrap_nettle_hmac_update (mac.c:231) ==29586== by > 0x405A232: _gnutls_hmac (gnutls_hash_int.h:73) ==29586== by > 0x405AB34: _gnutls_auth_cipher_add_auth (gnutls_cipher_int.c:190) > ==29586== by 0x40493DD: ciphertext_to_compressed > (gnutls_cipher.c:587) ==29586== by 0x4047CDB: _gnutls_decrypt > (gnutls_cipher.c:159) ... ==29586== Address 0x4464411 is 0 bytes > after a block of size 89 alloc'd ==29586== at 0x4024F12: calloc > (vg_replace_malloc.c:467) ==29586== by 0x4049AE4: _mbuffer_alloc > (gnutls_mbuffers.c:288) ==29586== by 0x4049C49: > _mbuffer_linearize (gnutls_mbuffers.c:349) ==29586== by > 0x40462FB: _gnutls_recv_in_buffers (gnutls_record.c:996) ==29586== > by 0x404D01C: _gnutls_handshake_io_recv_int > (gnutls_buffers.c:1174) ==29586== by 0x4050383: > _gnutls_recv_handshake (gnutls_handshake.c:1260) ... ==29586== > Invalid read of size 1 ... ==29586== Address 0x4464412 is 1 bytes > after a block of size 89 alloc'd ... ==29586== Process terminating > with default action of signal 11 (SIGSEGV) ==29586== Access not > within mapped region at address 0x4779000 ==29586== at > 0x42BC946: _nettle_sha256_compress (sha256-compress.c:111) > ==29586== by 0x42BC61A: nettle_sha256_update (sha256.c:92) > ==29586== by 0x42B636C: nettle_hmac_sha256_update > (hmac-sha256.c:43) ==29586== by 0x411C748: > wrap_nettle_hmac_update (mac.c:231) ==29586== by 0x405A232: > _gnutls_hmac (gnutls_hash_int.h:73) ==29586== by 0x405AB34: > _gnutls_auth_cipher_add_auth (gnutls_cipher_int.c:190) ==29586== > by 0x40493DD: ciphertext_to_compressed (gnutls_cipher.c:587) ... > Segmentation fault > > Details for ASN.1 length decoding vulnerability in Libtasn1 > [MU-201202-02]: > > Various functions using the ASN.1 length decoding logic in Libtasn1 > were incorrectly assuming that the return value from > asn1_get_length_der is always less than the length of the enclosing > ASN.1 structure, which is only true for valid structures and not > for intentionally corrupt or otherwise buggy structures. > > Here is an example of unsafe asn1_get_length_der usage from > lib/minitasn1/decoding.c, in the asn1_der_decoding function: > > 0812 asn1_retCode 0813 asn1_der_decoding (ASN1_TYPE * > element, const void *ider, int len, 0814 char > *errorDescription) 0815 { ... 1033 case > TYPE_ENUMERATED: 1034 len2 = 1035 > asn1_get_length_der (der + counter, len - counter, &len3); 1036 > if (len2 < 0) 1037 return ASN1_DER_ERROR; 1038 > if (len2 + len3 > len - counter) 1039 return > ASN1_DER_ERROR; 1040 _asn1_set_value (p, der + > counter, len3 + len2); 1041 counter += len3 + > len2; 1042 move = RIGHT; 1043 > break; > > The above call to asn1_get_length_der was returning an impossibly > large value of 2GB when the Mu analyzer generated corrupt lengths > fields for versions, serial numbers, public key info, and signature > structures in X.509 client certificates, but this could happen in > any use of Libtasn1 that is relying upon asn1_get_length_der, not > just SSL, TLS, or GnuTLS. > > The asn1_der_decoding function failed to check for cases when > asn1_get_length_der returned a length larger than the enclosing > structure's (void* ider) own length (int len). > > When _asn1_set_value was called anyway, it contained a memcpy > operation which assumed the arguments are valid, which tried copy > 2GB of memory, leading to a heap corruption vulnerability. > > Simon Josefsson, Libtasn1 maintainer, described the patch as > follows: "the real bug was not in asn1_get_length_der() even if > that is the function we patch[ed]. The callers of that function > that did not check that the return values are sane were buggy. > However, instead of fixing all callers, ... we went for the simpler > solution to let the function return an error for a situation that > is unlikely to occur without malicious interaction or data > corruption." > > The asn1_der_decoding function shown above is now safe, because > asn1_get_length_der was updated to "[return] -4 when the decoded > length value plus @len would exceed @der_len," so asn1_der_decoding > returns ASN1_DER_ERROR before it can call _asn1_set_value to > trigger the segmentation fault. > > Abbreviated GDB Backtrace after the segmentation fault: > > (gdb) bt #0 __memcpy_ia32 () at > ../sysdeps/i386/i686/multiarch/../memcpy.S:75 #1 0x00000001 in ?? > () #2 0x0020eadc in _asn1_set_value (node=0x807ff50, > value=0x807ed5c, len=2147483652) at parser_aux.c:228 #3 0x0020a646 > in asn1_der_decoding (element=0x8078000, ider=0x807ed4e, len=687, > errorDescription=0x0) at decoding.c:1036 #4 0x001bc7da in > gnutls_x509_crt_import (cert=0x8078000, data=0xbfffeae8, > format=GNUTLS_X509_FMT_DER) at x509.c:226 #5 0x00176d16 in > gnutls_pcert_import_x509_raw (pcert=0x807d610, cert=0xbfffeae8, > format=GNUTLS_X509_FMT_DER, flags=0) at gnutls_pcert.c:201 ... > (gdb) > > Response / Solution: > > TLS record handling vulnerability in GnuTLS [MU-201202-01] is fixed > in GnuTLS 3.0.15. For more details, see > http://article.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/5912 > . > > ASN.1 length decoding vulnerability in Libtasn1 [MU-201202-02] is > fixed in Libtasn1 2.12 and GnuTLS 3.0.16. For more details, see > http://lists.gnu.org/archive/html/help-libtasn1/2012-03/msg00000.html > and > http://article.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/5932 > . > > History: > > Mon, 27 Feb 2012 14:13:45 -0800: TLS Record handling issue > reported. Tue, 28 Feb 2012 10:29:46 +0100: TLS Record handling > patch created. Fri, 02 Mar 2012 18:42:05 +0000: GnuTLS 3.0.15 > release announced. Fri, 02 Mar 2012 14:04:31 -0800: ASN.1 length > decoding issue reported. Wed, 14 Mar 2012 01:04:36 +0100: ASN.1 > length decoding patch created. Mon, 19 Mar 2012 10:57:42 +0100: > Libtasn1 2.12 release announced. Tue, 20 Mar 2012 23:40:00 +0000: > Advisory released to the public. > > See also: > > http://article.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/5912 > > http://article.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/5932 > http://lists.gnu.org/archive/html/help-libtasn1/2012-03/msg00000.html > > http://git.savannah.gnu.org/gitweb/?p=gnutls.git;a=commitdiff;h=b495740f2ff66550ca9395b3fda3ea32c3acb185 > http://git.savannah.gnu.org/gitweb/?p=libtasn1.git;a=commitdiff;h=6e534bf4fb3144be51c928ed3efcf9c36055c9c7 > > Credit: > > These vulnerabilities were discovered by Matthew Hall > <mhall@xxxxxxxxxxxxxx>, Senior Network Protocol Software Engineer > at Mu Dynamics, via code inspection and protocol fuzzing using a Mu > 4000 security analyzer. > > http://blog.mudynamics.com/wp-content/uploads/2012/03/pgpkey.txt > > Mu Dynamics is the leading provider of solutions ensuring the > performance and security of both applications and network > infrastructure. The company's innovative solutions enable customers > to confidently meet the challenges posed by today's rapidly > changing networks. This includes the ever-growing number of > applications and devices on the network, and the swift transition > to mobile, virtual and cloud environments. Hundreds of service > providers, enterprises, application developers and network > equipment manufacturers count on its purpose-built solutions, like > Mu Studio and Blitz, to ensure their applications and networks are > scalable and secure. Mu Dynamics is headquartered in Sunnyvale, > California. > ___________________________________________________________________________ > > Sent via: Wireshark-dev mailing list <wireshark-dev@xxxxxxxxxxxxx> > Archives: http://www.wireshark.org/lists/wireshark-dev > Unsubscribe: https://wireshark.org/mailman/options/wireshark-dev > mailto:wireshark-dev-request@xxxxxxxxxxxxx?subject=unsubscribe - -- Join us for Sharkfest ’12! · Wireshark® Developer and User Conference Berkeley, CA, June 24-27 · sharkfest.wireshark.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9qUyIACgkQpw8IXSHylJrJSwCgqZWz1v7gP7s/b/+j9nZaJ6nW 0psAmgPx/RJxdrYbNwJti4gN6YGmUf33 =ZtFw -----END PGP SIGNATURE-----
- References:
- Prev by Date: Re: [Wireshark-dev] regarding pcap timestamps
- Next by Date: Re: [Wireshark-dev] (no subject)
- Previous by thread: [Wireshark-dev] Mu Dynamics, Inc. Security Advisories MU-201202-01 and MU-201202-02 for GnuTLS and Libtasn1
- Next by thread: [Wireshark-dev] Query.
- Index(es):