These vulnerabilities were discovered by Yves Younan.
Pidgin is a universal chat client that is used on millions of systems worldwide. The Pidgin chat client enables you to communicate on multiple chat networks simultaneously. Talos has identified multiple vulnerabilities in the way Pidgin handles the MXit protocol. These vulnerabilities fall into the following four categories.
- Information Leakage
- Denial Of Service
- Directory Traversal
- Buffer Overflow
The following vulnerabilities were identified (listed numerically by CVE):
CVE-2016-2365 - Pidgin MXIT Markup Command Denial of Service Vulnerability
CVE-2016-2366 - Pidgin MXIT Table Command Denial of Service Vulnerability
CVE-2016-2367 - Pidgin MXIT Avatar Length Memory Disclosure Vulnerability
CVE-2016-2368 - Pidgin MXIT g_snprintf Multiple Buffer Overflow Vulnerability
CVE-2016-2369 - Pidgin MXIT CP SOCK REC TERM Denial of Service Vulnerability
CVE-2016-2370 - Pidgin MXIT Custom Resource Denial of Service Vulnerability
CVE-2016-2371 - Pidgin MXIT Extended Profiles Code Execution Vulnerability
CVE-2016-2372 - Pidgin MXIT File Transfer Length Memory Disclosure Vulnerability
CVE-2016-2373 - Pidgin MXIT Contact Mood Denial of Service Vulnerability
CVE-2016-2374 - Pidgin MXIT MultiMX Message Code Execution Vulnerability
CVE-2016-2375 - Pidgin MXIT Suggested Contacts Memory Disclosure Vulnerability
CVE-2016-2376 - Pidgin MXIT read stage Ox3 Code Execution Vulnerability
CVE-2016-2377 - Pidgin MXIT HTTP Content-Length Buffer Overflow Vulnerability
CVE-2016-2378 - Pidgin MXIT get_utf8_string Code Execution Vulnerability
CVE-2016-2380 - Pidgin MXIT mxit_convert_markup_tx Information Leak Vulnerability
CVE-2016-4323 - Pidgin MXIT Splash Image Arbitrary File Overwrite Vulnerability
Information Leakage Vulnerabilities
Talos has discovered four information leakage vulnerabilities in the implementation of the MXit protocol as part of the Pidgin chat client. These vulnerabilities are
- CVE-2016-2367
- CVE-2016-2372
- CVE-2016-2375
- CVE-2016-2380
CVE-2016-2375
With this vulnerability, specially crafted MXIT data sent from the server could potentially result in an out-of-bounds read. In the function mxit_parse_cmd_suggestcontacts in the file mxit/protocol.c at line 2020 the number of attributes will be read from the incoming packet into the variable count.
2020 count = atoi( records[0]->fields[3]->data );
This value is subsequently used as the bounds for a loop at line 2030 and the loop index is used as an array index at lines 2034-2036.
2030for ( j = 0; j < count; j++ ) {
2034fname = records[0]->fields[4 + j]->data;/* field name */
2035 if ( records[i]->fcount > ( 2 + j ) )
2036 fvalue = records[i]->fields[2 + j]->data;/* field value */
The pointers set at these locations will subsequently be used to read data, potentially resulting in an out-of-bounds read, copying data into results fields, for example at lines 2056-2059:
2056else if ( strcmp( CP_PROFILE_FULLNAME, fname ) == 0 ) {
2057 /* nickname */
2058 g_strlcpy( profile->nickname, fvalue, sizeof( profile->nickname ) );
2059 }
Most of the out-of-bounds reads would simply result in a crash if a memory page is inaccessible since most information is not sent back to the server. However, when the add button is pushed, the a callback defined in mxit/profile.c is called. This can result in a leakage of information back to the server when the nickname is returned to the server since it will include the leaked information from memory.
CVE-2016-2380
An information leak exists in the handling of the MXIT protocol in Pidgin. Specially crafted MXIT data sent to the server could potentially result in an out of bounds read. A user could be convinced to enter a particular string which would then get converted incorrectly and could lead to a potential out-of-bounds read.
When a message is sent by Pidgin to the server, it has to convert the markup from libpurple (HTML-based) markup to MXIT markup. To do this, the function mxit_convert_markup_tx defined in the file markup.c will be called.
This function will copy the data from the old string message to the new string mx, converting it along the way.
However, at lines 1146-1154 it will convert the markup to change the font color without checking the length of the string that is remaining:
1146else if ( purple_str_has_prefix( &message[i], "<font color=" ) ) {
1147/* font colour */
1148tag = g_new0( struct tag, 1 );
1149tag->type = MXIT_TAG_COLOR;
1150tagstack = g_list_append( tagstack, tag );
1151memset( color, 0x00, sizeof( color ) );
1152memcpy( color, &message[i + 13], 7 );
1153g_string_append( mx, color );
1154}
It will compare if the string starts with <font color= at the current position in the message at line 1146. If it does it will copy 7 bytes from 1 element past the end of “=”, presumably to skip over the “#” tag. However, if “<font color=” is at the end of the string then this will result in an out-of-bounds read of message. Since one byte after the end of the “=” will be skipped over, the NULL termination string will be skipped over, allowing the 7 bytes of data behind the string to be copied to the mx, which is the string that will be sent to the server.
In addition to DoS issues, CVE-2016-2367 & CVE-2016-2372 can also result in a leakage of information. CVE-2016-2367 can potentially leak sensitive information from memory into the data after the avatar which can then be transferred when the avatar is copied. CVE-2016-2372 can potentially leak sensitive information by appending sensitive information from memory to the end of a received file.
Denial of Service Vulnerabilities
Talos has discovered six DoS vulnerabilities in the implementation of the MXit protocol as part of the Pidgin chat client.
- CVE-2016-2365
- CVE-2016-2366
- CVE-2016-2367
- CVE-2016-2369
- CVE-2016-2370
- CVE-2016-2372
CVE-2016-2365
In this vulnerability, specially crafted MXIT data sent via the server could potentially result in a null pointer dereference. This occurs because of the processing of insufficient checks to validate that all required fields have been provided to successfully execute the commands received. When a command is received in a message, the function mxit_parse_command() is called to find values in the key=value format and insert these pairs into a hashtable:
580hash = command_tokenize(start);/* break into <key,value> pairs */
It will then check what type of command it is dealing with and call the appropriate function.
The following two functions
command_imagestrip()
command_table()
rely on key/value pairs that, if not defined, will cause a null pointer dereference. The first function command_imagestrip() is defined at line 383 in mxit/formcmds.c: At lines 393-399 it will look up the values of the keys nm, v and dat:
392/* image strip name */
393name = g_hash_table_lookup(hash, "nm");
394
395/* validator */
396validator = g_hash_table_lookup(hash, "v");
397
398/* image data */
399tmp = g_hash_table_lookup(hash, "dat");
While there is a check at line 400 to ensure that tmp is not NULL, there are no similar checks for name and validator. This will cause a null pointer dereference when they are used at lines 419 and 420:
419escname = g_strdup(purple_escape_filename(name));
420escvalidator = g_strdup(purple_escape_filename(validator));
The keys fw, fh and layer have similar errors at lines 432-439:
432tmp = g_hash_table_lookup(hash, "fw");
433width = atoi(tmp);
434
435tmp = g_hash_table_lookup(hash, "fh");
436height = atoi(tmp);
437
438tmp = g_hash_table_lookup(hash, "layer");
439layer = atoi(tmp);
Similar errors also occur in the function command_table() defined in mxit/formcmds.c at lines 530-543:
530tmp = g_hash_table_lookup(hash, "col");
531nr_columns = atoi(tmp);
532
533/* number of rows */
534tmp = g_hash_table_lookup(hash, "row");
535nr_rows = atoi(tmp);
536
537/* mode */
538tmp = g_hash_table_lookup(hash, "mode");
539mode = atoi(tmp);
540
541/* table data */
542tmp = g_hash_table_lookup(hash, "d");
543coldata = g_strsplit(tmp, "~", 0);
If any of these key/value pairs are missing, a crash will ensue. A malicious server or an attacker who intercepts the network traffic can send invalid data to trigger this vulnerability and cause a crash
CVE-2016-2366
In this vulnerability, specially crafted MXIT data sent via the server could potentially result in an out-of-bounds read. In the function command_table in mxit/formcmds.c at lines 531 and 535, the number of rows and columns for the table are received from the server.
531 nr_columns = atoi(tmp);
535 nr_rows = atoi(tmp);
These two values are then used in loops at line 547 and 548 to access an array at line 549.
547 for (i = 0; i < nr_rows; i++) {
548for (j = 0; j < nr_columns; j++) {
549purple_debug_info(MXIT_PLUGIN_ID, " Row %i Column %i = %s\n", i, j, coldata[i*nr_columns + j]);
550 }
551 }
The data read from the array is not passed to the server so this is not an information leak, but it can still cause a crash if the memory accessed is on a memory page that can't be accessed. A malicious server or an attacker who intercepts the network traffic can send invalid data to trigger this vulnerability and cause a crash.
CVE-2016-2367
With this vulnerability, specially crafted MXIT data sent via the server could potentially result in an out of bounds read. When an avatar is received via the MXIT server, the server will send a CP_CHUNK_GET_AVATAR command. This will be handled by the function mxit_parse_cmd_media at lines 2208-2234 of mxit/protocol.c. At line 2215
2215 mxit_chunk_parse_get_avatar( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk );
it will call the function mxit_chunk_parse_get_avatar() which will read the size of the chunk from the data at line 683 of mxit/chunk.c
683pos += get_int32( &chunkdata[pos], &(avatar->length) );
If the length of the chunk that was specified is longer than the buffer, it will result in an out-of-bounds read and the resulting data in memory will be written after the received avatar. Depending on the memory layout of the program at the time the vulnerability is triggered this could result in a scenario where either program crashes because pages are not accessible or where sensitive data is leaked from memory into the file. The user may decide to copy this avatar to other places or might send it to another user, which would result in the leaking of this data.
A malicious server, an attacker who intercepts the network traffic or a malicious user can send an invalid size for a file which will trigger an out-of-bounds read vulnerability. This could result in a denial of service or if the avatar is sent on to another or the same user, it could result in an information leak.
CVE-2016-2369
With this vulnerability, specially crafted MXIT data sent via the server could potentially result in a NULL pointer dereference. The function mxit_parse_packet() in mxit/protocol.c is called when data is received from an MXIT server to parse the relevant stream of bytes into an MXIT packet.
When the packet is received, a new record is created in the packet to reflect the data:
2672rec = NULL;
2673field = NULL;
2674memset( &packet, 0x00, sizeof( struct rx_packet ) );
2675rec = add_record( &packet );
The function add_record does the following:
2634static struct record* add_record( struct rx_packet* p )
2635 {
2636 struct record*rec;
2637 rec = g_new0( struct record, 1 );
2638 p->records = g_realloc( p->records,
2639 sizeof( struct record* ) * ( p->rcount + 1 ) );
2640 p->records[p->rcount] = rec;
2641 p->rcount++;
2642 return rec;
2643 }
This will create a record in the packet and increasing the rcount variable by 1.
At lines 2679-2744 the packet is further analyzed and broken up into records and fields depending on if the separator being used is 0x0,0x1 or 0x2.
The following code if of particular interest:
2679while ( ( i < session->rx_i ) && ( !pbreak ) ) {
2680 switch ( session->rx_dbuf[i] ) {
2681case CP_SOCK_REC_TERM :
2682/* new record */
2683 if ( packet.rcount == 1 ) {
2684/* packet command */
2885
2686packet.cmd = atoi( packet.records[0]->fields[0]->data );
2687 }
The value CP_SOCK_REC_TERM indicates that the end of a record is reached and it will retrieve the command that the packet is sending. However, if the packet starts with a NULL byte then the fields variable for the record will not have been initialized resulting in a crash when trying to dereference it at line 2686. Specially crafted MXIT data sent via the server could potentially result in a denial of service vulnerability. A malicious server can send a packet starting with a NULL byte triggering the vulnerability.
CVE-2016-2370
With this vulnerability, specially crafted MXIT data sent via the server could potentially result in an out-of-bounds read. The function mxit_chunk_parse_cr(), which is defined in the file mxit/chunk.c, is used to parse custom resources like a new splash image. These type of resources are sent as part of a multimedia packet.
At lines 573 the length of the chunk is read from the chunk being parsed without bounds checks. This chunk can contain one or more resource chunks that are set at line 577. The size of the resource chunk is contained at the top of the chunk and again the size is read without bounds checks at lines 587 and 604:
573pos += get_int32( &chunkdata[pos], &chunklen );
574
575 /* parse the resource chunks */
576 while ( chunklen > 0 ) {
577gchar* chunk = &chunkdata[pos];
578
579 /* start of chunk data */
580 pos += MXIT_CHUNK_HEADER_SIZE;
581
582switch ( chunk_type( chunk ) ) {
583 case CP_CHUNK_SPLASH :/* splash image */
584 {
585 struct splash_chunk* splash = g_new0( struct splash_chunk, 1 );
586
587mxit_chunk_parse_splash( &chunkdata[pos], chunk_length( chunk ), splash );
588
589 cr->resources = g_list_append( cr->resources, splash );
590 break;
591 }
592 case CP_CHUNK_CLICK :/* splash click */
593 {
594 struct splash_click_chunk* click = g_new0( struct splash_click_chunk, 1 );
595
596 cr->resources = g_list_append( cr->resources, click );
597 break;
598 }
599 default:
600 purple_debug_info( MXIT_PLUGIN_ID, "Unsupported custom resource chunk received (%i)\n", chunk_type( chunk) );
601 }
602
603 /* skip over data to next resource chunk */
604pos += chunk_length( chunk );
605 chunklen -= ( MXIT_CHUNK_HEADER_SIZE + chunk_length( chunk ) );
This length is then used to access data in the chunk at lines 582 and 587, resulting in an out-of-bounds read. This data is not sent back to the server, so it is unlikely to result in an information leak vulnerability, but could result in a denial of service when accessing the out-of-bounds memory if the accessed location is not an allocated memory region.
CVE-2016-2372
With this vulnerability, specially crafted MXIT data sent via the server could potentially result in an out-of-bounds read. When a file transfer is received via the MXIT server, the server will send a CP_CHUNK_GET command. This will be handled by the function mxit_parse_cmd_media at lines 2195-2206 of mxit/protocol.c.
2195case CP_CHUNK_GET :/* get file response */
2196 {
2197 struct getfile_chunk chunk;
2198
2199 /* decode the chunked data */
2200 memset( &chunk, 0, sizeof( struct getfile_chunk ) );
2201mxit_chunk_parse_get( &records[0]->fields[0]->data[sizeof( char ) + sizeof( int )], records[0]->fields[0]->len, &chunk );
2202
2203 /* process the getfile */
2204mxit_xfer_rx_file( session, chunk.fileid, chunk.data, chunk.length );
2205 }
2206break;
At line 2201 it will call the function mxit_chunk_parse_get which will read the size of the file (and some other information on the file) into the getfile_chunk structure. This function is defined in the file mxit/chunk.c and the length is read at line 509:
509pos += get_int32( &chunkdata[pos], &(getfile->length) );
After this function has parsed the information and returned, the function mxit_xfer_rx_file will be called at line 2204.
This function is defined in the file mxit/filexfer.c, where at line 445 it will read from the received buffer into the file:
445if ( fwrite( data, datalen, 1, xfer->dest_fp ) > 0 ) {
If the length of the chunk that was specified is longer than the buffer, it will result in an out-of-bounds read and the resulting data in memory will be written after the newly received file. Depending on the memory layout of the program at the time the vulnerability is triggered this could result in a scenario where either program crashes because pages are not accessible or where sensitive data is leaked from memory into the file. Since the file may be innocuous, the victim may send it on to someone else or even send it back to the attacker, resulting in a leak of this data.
Directory Traversal Vulnerability
Talos has discovered one directory traversal vulnerability in the implementation of the MXit protocol as part of the Pidgin chat client. This vulnerability is
- CVE-2016-4323
CVE-2016-4323
A directory traversal exists in the handling of the MXIT protocol in Pidgin. Specially crafted MXIT data sent from the server could potentially result in an overwrite of files. A malicious server or someone with access to the network traffic can provide an invalid filename for a splash image triggering the vulnerability.
Pidgin allows the MXIT server to provide a splash image to show when connecting to the server. The server can also update this image by providing a new one via a command sent back from the server.
When the server provides a new image via a multimedia command then the function splash_update will be called at line 2170 of mxit/protocol.c:
2170 splash_update( session, chunk.id, splash->data, splash->datalen, clickable );
The variable chunk.id is read from data coming from the server in the function mxit_chunk_parse_cr at line 564:
564 pos += get_utf8_string( &chunkdata[pos], cr->id, sizeof( cr->id ) );
The function splash_update is defined in mxit/splashscreen.c at lines 115-136:
115 void splash_update(struct MXitSession* session, const char* splashId, const char* data, int datalen, gboolean clickable)
116 {
117 char* dir;
118 char* filename;
119
120 /* Remove the current splash-screen */
121 splash_remove(session);
122
123 /* Save the new splash image */
124 dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "mxit", purple_user_dir());
125 purple_build_dir(dir, S_IRUSR | S_IWUSR | S_IXUSR);
126 /* ensure directory exists */
127filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.png", dir, purple_escape_filename(splashId));
128 if (purple_util_write_data_to_file_absolute(filename, data, datalen)) {
129 /* Store new splash-screen ID to settings */
130 purple_account_set_string(session->acc, MXIT_CONFIG_SPLASHID, splashId);
131
132 purple_account_set_bool(session->acc, MXIT_CONFIG_SPLASHCLICK, clickable );
133 }
134 g_free(dir);
135 g_free(filename);
136 }
At line 127 splashId will be correctly escaped to prevent a directory traversal from occurring. However the unescaped string is stored in the MXIT_CONFIG_SPLASHID variable at line 130. The function splash_remove, which is called at line 121 in this function, will use MXIT_CONFIG_SPLASHID to find the file to delete (lines 84-104):
84 void splash_remove(struct MXitSession* session)
85 {
86 const char* splashId = NULL;
87 char* filename;
88
89 /* Get current splash ID */
90 splashId = splash_current(session);
91
92 if (splashId != NULL) {
93 purple_debug_info(MXIT_PLUGIN_ID, "Removing splashId: '%s'\n", splashId);
94
95 /* Delete stored splash image */
96 filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "mxit" G_DIR_SEPARATOR_S "%s.png", purple_user_dir(), splashId);
97 g_unlink(filename);
98 g_free(filename);
99
100 /* Clear current splash ID from settings */
101 purple_account_set_string(session->acc, MXIT_CONFIG_SPLASHID, "");
102 purple_account_set_bool(session->acc, MXIT_CONFIG_SPLASHCLICK, FALSE);
103 }
104 }
However unlike in splash_update, in this case there is no escaping of the filename, allowing an attacker to delete arbitrary png files on the system.
Buffer Overflow Vulnerabilities
Talos has discovered five directory traversal vulnerabilities in the implementation of the MXit protocol as part of the Pidgin chat client. The vulnerabilities are
- CVE-2016-2368
- CVE-2016-2371
- CVE-2016-2376
- CVE-2016-2377
- CVE-2016-2378
CVE-2016-2368
WIth this vulnerability, specially crafted MXIT data sent via the server could potentially result in a buffer overflow. The MXIT plugin for Pidgin uses the function g_snprintf in about 27 places where it receives the return value of the function. When g_snprintf returns, it will return the number of bytes that would have been written had the buffer been large enough, not the amount of bytes that have actually been written. This is described at
https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-snprintf:
The MXIT plugin uses the return value of g_snprintf as an index or an offset into the string that is being manipulated in multiple locations without making sure that the return value is within bounds. This could potentially lead to a buffer overflow. An example of this issue is illustrated by lines 467-479 in the mxit_queue_packet() function.
467hlen = g_snprintf( header, sizeof( header ), "id=%s%c", purple_account_get_username( session->acc ), CP_REC_TERM );/* client mxitid */
468
469if ( session->http ) {
470/* http connection only */
471hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "s=");
472if ( session->http_sesid > 0 ) {
473hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_sesid, CP_FLD_TERM );/* http session id */
474}
475session->http_seqno++;
476hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "%u%c", session->http_seqno, CP_REC_TERM );/* http request sequence id */
477}
478
479hlen += g_snprintf( header + hlen, sizeof( header ) - hlen, "cm=%i%c", cmd, CP_REC_TERM ); /* packet command */
A long user account returned at line 467 will potentially cause buffer overflows at lines 471, 473, 476 or 479. While it is recommended that all return values of g_snprintf are checked, the advisory(provide link) highlights 12 calls spread over 7 functions appear to be the most problematic as they will copy data that might come from an untrusted location into a string. A malicious server or a potentially malicious user (if the data is not validated by the server) can send data which will be used incorrectly with g_snprintf, potentially resulting in a buffer overflow.
CVE-2016-2371
WIth this vulnerability, specially crafted MXIT data sent via the server could potentially result in a buffer overflow. The function mxit_parse_cmd_extprofile() is called when extended profile packets are received from the server. At line 1837 it will read the number of attributes that were sent by the server into the variable count.
1837count = atoi( records[0]->fields[1]->data );
This value is subsequently used as the bounds for a loop at line 1839 and used to calculate the index into an array at line 1843 and that value is subsequently used to access values in the array at lines 1845-1847.
1839for ( i = 0; i < count; i++ ) {
1840char* fname;
1841char* fvalue;
1842char* fstatus;
1843int f = ( i * 3 ) + 2;
1844
1845fname = records[0]->fields[f]->data;/* field name */
1846fvalue = records[0]->fields[f + 1]->data;/* field value */
1847fstatus = records[0]->fields[f + 2]->data;/* field status */
The index is also used to write to an array at lines 1859-1860 potentially causing an out-of-bounds write.
1859fvalue[10] = '\0';
1860 records[0]->fields[f + 1]->len = 10;
A malicious server, an attacker who intercepts the network traffic or a potentially malicious user (if the data is not validated by the server) can send an invalid number of records, which could result in an out-of-bounds write of data.
CVE-2016-2376
Specially crafted MXIT data sent from the server could potentially result in a buffer overflow. The function mxit_cb_rx in the file mxit/protocol.c is a callback function will be called by Pidgin whenever data is sent from the MXIT server. When data is received, the size of the incoming packet will also be received at line 2825. There is a check at line 2826 to ensure that this data isn’t larger than the maximum size of that an MXIT packet can be which is defined as CP_MAX_PACKET.
2825session->rx_res = atoi( &session->rx_lbuf[3] );
2826if ( session->rx_res > CP_MAX_PACKET ) {
purple_connection_error( session->con, _( "A connection error occurred to MXit. (read stage 0x03)" ) );
2827 }
This is also the size of the buffer that the data is read into. However if the size is larger than CP_MAX_PACKET, an error will be logged but execution will simply continue. Moreover, if the size is negative (this is possible since rx_res is an int) then no error will be logged and execution will also continue. This size will be subsequently used in a read operation at line 2846.
2846len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res );
A malicious server or an attacker who intercepts the network traffic can send an invalid size for a packet which will trigger a buffer overflow.
CVE-2016-2377
Specially crafted MXIT data sent by the server could potentially result in an out of bounds write of one byte. When receiving a reply to a HTTP request from the HTTP server the callback function mxit_cb_http_read(), defined in mxit/http.c, will be called. This function will parse the HTTP headers and then send the body off for processing as a regular MXIT packet. As part of HTTP header parsing that occurs, the CONTENT_LENGTH is read from the headers at lines 178-185:
178ch += strlen( HTTP_CONTENT_LEN );
179tmp = strchr( ch, '\r' );
180if ( !tmp ) {
181 purple_debug_error( MXIT_PLUGIN_ID, "Received bad HTTP reply
packet (ignoring packet)\n" );
182goto done;
183}
184tmp = g_strndup( ch, tmp - ch );
185bodylen = atoi( tmp );
bodylen is defined as a signed integer and thus the input read from the HTTP header could be negative. There is a size check at lines 189-192:
189if ( buflen + bodylen >= CP_MAX_PACKET ) {
190/* this packet is way to big */
191goto done;
192}
However this check will pass if bodylen is set to a negative value.
At line 206 bodylen is copied to the variable session->rx_i which is an unsigned integer, thus casting a potential negative bodylen to a large positive value.
206session->rx_i = bodylen;
This value is then later used to control a loop when the packet is processed in the function mxit_parse_packet in mxit/procotol.c at line 2669:
2669while ( i < session->rx_i ) {
The index i is subsequently used a multiple locations to write to the buffer rx_dbuf, including at lines 2713, 2720 and 2729. This could allow an attacker to execute a buffer overflow on the buffer rx_dbuf.
A malicious server can send a negative content-length in response to a HTTP request triggering the vulnerability.
CVE-2016-2378
A buffer overflow vulnerability exists in the handling of the MXIT protocol Pidgin. Specially crafted data sent via the server could potentially result in a buffer overflow, potentially resulting in memory corruption. The function get_utf8_string, defined at line 231 in libpurple/protocols/mxit/chunk.c will take a maximum string length as an argument. Usually this is passed in as the size of the string str that is being written to.
It will read the length of the string at line 238 and check to ensure that it is not larger than the maximum string length at line 240. If it is, it will set the length to be equal to maxstrlen.
238pos += get_int16( &chunkdata[pos], &len );
239
240if ( len > maxstrlen ) {
243 skip = len - maxstrlen;
244len = maxstrlen;
245}
However, len is a signed short that will be read from nthos, which will read an unsigned integer, but because len is signed it will be cast to a signed integer. If the value of len is a large positive value it will be cast to a negative value, bypassing the size check at line 240.
The call to get_data at line 248 will then result in a buffer overflow:
248pos += get_data( &chunkdata[pos], str, len );
The function get_data will end up calling memcpy which expects an unsigned size parameter and will interpret a negative value as a large positive value.
A malicious server or a potentially malicious user (if the data is not validated by the server) can send negative length values to trigger this vulnerability.
Conclusion
Communicating quickly and efficiently using instant messaging software has made this software very popular. Consequently, attackers are constantly trying to find and exploit vulnerabilities in instant messaging applications because it gives them access to a large number of potential victims. Patching software is crucial to reducing the attack surface against these constant ongoing attacks. Many users do not patch regularly, which can provide an easy avenue that an attacker can use to gain access to a system. The Pidgin instant messaging client is installed on many systems and installing the latest updated version (2.11.0) is vital to protecting against the vulnerabilities identified by Talos. You can find the latest pidgin software releases here.
Mitigations
Talos has released rules that detect attempts to exploit these vulnerabilities to protect our customers. Please note that additional rules may be released at a future date and current rules are subject to change pending additional vulnerability information. For the most current rule information, please refer to your Defense Center, FireSIGHT Management Center or Snort.org.
Snort rules: 38344,38345,38545-38551,38578,38867,38870,39150,39151