|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
Details on the gnutls_handshake local crash problem [GNUTLS-SA-2008-2]Below is my analysis of the problem. The patch is short:
From 0fee3917077e191dea3c9787c95c072979532086 Mon Sep 17 00:00:00 2001 From: Simon Josefsson <simon@...> Date: Mon, 30 Jun 2008 22:44:47 +0200 Subject: [PATCH] (_gnutls_handshake_hash_buffers_clear): Make sure deinitialized MAC hashes are initialized. Report and tiny patch from Tomas Mraz <tmraz@...>. --- lib/gnutls_handshake.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index d798180..0192c9f 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -69,11 +69,12 @@ int _gnutls_server_select_comp_method (gnutls_session_t session, /* Clears the handshake hash buffers and handles. */ -inline static void +static void _gnutls_handshake_hash_buffers_clear (gnutls_session_t session) { _gnutls_hash_deinit (&session->internals.handshake_mac_handle_md5, NULL); _gnutls_hash_deinit (&session->internals.handshake_mac_handle_sha, NULL); + session->internals.handshake_mac_handle_init = 0; _gnutls_handshake_buffer_clear (session); } -- 1.5.6 /Simon I have received a report against gnutls v2.4.0 which triggers a local segmentation fault when any application calls gnutls_handshake() for an already valid session. This is valid but not common usage. Btw, earlier stable releases before v2.4.0 are not affected. The problem was introduced in v2.3.5 in the first @@-section of: http://git.savannah.gnu.org/gitweb/?p=gnutls.git;a=commitdiff;h=3aea821a6ce36bd14f2a3a41598db698d031fadc#patch5 How to reproduce: 1. download ftp://ftp.gnutls.org/pub/gnutls/gnutls-2.4.0.tar.bz2 you'll need libgpg-error/libgcrypt installed if you do not have it already 2. build it: ./configure && make 3. download 'http://git.savannah.gnu.org/gitweb/?p=gnutls.git;a=blob_plain;f=tests/mini.c;h=HEAD;hb=HEAD' into tests/mini.c, the latest code triggers the behaviour. 4. run cd tests; make mini;./mini Detailed analysis: The code ends up invoking gcry_md_write() on a handle that points to a free()'d structure. Since the pointer has been free()'d, the pointer could point to anything at the time when the code is invoked. An attacker can't control where the pointer points to, but an attacker could have sent data into a buffer that is in the victims memory. If the pointer happens to point to the data buffer sent by the attacker, the attacker may be able to control execution. Libgcrypt's code is: http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/trunk/cipher/md.c?root=Libgcrypt&view=auto static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen) { GcryDigestEntry *r; if (a->ctx->debug) { if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1) BUG(); if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1) BUG(); } for (r = a->ctx->list; r; r = r->next) { if (a->bufpos) (*r->digest->write) (&r->context.c, a->buf, a->bufpos); (*r->digest->write) (&r->context.c, inbuf, inlen); } a->bufpos = 0; } For me, the crash happens because a->ctx is still valid but a->ctx->debug is garbage, so it crashes in the fwrite, writing to a bad file descriptor. Given that the code de-reference a->ctx->list or a->buf early, which is typically garbage, normally the code will crash before using any of the inbuf/inlen data. The inbuf/inlen data is normally not under attacker control, it is generated by the local implementation to be a TLS handshake packet. However, some elements of the TLS handshake packets may have been influenced by the other side during the first handshake, so the conservative approach would be to treat it as tainted. To turn this into an exploit, I believe the attacker needs to cause some specific data to be located where the free()'d pointer 'a' points. To do this reliable, you need to predict where the 'a' pointer will point to and to put some custom data at that memory address. Once that is done, you could make the first fwrite() in the function above write some data to an already open file descriptor. Of course, the attacker needs to know the address of the file descriptor, and make that address be part of the data sent to to the victim. However, causing custom data to be placed at the point where an earlier free()'d pointer points to appears difficult to do on normal platforms where you typically don't know the heap memory addresses. _______________________________________________ Gnutls-devel mailing list Gnutls-devel@... http://lists.gnu.org/mailman/listinfo/gnutls-devel |
| Free embeddable forum powered by Nabble | Forum Help |