标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-2938]   作者: 大猪 发表于: [2021-09-30]

本文共 [726] 位读者顶过

Windows Installer File Read 0day

[出自:jiwo.org]

Days ago, as usual I was reading some google project zero bugs. Then I found this one by James Forshaw about an EoP in dos device when a privileged process impersonate the user to load libraries. You can read the article here , My only problem was the PoC file as it seems look like james submitted 2 attachment to MSRC, the first one was with the actual PoC compiled and a dll, the second attachment seems to be password protected


And after some research trying to find the original PoC source code, I didn't found something useful so the only way to answer my questions is to reverse the actual PoC.

I really had some questions like, how did he managed the override the original link ? how did he get the login session \Sessions\0\DosDevices\X-Y <- how did he manage to get those numbers ?

Nothing special the dll will just call "RevertToSelf()" and then create notepad as a child process.

But for the actual PoC, some ops are done. I will only cover the code which has impact on our research area.

The PoC will first check the current OS architecture if it match x86 it will continue otherwise it will exit. I still don't know why did he do that but maybe to get ride off the annoying Wow64 redirections.

And after doing some reverse I finally answered my question, in order to get the current DosDevice path is to call GetTokenInformation

Then simply it will redirect the dos device symlink to the PoC's current directory by calling NtCreateSymbolicLinkObject, of course it make sure to recreate C:\Windows\System32 and place the dll described previously to system32 with the name PrintFilterPipelinePrxy.dll, after that the PoC will simply call "OpenPrinterW" "StartDocPrinterW" "EndDocPrinter" then the dll will be loaded as the spooler service. Microsoft has released the advisory for the bug as CVE-2015-1644

 

After taking a look on how Microsoft patched the bug, Microsoft implemented a mitigation to make sure that the dll load behaviour won't be redirected because of a DosDevice link, by using the OBJ_IGNORE_IMPERSONATED_DEVICEMAP. But any other file system operation will follow the link if it’s not using the flag described above.

The following Diagram will explain how things are done

Quite easy, but is it exploitable ? Well yes but actually no. In some rare cases the CreateFileW redirection might be useful. For now I just wanna fix one problem, I didn't like how the PoC call GetTokenInformation to get the current process Dos Device so I've done some research and got some good result.


You won't need to create the actual DosDevice link, overriding C:\ will do the job for the current user.

I was firstly inspired by sandbox escaper arbitrary file read PoC, which was dropped as a 0day vulnerability 2018. The bug existed in MsiAdvertiseProduct function, calling it will trigger a file copy from windows installer service running as SYSTEM privileges.

In this vulnerability I will be attacking the MsiInstallProduct which takes two arguments. 


The first one is szPackagePath which can be either an URL or a local file. The second parameter is szCommandLine.

After calling the function, I had the following output from process monitor

Phase 1: Windows installer service will impersonate the user and call OpenAndValidateMsiStorageRec which will first check if the package valid.

Phase 2: Windows installer service will reverse to itself and create a new file in C:\Windows\Installer\*.msi

Phase 3: It will make sure that the opened file match the expected file to be opened by calling GetFinalPathNameByHandleW if it match the file will be copied if it doesn’t the installer service will impersonate the user and try to copy the file.

The flaw exist exactly in msi.dll!CopyTempDatabase() when it call   CElevate::CElevate((CElevate *)&X, 1); to elevate privileges instead of staying in impersonation mode

There’s some checks in CopyTempDatabase such as CMsiFileCopy::VerifySource which check the source if it valid for for copy or not but it can be defeated if the user impersonation is done incorrectly.

Since the package sanitization will run while impersonating the user, we can redirect it with the trick mentioned above to a valid package which will trick OpenAndValidateMsiStorage and mark it as a valid package. Then the installer will check if the target file is the one expected to be opened in our case yes it is so it will proceed copying the file to C:\Windodws\Installer\*.msi

I succeeded implementing the exploit but I had one more issue, when the file is copied to C:\Windows\installer it’s probably not the only file there so fetching the newly created file is like a programming quiz, I took a while to see my options, the first one was ReadDirectoryChangesW which wait and fetch any newly created file, this sounds great but wasn’t useful. Since windows installer service tamper with certain parameters of the directory and remove the newly created MSI package as soon as it’s written. The second option was to use FindFirstFileW, FindNextFileW which has solved a bit of the problem, the technique I used here is to find newest file created and pick it as the our target, for some unknow reasons the technique failed and always pick the wrong file. So I moved away to another technique (and it was my last hope), This snippet of code will explain the process of finding the newly created file

We will first begin by deprecating “C:\” path and we will use the windows GUI path so we won’t issues with redirection, to retrieve the GUI path of drive you can use GetVolumeNameForVolumeMountPoint, then it will be used primary in the next api calls. Next our PoC will search \Windows\Installer\*.msi and will store it in an array “first_srch[10000]” and then you might notice there’s two calls of FindFirstChangeNotification and according to Microsoft documentation

“Creates a change notification handle and sets up initial change notification filter conditions. A wait on a notification handle succeeds when a change matching the filter conditions occurs in the specified directory or subtree. The function does not report changes to the specified directory itself. “

The PoC will set 2 events, one for the file creation and the second one for file write, When the first event trigger the PoC will restart the search of MSI files and will store to an array, the PoC will take those arrays and compare every file name if there’s something that doesn’t match at certain index then it’s the newly created file. After that we will just wait the second event to trigger then simply copy our file.

How exploitable a windows read-file ?

When windows crash it automatically generate a windows kernel memory dump in C:\Windows\memory.dmp and restrict it’s DACL to administrators only


You can read the file with the PoC :)


The PoC can be found here

[Update] : Fixed as CVE-2021-28437

评论

暂无
发表评论
 返回顶部 
热度(726)
 关注微信