[Cabal] CERT

Luke Schierer lschiere at pidgin.im
Wed Dec 13 17:44:10 EST 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


On Dec 12, 2006, at 16:21 EST, Luke Schierer wrote:

> On Tue, Dec 12, 2006 at 03:32:08PM -0500, Luke Schierer wrote:
>> Today Sean and I received an email from CERT asking for a formal
>> security contact with GPG key.  They will want to call the person to
>> verify the fingerprint.
>>
>> I do not object being their contact, but if someone else is  
>> interested,
>> many of you are better qualified for it than I.
>>
>> luke
>
> Having heard from Sean and Ethan, I went ahead and replied to CERT.
>
> luke

And they are concerned about precisely the format string  
vulnerability recently reported to us.

luke

From: endrazine <endrazine at gmail.com>
Date: December 12, 2006 06:11:59 EST
To: lschiere at users.sourceforge.net, seanegan at users.sourceforge.net,  
thekingant at users.sourceforge.net
Subject: Format string vulnerability in Gaim 1.5 and beta 2.0.Obeta5

Hi,
I tought I should write directly to you since you are the admins of  
the Gaim project and I found a bug I could not post on the main
bug tracker page because of its nature : there is a security issue,  
namely a format string vulnerability in the current Gaim
package. Possibly allowing remote arbitrary code execution.

Here are my details:

localhost ~ $ gaim -v
Gaim 1.5.0
localhost ~ $ uname -a
Linux localhost 2.6.18 #2 SMP Fri Sep 29 18:47:30 CEST 2006 i686 Intel 
(R) Celeron(R) CPU 2.80GHz GenuineIntel GNU/Linux
localhost ~ $


Ok, now, let me detail a bit more the bug :

There is a function whose prototype is :
        void gaim_debug(GaimDebugLevel level, const char *category,   
const char *format, ...);
declared in my /usr/include/gaim/debug.h header.

Now, if you look at the source file in
<somepath>/gaim-1.5.0/plugins/perl/common/Gaim.c


you'll find this function missused in 3 places :

line 204:     gaim_debug(level, category, string);
line 220:    gaim_debug(GAIM_DEBUG_MISC, category, string);
line 237:    gaim_debug(GAIM_DEBUG_INFO, category, string);

In those 3 places, the "string" variable can allow an attacker to  
inject its own format string, and therefore,
read or write anywhere in the process's memory, potentially allowing  
arbitrary execution.


Note: to correct the bug, I'd suggest using
line 204:     gaim_debug(level, category,"%s", string);
line 220:    gaim_debug(GAIM_DEBUG_MISC, category, "%s",string);
line 237:    gaim_debug(GAIM_DEBUG_INFO, category,"%s", string);

instead.

Ok, now : how exploitable is the in real conditions ?

in the each case, string is defined via :

line 202:    const char *    string = (const char *)SvPV_nolen(ST(2));

line 218:     const char *    string = (const char *)SvPV_nolen(ST(1));

line 252:    const char *    string = (const char *)SvPV_nolen(ST(1));



