Bug 11944 - Heap overflow in messageAddArgument (message.c)
Heap overflow in messageAddArgument (message.c)
Status: RESOLVED FIXED
Product: ClamAV
Classification: ClamAV
Component: All
ALL
x86_64 GNU/Linux
: P1 security
: 0.99.3
Assigned To: Steven Morgan
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2017-10-26 19:21 EDT by Suleman Ali
Modified: 2021-09-23 16:36 EDT (History)
7 users (show)

See Also:
QA Contact:


Attachments

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

There is a  heap-buffer-overflow at /message.c:442 when function strchr is called on a string, the function keeps reading the allocated memory because the "=" is removed from the input previously.

In message.c, within the messageAddArgument function we have the following line
```c
435             p = m->mimeArguments[offset] = rfc2231(arg);
```

The code takes arg, which in this poc is "numberDelivered-To:**0*=*/Received:" and transforms it to "numberDelivered-To:0/Received:'\276' <repeats 21 times>".

The function responsible for removing the '=' and '*' from arg is below. The error seems to be the way "*" case is coded. *p is ='\0' is never reached due to the continue. 

rfc2231
```C
2317                    do {
2318                            switch(*in) {
2319                                    default:
2320                                            *p++ = *in++;
2321                                            continue;
2322                                    case '*':
02323                                            do
2324                                                    in++;
2325                                            while((*in != '*') && *in);
2326                                            if(*in) {
2327                                                    in++;
2328                                                    continue;
2329                                            }
2330                                            *p = '\0';
2331                                            break;
2332                                    case '=':
2333                                            /*strcpy(p, in);*/
2334                                            strcpy(p, "=rfc2231failure");
2335                                            break;
2336                            }
2337                            break;
2338                    } while(*in);
2340                    cli_dbgmsg("RFC2231 parameter continuations are not yet handled, returning \"%s\"\n",
2341                            ret);
2342                    return ret;
```

There are multiple ways to patch this, one is to uncomment the code because the RGC is not supported anyway. Secondly we could fix the buggy case so a null termination is reached by removing the continue, strchr will stop at null termination. Alternately we could fix the while loop in the "*" case so its only running when there are "*" and not removing the "=", the "=" is handled by its appropriate case. The proper fix depends on what exactly the developer was trying to achieve and what the RFC2231 says to do when * is encoutered.

Backtrace:
```c
    #0 0x80e2083 in __interceptor_index (/tmp/x/x+0x80e2083)
    #1 0x81a8c53 in messageAddArgument /tmp/clamav-devel/libclamav/message.c:442:5
    #2 0x81a9894 in messageAddArguments /tmp/clamav-devel/libclamav/message.c:640:4
    #3 0x819ff7c in parseMimeHeader /tmp/clamav-devel/libclamav/mbox.c:2914:6
    #4 0x819ff7c in parseEmailHeader /tmp/clamav-devel/libclamav/mbox.c:1088
    #5 0x819480b in parseEmailFile /tmp/clamav-devel/libclamav/mbox.c:785:8
    #6 0x819480b in cli_parse_mbox /tmp/clamav-devel/libclamav/mbox.c:546
    #7 0x819480b in cli_mbox /tmp/clamav-devel/libclamav/mbox.c:353
    #8 0x8182f73 in cli_scanmail /tmp/clamav-devel/libclamav/scanners.c:2010:16
    #9 0x816e5d2 in magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3291:19
    #10 0x8167904 in cli_base_scandesc /tmp/clamav-devel/libclamav/scanners.c:3616:11
    #11 0x8167473 in cli_magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3625:12
    #12 0x861981b in fileblobScan /tmp/clamav-devel/libclamav/blob.c:646:7
    #13 0x86192bb in fileblobScanAndDestroy /tmp/clamav-devel/libclamav/blob.c:400:9
    #14 0x8197aae in parseEmailBody /tmp/clamav-devel/libclamav/mbox.c:2333:7
    #15 0x8194e47 in cli_parse_mbox /tmp/clamav-devel/libclamav/mbox.c:555:11
    #16 0x8194e47 in cli_mbox /tmp/clamav-devel/libclamav/mbox.c:353
    #17 0x8182f73 in cli_scanmail /tmp/clamav-devel/libclamav/scanners.c:2010:16
    #18 0x816e5d2 in magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3291:19
    #19 0x8167904 in cli_base_scandesc /tmp/clamav-devel/libclamav/scanners.c:3616:11
    #20 0x8176391 in cli_magic_scandesc /tmp/clamav-devel/libclamav/scanners.c:3625:12
    #21 0x8176391 in scan_common /tmp/clamav-devel/libclamav/scanners.c:3891
    #22 0x8177162 in cl_scandesc_callback /tmp/clamav-devel/libclamav/scanners.c:4032:12
    #23 0x8177162 in cl_scanfile_callback /tmp/clamav-devel/libclamav/scanners.c:4099
    #24 0x8177162 in cl_scanfile /tmp/clamav-devel/libclamav/scanners.c:4082
```
Eventually the code below in message.c(messageAddArgument) is executed, since there is no null termination in p, it keeps reading memory.
```c
442             if(strchr(p, '=') == NULL) {
```


The poc is below

```
Content-Type:;numberDelivered-To:**0*=*/Received
```

This vulnerability has been found by Offensive Research at Salesforce.com:
Alberto Garcia (@algillera), Francisco Oca (@francisco_oca) & Suleman Ali (@Salbei_)
Comment 1 Joel Esler 2017-10-27 09:51:56 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 2 Steven Morgan 2017-11-01 16:53:25 EDT
fixed in commit 0604618374dc0dfd148b0ce7bf7a3d2b7528e66b/