Title: Microsoft Visual C++ 8.0 standard library time functions invalid assertion DoS (Problem 3000). Product: Visual Studio 2005 Vendor: Microsoft Vulnerability class: Denial of Service Remote: application dependant, remote vector is possible CVE: CVE-2007-0842 Author: 3APA3A, http://SecurityVulns.com/ Advisory URL: http://SecurityVulns.com/advisories/year3000.asp Intro: Since Microsoft Visual Studio 5.0, Visual C++ compiler defaults time_t type to 64 bit integer and time functions to their 64-bit variants. Vulnerability: 64-bit versions of time functions: localtime() localtime_s() gmtime() gmtime_s() ctime() ctime_s() wctime() wctime_s() fstat() and may be others incorrectly behave for a time_t argument larger than or equal to _MAX__TIME64_T (representing January, 1 3000 00:00:00). According to MSDN documentation, time functions must indicate error by returning NULL pointer or EINVAL (depending on function class) and must not invoke any invalid parameter handler. Instead, time function calls invalid parameter assert()-like macro, terminating calling application and creating Denial of Service condition for calling application. An example is within localtime_s function (loctim64.c): /* * Check for illegal __time64_t value */ _VALIDATE_RETURN_ERRCODE_NOEXC( (*ptime >= 0), EINVAL); _VALIDATE_RETURN_ERRCODE( (*ptime <= _MAX__TIME64_T), EINVAL); Last string initiates assertion, it's invalid _VALIDATE_RETURN_ERRCODE_NOEXC must be used for both negative and oversized value. Valid code is: /* * Check for illegal __time64_t value */ _VALIDATE_RETURN_ERRCODE_NOEXC( (*ptime >= 0), EINVAL); _VALIDATE_RETURN_ERRCODE_NOEXC( (*ptime <= _MAX__TIME64_T), EINVAL); Both static and dynamic (MSVCR80.DLL) versions of C library are vulnerable. Who is vulnerable? Any application compiled with Microsoft Visual C++ 8.0 compiler with either static or dynamic libraries is vulnerable, if it uses one of named functions with user-controlled data. Possible attack vectors: 1. Network protocols and applications where time_t value is used and/or transmitted as 8-octets (64 bit) in seconds or milliseconds and can be behind January, 1, 3000. Example: different SQL databases. 2. Windows applications where time_t is result of conversion from FILETIME or SYSTEMTIME structures. E. g. GetFileTime/SetFileTime functions can be used to get/set NTFS file time to values behind January, 1, 3000. You can try to exploit different applications by using this very simple trick. This is also true for Java and JavaScript timestamps. 3. Application where date_t is calculated as a result from user input + some offset (e.g. timezone conversions for date December, 29 2999 23:01 GMT-01:00). An example: e-mail messages, HTTP requests, etc. Example of vulnerable application: /* D:\>cl localtime_s.c Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. localtime_s.c Microsoft (R) Incremental Linker Version 8.00.50727.42 Copyright (C) Microsoft Corporation. All rights reserved. /out:localtime_s.exe localtime_s.obj D:\>localtime_s.exe (Dr.Watson comes, expected result: "Invalid value") */ #include #include #include int main(){ struct tm tm; time_t t = 0x3a3a3a3a3a3a3a3a; if(localtime_s(&tm, &t) != 0) { printf("Invalid value\n"); } else { printf("OK\n"); } return 0; } Workarounds: Developer can use one if this workarounds: 1. Define _USE_32BIT_TIME_T to use 32-bit functions (not available on 64-bit platforms). 2. Explicitly check 'time' argument of named functions to be below _MAX__TIME64_T. It should be noted, that this workaround is not reliable, because it doesn't covers the vector where time_t is calculated as a result of time arithmetics. Exploitation: Test application to set file date to 27.09.14896 3touch.c is available from http://SecurityVulns.com/news/MICROSOFT/Time/Assert.html. Application compiled with MSVC 8.0, e.g. MSDN sample fstat.c, crashes on attempt to fstat() this file. It may also be used to get interesting results with "dir" command (shows "Invalid argument") if FILETIME is changed to 0x7FFFFF00, but it seems to be different issue. Vendor: 23.08.2006 Initial vendor notification through secure@microsoft.com 25.08.2006 Second vendor notification 25.08.2006 Initial vendor reply 30.08.2006 Vendor asks for additional details 31.08.2006 Additional details with example of crashing application are sent to vendor 12.09.2006 Additional details are sent again because of no response 11.10.2006 Vendor response: "We believe this is not a security vulnerability but in fact a deliberate security feature to mitigate problems with invalid data propagating through the system".