X41 D-Sec GmbH Security Advisory: X41-2017-002 Multiple Vulnerabilities in ytnef ================================= Overview -------- Severity Rating: High Confirmed Affected Versions: 1.9 and earlier Confirmed Patched Versions: 1.9.1 Vendor: Yerase Vendor URL: https://github.com/Yeraze/ytnef Vector: Via file Credit: X41 D-Sec GmbH, Eric Sesterhenn Status: public CVE: not yet assigned CVSS Score: 7.4 CVSS Vector: CVSS:3.0/AV:L/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:N Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2017-002-ytnef/ Summary and Impact ------------------ Multiple Heap Overflows, out of bound writes and reads, NULL pointer dereferences and infinite loops have been discovered in ytnef 1.9 an earlier. These could be exploited by tricking a user into opening a malicious winmail.dat file. Product Description ------------------- ytnef offers a library and utilities to extract the files from winmail.dat files. winmail.dat files are send by Microsoft Outlook when forwarding files via e-mail. The vendor was very responsive in providing a patched version. Analysis -------- Due to the big amount of issues found no detailed analysis is given here. Almost all allocations were unchecked and out of bounds checks rarely performed in the code. In total 9 patches were generated for the following issues: 1. Null Pointer Deref / calloc return value not checked 2. Infinite Loop / DoS 3. Buffer Overflow in version field 4. Out of Bound Reads 5. Integer Overflow 6. Invalid Write and Integer Overflow 7. Out of Bounds read 8. Out of Bounds read and write 9. Directory Traversal using the filename To detail some of the findings, here are excerpts from the quickly written patch, which was send to the vendor: Missing out of bounds checks: diff --git a/lib/ytnef.c b/lib/ytnef.c index ad92f15..5dd07a7 100644 --- a/lib/ytnef.c +++ b/lib/ytnef.c @@ -55,6 +55,7 @@ #define MIN(x,y) (((x)<(y))?(x):(y)) #define ALLOCCHECK(x) { if(!x) { printf("Out of Memory\n"); exit(-1); } } +#define SIZECHECK(x) { if ((((char *)d - (char *)data) + x) >= size) { printf("Corrupted file\n"); exit(-1); } } void TNEFFillMapi(TNEFStruct *TNEF, BYTE *data, DWORD size, MAPIProps *p); void SetFlip(void); @@ -427,9 +428,11 @@ void TNEFFillMapi(TNEFStruct *TNEF, BYTE *data, DWORD size, MAPIProps *p) { length = -1; if (PROP_ID(mp->id) >= 0x8000) { // Read the GUID + SIZECHECK(16); memcpy(&(mp->guid[0]), d, 16); d += 16; + SIZECHECK(4); length = SwapDWord((BYTE*)d, 4); Infinite Loop: diff --git a/lib/ytnef.c b/lib/ytnef.c index 328e605..43b0e56 100644 --- a/lib/ytnef.c +++ b/lib/ytnef.c @@ -546,6 +546,9 @@ void TNEFFillMapi(TNEFStruct *TNEF, BYTE *data, DWORD size, MAPIProps *p) { memcpy(vl->data, d, vl->size); d+=16; break; + default: + printf("Bad file\n"); + exit(-1); } switch (PROP_ID(mp->id)) { Buffer Overflow: diff --git a/lib/tnef-types.h b/lib/tnef-types.h index 7b6ad01..2a9709a 100644 --- a/lib/tnef-types.h +++ b/lib/tnef-types.h @@ -103,7 +103,7 @@ typedef struct { } TNEFMemInfo; typedef struct { - char version[10]; + char version[16]; variableLength from; variableLength subject; dtr dateSent; Workarounds ----------- Update to version 1.9.1 as released on https://github.com/yeraze/ytnef About X41 D-Sec GmbH -------------------- X41 D-Sec is a provider of application security services. We focus on application code reviews, design review and security testing. X41 D-Sec GmbH was founded in 2015 by Markus Vervier. We support customers in various industries such as finance, software development and public institutions. Timeline -------- 2017-02-10 Issues found 2016-02-12 Vendor contacted 2016-02-12 Vendor replied 2016-02-12 CVE ID requested 2016-02-13 Pull request for patch send as per vendor request 2016-02-13 Issue 9 / Directory Traversal reported 2016-02-14 Issues fixed, 1.9.1 released 2016-02-15 Advisory release -- X41 D-SEC GmbH, Dennewartstr. 25-27, D-52068 Aachen T: +49 241 9809418-0, Fax: -9 Unternehmenssitz: Aachen, Amtsgericht Aachen: HRB19989 GeschA$?ftsfA1/4hrer: Markus Vervier