Pidgin MXIT Splash Image Arbitrary File Overwrite Vulnerability

2016-06-21T00:00:00
ID TALOS-2016-0128
Type talos
Reporter Talos Intelligence
Modified 2016-06-21T00:00:00

Description

Talos Vulnerability Report

TALOS-2016-0128

Pidgin MXIT Splash Image Arbitrary File Overwrite Vulnerability

June 21, 2016
CVE Number

CVE-2016-4323

DESCRIPTION

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.

CVSSv3 SCORE

4.8 CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L

TESTED VERSIONS

Pidgin 2.10.11

PRODUCT URLs

https://www.pidgin.im/

DETAILS

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:

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:

void splash_update(struct MXitSession* session, const char* splashId, const char* data, int datalen, gboolean clickable)
{
    char* dir;
    char* filename;

    /* Remove the current splash-screen */
    splash_remove(session);

    /* Save the new splash image */
dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "mxit", purple_user_dir());

       purple_build_dir(dir, S_IRUSR | S_IWUSR | S_IXUSR);      
       /* ensure directory exists */

127 filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s.png", dir, purple_escape_filename(splashId));

       if (purple_util_write_data_to_file_absolute(filename, data, datalen)) {
        /* Store new splash-screen ID to settings */
purple_account_set_string(session->acc, MXIT_CONFIG_SPLASHID, splashId);

purple_account_set_bool(session->acc, MXIT_CONFIG_SPLASHCLICK, clickable );
    }

    g_free(dir);
    g_free(filename);
}

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):

void splash_remove(struct MXitSession* session)
{
    const char* splashId = NULL;
    char* filename;

    /* Get current splash ID */
    splashId = splash_current(session);

    if (splashId != NULL) {
purple_debug_info(MXIT_PLUGIN_ID, "Removing splashId: '%s'\n", splashId);

        /* Delete stored splash image */
filename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "mxit" G_DIR_SEPARATOR_S "%s.png", purple_user_dir(), splashId);
        g_unlink(filename);
        g_free(filename);

        /* Clear current splash ID from settings */
purple_account_set_string(session->acc, MXIT_CONFIG_SPLASHID, "");
purple_account_set_bool(session->acc, MXIT_CONFIG_SPLASHCLICK, FALSE);
    }
}

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.

TIMELINE

2016-04-12 - Initial Vendor Contact
2016-06-21 - Public Disclosure

Credit

Discovered by Yves Younan of Cisco Talos.


Vulnerability Reports Next Report

TALOS-2016-0133

Previous Report

TALOS-2016-0123