-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CVE-2020-8315] Unsafe dll loading in getpathp.c on Win7 #83582
Comments
On Win7, running Python in the terminal will attempt to load the "api-ms-win-core-path-l1-1-0.dll" from various paths outside of the Python directory and the C:\Windows\System32 directories. This behavior can be verified using Process Monitor (see attachment). This is happening due to direct calls to LoadLibraryW() in getpathp.c without any "LOAD_LIBRARY_SEARCH*" flags. In join(): Line 255 in c02b41b
and canonicalize(): Line 291 in c02b41b
For both cases, the methods they are trying to load from api-ms-win-core-path-l1-1-0.dll (PathCchCanonicalizeEx and PathCchCombineEx) were introduced in Win8. I tested on Win7 and Win10 and they differ in how they load these api-ms-win-* dll's and whether they appear in process monitor. In Win7, a CreateFile event appears in procmon, while in Win10 it seems like the OS is automatically loading the module from kernelbase.dll. Also in Win7 the loading of api-ms-win-core-path-l1-1-0.dll will fail while in Win10 it succeeds. However, in Win7 when it fails it results in the standard dll search strategy, which will eventually search outside of the secure directories such as the directories in the PATH env var: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order Each of the problematic methods in cpython have a pattern of attempting to load the dll, then falling back to an older version of the method. Thus in Win7, the dll fails to load and it falls back to the older version of the method. In Win10, the dll load succeeds and we use the new versions of the methods. I'm working on a fix to pass the LOAD_LIBRARY_SEARCH_DEFAULT_DIRS flag to limit to the dll search path scope. |
"api-ms-win-core-path-l1-1-0.dll" is not assigned in the API set schema (in ApiSetSchema.dll) in Windows 7. Since the name is neither in the list of known DLLs nor the list of assigned API sets, the loader searches for it in the normal way. (FYI, the number of API sets increased from 35 in Windows 7 up to 502 in Windows 8.1.)
I think this could use just LOAD_LIBRARY_SEARCH_SYSTEM32. I see no reason to try to load "api-ms-win-core-path-l1-1-0.dll" from the application directory or user directories. I'm adding 3.6-3.9 to the list of affected versions. In 3.9 it can use a static import instead (i.e. remove LoadLibraryaExW / GetProcAddress), since only Windows 8.1+ is supported. |
Agreed, we can just search System32 for this. Thanks for doing the patch! For future reference, and for anyone else reading this, we generally prefer unavoidable DLL hijacking bugs to come to the Python Security Response Team first (security@python.org). |
For clarity, I'm removing 3.9 from the affected versions. This version does not support Windows 7, and only Windows 7 is vulnerable to this DLL hijack. Also submitting the CVE request. |
I added 3.9 for the related issue to switch to using a static import, since Windows 7 isn't supported in 3.9. But I guess that should have been made a separate issue, or added to the omnibus issue bpo-32592. |
This is now assigned CVE-2020-8315 (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8315 https://nvd.nist.gov/vuln/detail/CVE-2020-8315) Thanks Anthony for the report! I included your name as the reporter, though I don't see it on any of the pages. |
I added https://python-security.readthedocs.io/vuln/unsafe-dll-load-windows-7.html to track fixes in all branches. |
As noted on the PR landing page, this PR has caused failures of 2 buildbots: https://buildbot.python.org/all/#builders/81/builds/272 https://buildbot.python.org/all/#builders/150/builds/227 (both are Windows 7) |
Both of those buildbots should be retired (or repurposed for versions of Python that still support Windows 7) :) |
The master branch should no longer get built on Windows 7 machines. The initial build succeeds, but running "_freeze_importlib[_d].exe" fails with STATUS_DLL_NOT_FOUND (0xC0000135, i.e. -1073741515) since "api-ms-win-core-path-l1-1-0.dll" (linked from pathcch.lib) is not a Windows 7 API set. |
Thanks, Victor! Python 2.7 and 3.5 are not vulnerable. The issue was added in 3.6 when I added support for installing Python into a long path name on up-to-date OS, which required dynamically loading an OS function. That dynamic load was the problem. |
Oh ok, I updated the page to reflect that. I also added 3.7 & 3.8 commits. |
No problem! Thanks Steve, Eryk, and Victor for jumping on this! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: