From: Seonah Moon Date: Wed, 22 Jun 2016 05:43:54 +0000 (+0900) Subject: [CVE-2016-4802] Windows DLL hijacking X-Git-Tag: accepted/tizen/common/20160627.191214^0 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fupstream%2Fcurl.git;a=commitdiff_plain;h=ede3440ea72f7455b2a43cd6fda32cdc777b8a41 [CVE-2016-4802] Windows DLL hijacking Change-Id: I52bc7cb34ac493c20588876294d59039af03cbe1 Signed-off-by: Seonah Moon --- diff --git a/lib/Makefile.in b/lib/Makefile.in index 2c21bfa..377e14f 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -685,7 +685,7 @@ LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \ curl_ntlm_core.c curl_ntlm_msgs.c curl_sasl.c curl_multibyte.c \ hostcheck.c conncache.c pipeline.c dotdot.c x509asn1.c \ http2.c curl_sasl_sspi.c smb.c curl_sasl_gssapi.c curl_endian.c \ - curl_des.c + curl_des.c system_win32.c LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \ @@ -704,7 +704,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \ curl_ntlm_msgs.h curl_sasl.h curl_multibyte.h hostcheck.h \ conncache.h curl_setup_once.h multihandle.h setup-vms.h pipeline.h \ dotdot.h x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \ - curl_printf.h + curl_printf.h system_win32.h LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VTLS_CFILES) diff --git a/lib/Makefile.vc6 b/lib/Makefile.vc6 index ba903c9..f140554 100644 --- a/lib/Makefile.vc6 +++ b/lib/Makefile.vc6 @@ -620,6 +620,7 @@ X_OBJS= \ $(DIROBJ)\speedcheck.obj \ $(DIROBJ)\splay.obj \ $(DIROBJ)\ssh.obj \ + $(DIROBJ)\system_win32.obj \ $(DIROBJ)\vtls.obj \ $(DIROBJ)\openssl.obj \ $(DIROBJ)\strdup.obj \ diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c index 04eac48..54bbef6 100644 --- a/lib/curl_sspi.c +++ b/lib/curl_sspi.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -27,6 +27,7 @@ #include #include "curl_sspi.h" #include "curl_multibyte.h" +#include "system_win32.h" #include "warnless.h" /* The last #include files should be: */ @@ -117,9 +118,9 @@ CURLcode Curl_sspi_global_init(void) /* Load SSPI dll into the address space of the calling process */ if(securityDll) - s_hSecDll = LoadLibrary(TEXT("security.dll")); + s_hSecDll = Curl_load_library(TEXT("security.dll")); else - s_hSecDll = LoadLibrary(TEXT("secur32.dll")); + s_hSecDll = Curl_load_library(TEXT("secur32.dll")); if(!s_hSecDll) return CURLE_FAILED_INIT; diff --git a/lib/system_win32.c b/lib/system_win32.c new file mode 100644 index 0000000..f20bcb7 --- /dev/null +++ b/lib/system_win32.c @@ -0,0 +1,131 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2016, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(WIN32) + +#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ + defined(USE_WINSOCK)) + +#include +#include "system_win32.h" + +/* The last #include files should be: */ +#include "curl_memory.h" +#include "memdebug.h" + +#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) +#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 +#endif + +#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) +#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +#endif + +/* We use our own typedef here since some headers might lack these */ +typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); + +/* See function definitions in winbase.h */ +#ifdef UNICODE +# ifdef _WIN32_WCE +# define LOADLIBARYEX L"LoadLibraryExW" +# else +# define LOADLIBARYEX "LoadLibraryExW" +# endif +#else +# define LOADLIBARYEX "LoadLibraryExA" +#endif + +/* + * Curl_load_library() + * + * This is used to dynamically load DLLs using the most secure method available + * for the version of Windows that we are running on. + * + * Parameters: + * + * filename [in] - The filename or full path of the DLL to load. If only the + * filename is passed then the DLL will be loaded from the + * Windows system directory. + * + * Returns the handle of the module on success; otherwise NULL. + */ +HMODULE Curl_load_library(LPCTSTR filename) +{ + HMODULE hModule = NULL; + LOADLIBRARYEX_FN pLoadLibraryEx = NULL; + + /* Get a handle to kernel32 so we can access it's functions at runtime */ + HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); + if(!hKernel32) + return NULL; + + /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 + and above */ + pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX); + + /* Detect if there's already a path in the filename and load the library if + there is. Note: Both back slashes and forward slashes have been supported + since the earlier days of DOS at an API level although they are not + supported by command prompt */ + if(_tcspbrk(filename, TEXT("\\/"))) + hModule = pLoadLibraryEx ? + pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : + LoadLibrary(filename); + /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only + supported on Windows Vista, Windows Server 2008, Windows 7 and Windows + Server 2008 R2 with this patch or natively on Windows 8 and above */ + else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) { + /* Load the DLL from the Windows system directory */ + hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + } + else { + /* Attempt to get the Windows system path */ + UINT systemdirlen = GetSystemDirectory(NULL, 0); + if(systemdirlen) { + /* Allocate space for the full DLL path (Room for the null terminator + is included in systemdirlen) */ + size_t filenamelen = _tcslen(filename); + TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)); + if(path && GetSystemDirectory(path, systemdirlen)) { + /* Calculate the full DLL path */ + _tcscpy(path + _tcslen(path), TEXT("\\")); + _tcscpy(path + _tcslen(path), filename); + + /* Load the DLL from the Windows system directory */ + hModule = pLoadLibraryEx ? + pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : + LoadLibrary(path); + + free(path); + } + } + } + + return hModule; +} + +#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */ + +#endif /* WIN32 */ + diff --git a/lib/system_win32.h b/lib/system_win32.h new file mode 100644 index 0000000..dec1889 --- /dev/null +++ b/lib/system_win32.h @@ -0,0 +1,39 @@ +#ifndef HEADER_CURL_SYSTEM_WIN32_H +#define HEADER_CURL_SYSTEM_WIN32_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2016, Steve Holme, . + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "curl_setup.h" + +#if defined(WIN32) + +#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ + defined(USE_WINSOCK)) + +/* This is used to dynamically load DLLs */ +HMODULE Curl_load_library(LPCTSTR filename); + +#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */ + +#endif /* WIN32 */ + +#endif /* HEADER_CURL_SYSTEM_WIN32_H */ diff --git a/lib/telnet.c b/lib/telnet.c index 4ebc492..c3a19fe 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -52,6 +52,7 @@ #include "connect.h" #include "progress.h" #include "curl_printf.h" +#include "system_win32.h" #define TELOPTS #define TELCMDS @@ -1334,7 +1335,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) /* OK, so we have WinSock 2.0. We need to dynamically */ /* load ws2_32.dll and get the function pointers we need. */ - wsock2 = LoadLibrary(TEXT("WS2_32.DLL")); + wsock2 = Curl_load_library(TEXT("WS2_32.DLL")); if(wsock2 == NULL) { failf(data, "failed to load WS2_32.DLL (%d)", ERRNO); return CURLE_FAILED_INIT; diff --git a/packages/Symbian/group/libcurl.mmp b/packages/Symbian/group/libcurl.mmp index 545cdee..cf1a0ec 100644 --- a/packages/Symbian/group/libcurl.mmp +++ b/packages/Symbian/group/libcurl.mmp @@ -40,7 +40,7 @@ SOURCE \ curl_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_ntlm_msgs.c \ curl_sasl.c vtls/schannel.c curl_multibyte.c vtls/darwinssl.c \ conncache.c curl_sasl_sspi.c smb.c curl_sasl_gssapi.c \ - curl_endian.c curl_des.c + curl_endian.c curl_des.c system_win32.c USERINCLUDE ../../../lib ../../../include/curl #ifdef ENABLE_SSL