Re: Re: Buffer Overflow in gnutls_pk.c/_gnutls_pkcs1_rsa_decrypt

Michal Ambroz rebus at seznam.cz
Tue Jan 10 01:44:10 CET 2012


Hi Nikos,
more info on https://bugzilla.redhat.com/show_bug.cgi?id=747167

<  I would be curious on how you reached the buffer overflow. This is an
< internal function and its input is controlled by its callers.
Server gets there by calling gnutls_handshake when new client connects.

I was hunting this one for quite some time.
It works like that:
1) The code is/was wrongly used in openvas-libraries - use after free condition.
During the inicialization of the gnutls credentials the code in openvas-library loaded private key from file, 
initialized credentials then freed the memory of pk structure (which is obviously wrong).
2) when new socket connection is initialized the function gnutls_handshake is called
3) this calls the _gnutls_pkcs1_rsa_decrypt


It seems that on other operating systems/versions this race condition is hidden. Between inicialization and
use there is usually not enough time to overwrite the data in the memory of former PK so nobody notices.

In Fedora 16 it nearly always wins the race condition. tls_cred.pkey.key.509.params_size gets usually set with some high value and it smashes whole stack so it is flagrantly visible.

The fact that it doesn't demonstrate in other operating systems/versions doesn't mean it is not there and can't be exploited.

Let's say I am hacker and I am up to exploit such the code. 
I would try to go in this direction:
1) spray the heap with my shell code somehow (maybe there is some memory leak in parent, maybe there is some string formatting issue ....)
2) call the gnutls_handshake ( by opening new connection )
3) _gnutls_pkcs1_rsa_decrypt will copy the data to the stack and overwrite the return pointer to jump to the buffer
4) params buffer would contain shell code to execute, or heap will contain the code to execute

I know it seem's bit contrieved but look ... in this trace it has overwritten the return pointer with address 0, so why not some other address:
gdb --args openvassd -f -p 9391
> set follow-fork-mode child
> run

Program received signal SIGSEGV, Segmentation fault.
0x4caba11c in _gnutls_pkcs1_rsa_decrypt (plaintext=0x0, ciphertext=0xabd79c8,
params=
    0xabd7968, params_len=0, btype=0) at gnutls_pk.c:220
220     pk_params.params[i] = params[i];
(gdb) where
#0  0x4caba11c in _gnutls_pkcs1_rsa_decrypt (plaintext=0x0,
ciphertext=0xabd79c8, 
    params=0xabd7968, params_len=0, btype=0) at gnutls_pk.c:220
#1  0x00000000 in ?? ()

Best regards
Michal Ambroz



< ------------ Původní zpráva ------------
< Od: Nikos Mavrogiannopoulos <nmav at gnutls.org>
< Předmět: Re: Buffer Overflow in gnutls_pk.c/_gnutls_pkcs1_rsa_decrypt
< Datum: 09.1.2012 23:46:47
< ----------------------------------------
< On 01/09/2012 10:28 PM, Michal Ambroz wrote:
< 
< > Hello,
< > As a result of bug in openvas-libraries I hit buffer overflow
< > condition in gnutls. This code in gnutls (gnutls_pk.c:220) will
< > overwrite the stack because the function trusts that the declared
< > size of the pk_params.params will be bigger than the size of
< > parameters from the configured pkcs11 key:
< 
< 
< Hello,
<  I would be curious on how you reached the buffer overflow. This is an
< internal function and its input is controlled by its callers.
< 
< > 2) log an error and limit the for cycle with the min(params_len,
< > sizeof(pk_params.params) )
< 
< > to ensure that the buffer will not get overwritten with broken or
< > intentionally crafted data.
< 
< 
< Although having a sanity check there is useful, how could intentionally 
< crafted data reach that point?
< 
< regards,
< Nikos
< 
< 
< 




More information about the Gnutls-devel mailing list