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 gadu-gadu.pl 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.