The corresponding ST being defined earlier in :

    if (items < 4 || items > 5)
    Perl_croak(aTHX_ "Usage: Gaim::signal_connect(instance, signal,  
plugin, callback, data = 0)");
    {
    void *    instance = INT2PTR(void *,SvIV(ST(0)));
    const char *    signal = (const char *)SvPV_nolen(ST(1));
    Gaim__Plugin    plugin = gaim_perl_ref_object(ST(2));
    SV *    callback = ST(3);
    SV *    data;

    if (items < 5)
        data = 0;
    else {
        data = ST(4);
    }


so the signal and pluggin strings are the one an attacker would use  
to trigger an attack (I admin this is not trivial ;)


Now, conserning the new Beta 2.0.0beta5 version, the problem has  
moved to Debug.c, where we can read :

XS(XS_Gaim__Debug_gaim_debug)
{
    dXSARGS;
    if (items != 3)
    Perl_croak(aTHX_ "Usage: Gaim::Debug::gaim_debug(level, category,  
string)");
    {
    Gaim__DebugLevel    level = (Gaim__DebugLevel)SvIV(ST(0));
    const char *    category = (const char *)SvPV_nolen(ST(1));
    const char *    string = (const char *)SvPV_nolen(ST(2));

    gaim_debug(level, category, string);
    }
    XSRETURN_EMPTY;
}



XS(XS_Gaim__Debug_misc)
{
    dXSARGS;
    if (items != 2)
    Perl_croak(aTHX_ "Usage: Gaim::Debug::misc(category, string)");
    {
    const char *    category = (const char *)SvPV_nolen(ST(0));
    const char *    string = (const char *)SvPV_nolen(ST(1));

    gaim_debug_misc(category, string);
    }
    XSRETURN_EMPTY;
}


(same issues, only at different places. Those are even more likely to  
be triggered remotly imho, just check the prototypes...)
I will shortly do a deeper audit of this last beta version and keep  
you informed.





Finally, I don't think an attack would be realistic, but I strongly  
suggest you update your code accordingly, to avoid any security issue  
(I'm not a great perl coder, nor a gaim developper, so I simply  
cannot say if those variables can be modified otherwise remotly).

As the header claims :
/*
* This file was generated automatically by xsubpp version 1.9508 from  
the
* contents of Gaim.xs. Do not edit this file, edit Gaim.xs instead.
*
*    ANY CHANGES MADE HERE WILL BE LOST!
*
*/
maybe you would like to had a fix format string in Gaim.xs rather.  
That shouldn't be too complicated since
the calls to the vulnerable function are declared as :

void
gaim_debug(level, category, string)
    Gaim::DebugLevel level
    const char *category
    const char *string


Feel free to contact me if you feel the need to. I would even  
appreciate a little feedback :)
If you ever want to give me credits for this discovery, you can quote  
"Jonathan Brossard, endrazine"
Thanks for your patience,

Best regards,



endrazine-










From: endrazine <endrazine at gmail.com>
Date: December 12, 2006 07:05:07 EST
To: endrazine <endrazine at gmail.com>
Cc: lschiere at users.sourceforge.net, seanegan at users.sourceforge.net,  
thekingant at users.sourceforge.net
Subject: Re: Format string vulnerability in Gaim 1.5 and beta 2.0.Obeta5

Ok, here come more for the beta2.0.0beta5 : (I only focused on  
trivial format strings for now)

in /gaim-2.0.0beta5/gtk/win32/win_gaim.c:
        printf(aspelldir);
        printf(errbuf);
        printf(errbuf);

in /gaim-2.0.0beta5/libgaim/protocols/qq/qq_proxy.c

void _qq_show_packet(const gchar *desc, const guint8 *buf, gint len)
{
    char buf1[8*len+2], buf2[10];
    int i;
    buf1[0] = 0;
    for (i = 0; i < len; i++) {
        sprintf(buf2, " %02x(%d)", buf[i] & 0xff, buf[i] & 0xff);
        strcat(buf1, buf2);
    }
    strcat(buf1, "\n");
    gaim_debug(GAIM_DEBUG_INFO, desc, buf1);
}


in /root/audits/tools/gaim-2.0.0beta5/libgaim/plugins/perl/common/ 
Debug.c
Multiple unsafe calls to:
gaim_debug()
gaim_debug_misc()
gaim_debug_info()
gaim_debug_warning()
gaim_debug_error()
gaim_debug_fatal()

in /root/audits/tools/gaim-2.0.0beta5/console/libgnt/gntwm.c
fprintf(file, start);
fprintf(file, end);


Hrm, let's say it's a beta ;)
Do you have a standardised process to review your code ? If so, I  
would like to give a hand if you think I might be of some help.

Have a nice day,

endrazine-

endrazine a écrit :
Hi,
I tought I should write directly to you since you are the admins of  
the Gaim project and I found a bug I could not post on the main
bug tracker page because of its nature : there is a security issue,  
namely a format string vulnerability in the current Gaim
package. Possibly allowing remote arbitrary code execution.

Here are my details:

localhost ~ $ gaim -v
Gaim 1.5.0
localhost ~ $ uname -a
Linux localhost 2.6.18 #2 SMP Fri Sep 29 18:47:30 CEST 2006 i686 Intel 
(R) Celeron(R) CPU 2.80GHz GenuineIntel GNU/Linux
localhost ~ $


Ok, now, let me detail a bit more the bug :

There is a function whose prototype is :
        void gaim_debug(GaimDebugLevel level, const char *category,   
const char *format, ...);
declared in my /usr/include/gaim/debug.h header.

