Talos Vulnerability Report

VRT-2014-0203

Pidgin libpurple Mxit Emoticon ASN Length Denial of Service Vulnerability

Nov 6, 2014

Description

An exploitable denial of service vulnerability exists in Pidgin''s implementation of the Mxit protocol in the libpurple library. An attacker who can control the contents of an Emoticon downloaded through the Mxit protocol can cause an out of bounds read by specifying an overly large ASN length value. Since this data is not returned to the attacker, the impact is limited to a denial of service. An attack requires the ability to spoof messages from the mxit.com domain to exploit this vulnerability.

Tested Versions

Pidgin 2.10.7

Product URLs

http://www.pidgin.im/

Details

When downloading an emoticon via the mxit protocol, it is possible to cause an out of bounds read by providing an invalid length. This occurs in the function emoticonreturned() at line 520 in file pidgin-2.10.7\libpurple\protocols\mxit\markup.c

  res = asngetlength( &data[pos], &emsize );
          if ( res <= 0 ) {
              /* bad frame length */
              purpledebugerror( MXITPLUGINID, "Invalid emoticon received from wapsite (bad frame length)\n" );
              goto done;
          }
          pos += res;
        #ifdef  MXITDEBUGEMO
          purpledebuginfo( MXITPLUGINID, "read the length ''%i''\n", emsize );
        #endif
          /* utf-8 (emoticon name) */
          res = asn_getUtf8( &data[pos], 0x0C, &str );
        

The function asngetlength() will do the following:

static unsigned int asngetlength( const char* data, int* size )
        {
            unsigned int    len     = 0;
            unsigned char   bytes;
            unsigned char   byte;
            int             i;

        /* first byte specifies the number of bytes in the length */
        bytes = ( data[0] & ~0x80 );
        if ( bytes > sizeof( unsigned int ) ) {
            /* file too big! */
            return -1;
        }
        data++;

        /* parse out the actual length */
        for ( i = 0; i < bytes; i++ ) {
            byte = data[i];
            len <<= 8;
            len += byte;
        }

        *size = len;
        return bytes + 1;

        }
        

This function parses and returns a 4 byte size value from the ASN format. However, the only validation that occurs on the value is to ensure that the result is not negative. There is no check to ensure that the returned result is within the bounds of the memory pointed to by data. It will simply add the returned value to pos at line 526 and use that as an index into data at line 532, allowing an attacker to specify up to 2GB read length.

Credit

Discovered by Yves Younan and Richard Johnson Sourcefire VRT