Sourcefire Vulnerability Report VRT-2013-1001 (CVE-2013-6487): Buffer overflow in Gadu-Gadu HTTP parsing

Description An exploitable remote code execution vulnerability exists in Pidgin's implementation of the Gadu Gadu protocol in the libpurple library. An attacker who can control the Content-Length of a HTTP request can cause an undersized allocation which can later be used to overflow into the heap. An attack requires the ability to spoof messages from the domain to exploit this vulnerability.

Tested Versions Pidgin 2.10.7

Coverage Prior coverage through an http_inspect alert GID 120, SID 8 as well as SID 2580.

Details In gg_http_watch_fd() in file pidgin-2.10.7\libpurple\protocols\gg\lib\http.c at line 353 content-length will be read from the HTTP server:

353     while (line) {
  354 if (!strncasecmp(line, "Content-length: ", 16)) {
  355             h->body_size = atoi(line + 16);
  356         }
  357         line = strchr(line, '\n');
  358         if (line)
  359 line++;
  360     }

It then checks if h->bodysize is less than or equal to 0, however h->body_size is an unsigned integer so a negative value will return a large positive size, meaning the check for less than zero will never be true:

362     if (h->body_size <= 0) {
  363         gg_debug(GG_DEBUG_MISC, "=> http, content-length not found\n");
  364         h->body_size = left;
  365     }

This check will also pass because left will not be larger than a negative body_size:

367     if (left > h->body_size) {
  368         gg_debug(GG_DEBUG_MISC, "=> http, oversized reply (%d bytes needed, %d bytes left)\n", h->body_size, left);
  369         h->body_size = left;
  370     }

if h->body_size is 4294967295 (or -1) then the below will result in a malloc(0):

374     if (!(h->body = malloc(h->body_size + 1))) {

Finally we reach our out of bounds write into the heap here:

381     if (left) {
  382         memcpy(h->body, tmp + sep_len, left);
  383         h->body_done = left;
  384     }

The client will keep copying data as long as there's data in the http response body and will then free the original heap chunk.