Bug 11942 - Heap overflow in handle_pdfname (pdf.c)
Heap overflow in handle_pdfname (pdf.c)
Status: RESOLVED FIXED
Product: ClamAV
Classification: ClamAV
Component: All
ALL
x86_64 GNU/Linux
: P1 security
: 0.99.3
Assigned To: Mickey Sola
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2017-10-26 18:51 EDT by Suleman Ali
Modified: 2021-09-23 16:35 EDT (History)
5 users (show)

See Also:
QA Contact:


Attachments
poc, pass is virus (308 bytes, application/x-zip-compressed)
2017-10-26 18:51 EDT, Suleman Ali
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Suleman Ali 2017-10-26 18:51:30 EDT
Created attachment 7307 [details]
poc, pass is virus

There a heap buffer overflow in ClamAV while analyzing a PDF file.

The bug happens when a PDF file contains a filter cascade larger than the designed size. The vulnerability is at `pdf.c:1242` inside the function `handle_pdfname`:
```c
1215 static void handle_pdfname(struct pdf_struct *pdf, struct pdf_obj *obj, const char *pdfname, int escapes, enum objstate *state)
1216 {
1217     struct pdfname_action *act = NULL;
1218     unsigned j;
1219 
1220     obj->statsflags |= OBJ_FLAG_PDFNAME_DONE;
1221 
1222     for (j=0;j<sizeof(pdfname_actions)/sizeof(pdfname_actions[0]);j++) {
1223         if (!strcmp(pdfname, pdfname_actions[j].pdfname)) {
1224             act = &pdfname_actions[j];
1225             break;
1226         }
1227     }
....
1240     /* record filter order */
1241     if ((*state == STATE_FILTER) && ((1 << act->set_objflag) & KNOWN_FILTERS))
1242         obj->filterlist[obj->numfilters++] = act->set_objflag;
```

`filterlist` is an array of 64 elements. 
```c
 25 #define PDF_FILTERLIST_MAX  64
...
 27 struct pdf_obj {
 28     uint32_t start;
 29     uint32_t id;
 30     uint32_t flags;
 31     uint32_t statsflags;
 32     uint32_t numfilters;
 33     uint32_t filterlist[PDF_FILTERLIST_MAX];
 34     char *path;
 35 };
```

When more than 64 encoding filters are used in cascade the variable `obj->numfilters` takes values greater than `64` and the buffer is overflown.

A filter cascade looks like this:
```
1 0 obj 
<<
/Filter /ASCII85Decode /FlateDecode /ASCIIHEXDecode /Fl /Fl /Fl
>>
stream
...
endstream
endobj
```
More information: https://blog.didierstevens.com/2008/05/19/pdf-stream-objects/

It is not possible to control the data being written. 
```c
1242         obj->filterlist[obj->numfilters++] = act->set_objflag;
```
The variable `act->set_objflag` contains a static identifier for the different encodings:
```c
OBJ_FILTER_AH		3
OBJ_FILTER_RL		7
OBJ_FILTER_A85		4
OBJ_FILTER_FLATE	5
OBJ_FILTER_LZW		6
OBJ_FILTER_FAX		8
OBJ_FILTER_DCT		10
OBJ_FILTER_JPX		11
OBJ_FILTER_CRYPT	12
```

The bug could be used to corrupt the heap, generating a Denial of Service or perhaps remote code execution.

A possible solution is to verify that the variable `numfilters` does not take a value higher than `64`:
```c
1241     if (obj->numfilters < PDF_FILTERLIST_MAX && (*state == STATE_FILTER) && ((1 << act->set_objflag) & KNOWN_FILTERS))
1242         obj->filterlist[obj->numfilters++] = act->set_objflag;
```

Backtrace:
```c
    #0 0x82ad1ee in handle_pdfname /tmp/clamav-devel/libclamav/pdf.c:1241:9
    #1 0x82ad1ee in pdf_parseobj /tmp/clamav-devel/libclamav/pdf.c:1536
    #2 0x82b3bce in cli_pdf /tmp/clamav-devel/libclamav/pdf.c:2458:9
    #3 0x8183656 in cli_scanpdf /tmp/clamav-devel/libclamav/scanners.c:1925:11
    #4 0x816cb15 in magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3389:19
    #5 0x8167904 in cli_base_scandesc /tmp/clamav-devel/libclamav/scanners.c:3616:11
    #6 0x8176391 in cli_magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3625:12
    #7 0x8176391 in scan_common /tmp/clamav-devel/libclamav/scanners.c:3891
    #8 0x8177162 in cl_scandesc_callback /tmp/clamav-devel/libclamav/scanners.c:4032:12
    #9 0x8177162 in cl_scanfile_callback /tmp/clamav-devel/libclamav/scanners.c:4099
    #10 0x8177162 in cl_scanfile /tmp/clamav-devel/libclamav/scanners.c:4082
```
Comment 1 Suleman Ali 2017-10-26 19:01:33 EDT
Wrong attachment, forgot to update template. 

This vulnerability has been found by Offensive Research at Salesforce.com:
Alberto Garcia (@algillera), Francisco Oca (@francisco_oca) & Suleman Ali (@Salbei_)
Comment 2 Suleman Ali 2017-10-26 19:02:15 EDT
Created attachment 7308 [details]
poc, pass is virus
Comment 3 Joel Esler 2017-10-27 09:51:47 EDT
Thank you very much for reporting these issues.  If possible, we'd like to gather some initial first details from you on these.  

First, can you tell us what version of ClamAV you are reporting against?  I notice that you have our git-repository name in the reports, is this a fresh check out of git?
Comment 4 Mickey Sola 2017-10-30 17:45:24 EDT
Went with the proposed solution here, tested with heuristic filter checks set above and below the max filter limit.

https://github.com/vrtadmin/clamav-devel/commit/c8ba4ae2e47a4f49add3e85ef7041b166be6bfdb