Now, if you look at the source file in
<somepath>/gaim-1.5.0/plugins/perl/common/Gaim.c


you'll find this function missused in 3 places :

line 204:     gaim_debug(level, category, string);
line 220:    gaim_debug(GAIM_DEBUG_MISC, category, string);
line 237:    gaim_debug(GAIM_DEBUG_INFO, category, string);

In those 3 places, the "string" variable can allow an attacker to  
inject its own format string, and therefore,
read or write anywhere in the process's memory, potentially allowing  
arbitrary execution.


Note: to correct the bug, I'd suggest using
line 204:     gaim_debug(level, category,"%s", string);
line 220:    gaim_debug(GAIM_DEBUG_MISC, category, "%s",string);
line 237:    gaim_debug(GAIM_DEBUG_INFO, category,"%s", string);

instead.

Ok, now : how exploitable is the in real conditions ?

in the each case, string is defined via :

line 202:    const char *    string = (const char *)SvPV_nolen(ST(2));

line 218:     const char *    string = (const char *)SvPV_nolen(ST(1));

line 252:    const char *    string = (const char *)SvPV_nolen(ST(1));



The corresponding ST being defined earlier in :

    if (items < 4 || items > 5)
    Perl_croak(aTHX_ "Usage: Gaim::signal_connect(instance, signal,  
plugin, callback, data = 0)");
    {
    void *    instance = INT2PTR(void *,SvIV(ST(0)));
    const char *    signal = (const char *)SvPV_nolen(ST(1));
    Gaim__Plugin    plugin = gaim_perl_ref_object(ST(2));
    SV *    callback = ST(3);
    SV *    data;

    if (items < 5)
        data = 0;
    else {
        data = ST(4);
    }


so the signal and pluggin strings are the one an attacker would use  
to trigger an attack (I admin this is not trivial ;)


Now, conserning the new Beta 2.0.0beta5 version, the problem has  
moved to Debug.c, where we can read :

XS(XS_Gaim__Debug_gaim_debug)
{
    dXSARGS;
    if (items != 3)
    Perl_croak(aTHX_ "Usage: Gaim::Debug::gaim_debug(level, category,  
string)");
    {
    Gaim__DebugLevel    level = (Gaim__DebugLevel)SvIV(ST(0));
    const char *    category = (const char *)SvPV_nolen(ST(1));
    const char *    string = (const char *)SvPV_nolen(ST(2));

    gaim_debug(level, category, string);
    }
    XSRETURN_EMPTY;
}



XS(XS_Gaim__Debug_misc)
{
    dXSARGS;
    if (items != 2)
    Perl_croak(aTHX_ "Usage: Gaim::Debug::misc(category, string)");
    {
    const char *    category = (const char *)SvPV_nolen(ST(0));
    const char *    string = (const char *)SvPV_nolen(ST(1));

    gaim_debug_misc(category, string);
    }
    XSRETURN_EMPTY;
}


(same issues, only at different places. Those are even more likely to  
be triggered remotly imho, just check the prototypes...)
I will shortly do a deeper audit of this last beta version and keep  
you informed.





Finally, I don't think an attack would be realistic, but I strongly  
suggest you update your code accordingly, to avoid any security issue  
(I'm not a great perl coder, nor a gaim developper, so I simply  
cannot say if those variables can be modified otherwise remotly).

As the header claims :
/*
* This file was generated automatically by xsubpp version 1.9508 from  
the
* contents of Gaim.xs. Do not edit this file, edit Gaim.xs instead.
*
*    ANY CHANGES MADE HERE WILL BE LOST!
*
*/
maybe you would like to had a fix format string in Gaim.xs rather.  
That shouldn't be too complicated since
the calls to the vulnerable function are declared as :

void
gaim_debug(level, category, string)
    Gaim::DebugLevel level
    const char *category
    const char *string


Feel free to contact me if you feel the need to. I would even  
appreciate a little feedback :)
If you ever want to give me credits for this discovery, you can quote  
"Jonathan Brossard, endrazine"
Thanks for your patience,

Best regards,



endrazine-













-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Darwin)

iD8DBQFFgII+UsDanPbyGdkRAuQkAKCQorK5pJGRqgppnhAI6bnMpa0+fwCfS5lR
/A/bR/aPnifJSEXqN3KILoE=
=9afF
-----END PGP SIGNATURE-----


More information about the Cabal mailing list