CISecurity/OVALRepo

[Windows] Possible issues when using Windows\WinSXS* subfolders to determine Library-Versions

Memnarch opened this issue · 11 comments

A fair number of tests/objects uses the Windows\WinSXS subfolders (Windows SideBySide) to get a list of a specific dll and test those against a specific version.

As an example:
oval:org.cisecurity:tst:9680
"gdiplus.dll version is less than 10.0.14393.2791"

The issue here is, that the WinSXS subfolders keep copies of older files. On the system in question (Windows Server 2016) KB4487026 is installed which is supposed to fix CVE-2019-0662.

GdiPlus.dll in System32 and SysWOW have a higher buildversion afterwards and are considered "fixed". However due to the WinSXS folders, there are libraries with buildversions of 0 or lower than the current one. Which means this test will always hit.

Given the nature of the WinSXS folders, i'm not sure it's convenient to search them, as the default active libraries reside outside of them.

Hi @Memnarch, yes this is a tricky issue.

I believe that even if the default/active version of a specific library has been updated, old/vulnerable versions residing in WinSXS may be used if an application specifically requires that old/vulnerable version. WinSXS (Windows Side-by-Side) allows multiple versions of the same library to run "side-by-side". Microsoft provides tools to clean up the WinSXS folder, removing old versions, but I am not sure how "smart" these tools are--i.e. will the tool remove an old version that is still required by an older application?

Questions:

  1. Can older/vulnerable files in WinSXS really be used by applications on a system even if a newer version of the library exists?
  2. If so, should we limit our testing to the default/active version of a package or should we test against all potentially active versions of the file on the system?

-David

mh found this thread on MSDN:
Delete DLL files from %WinDir%\WinSxS

So it seems these older versions can run? But windows allows removing update backups(which is one primary use of all those copies).
Rigorous cleanup of WinSxS folder?!

However it still seems strange. You install a security update and vulnerable copies are left on the system which Might run? Maybe that's a seperate question to ask on the msdn forum.

@Memnarch, thanks for researching this. I'd love an authoritative answer from MS! Please let us know if you get one. -David

Ok so far the response i got was:

Hi,

According to my understanding, previous versions of dll files are used to rollback. It shouldn't be used by other application. At least to Microsoft files.

Best regards,

Yilia

Just noticed, that one of our applications has a module loaded from a WinSxS subfolder (msvcr80.dll).
It has loaded the most recent one, while older ones exists locally in other WinSxS folders. So i would assume, not all files exist outside of WinSxS(therefore requireing to search this structure). But as soon as a newer one exists, the olders ones can be ignored in results. Therefore a vulnerabilitytest might need to have all DLLs satisfy a test against a vulnerable version to actually be vulnerable. as soon as one is higher than the vulnerable, the vulnerability seems to be fixed for the system.

So while we can't skip the WinSxS subfolders, some changes seem to be possible, to avoid false positives.

But this is open for debate. We can accept false positives, if we want to force people to cleanup the update history, which removes the rollback option for previously installed updates.

@Memnarch, thanks for the update and continued review. The implementation of Windows Component Based servicing is pretty complex and opaque (not pubicly documented). My understanding is that the WixSXS supports both side-by-side assembly executions (as Yilla referred to) and rollback.

I think that in an ideal world, CVE definitions would:

A) exclude/ignore files under WinSXS that are present to support rollback but cannot be used in the current system state (i.e. are not a part of any currently active/accessible component versions)
B) include/assess files under WinSXS that are the current/default version
C) include/assess files under WinSXS that can be run side-by-side with the current version when a specific non-default component version is required by an application

The issue is that I don't know how to reliably differentiate between A and C.

The About Side-by-Side Assemblies article includes this example:

...both Comctl32.DLL version 6.0 and Comctl32.DLL version 5.0 are in the side-by-side assembly cache and available to applications. When an application calls to load the DLL, the side-by-side manager determines whether the application has a version dependence described in a manifest. If there is no relevant manifest, the system loads the default version of the assembly. For Windows XP, version 5.0 of Comctl32.DLL is the system default. If the side-by-side manager finds a dependence on version 6.0 stated in a manifest, that version is loaded to run with the application.

Even from this simple example, we can see that the most recent version on the system (6.0) may not be the default version!

One might hope that there was a clear, consistent versioning scheme that allowed us to determine active versions based on version numbers. For example, perhaps the major versions are all available when on the system and minor version updates override earlier minor versions.

In practice, however, I think that component-based servicing is much more complex. Files have versions. Components (managed groupings of files) have their own versions. And, the state (active/inactive) seems to be held in a registry key with opaque/hashed IDs. I haven't been able to find an API or other method for determining which components are currently active.

-David

Hello, after many hours of discussions with Microsoft Engineers, they provided some info on servicing changes starting with Windows Server 2008. I think the main point in this article is, only the higher number of a component is used by the system. I think this explains why MS doesn't consider a system with the latest patch applied vulnerable, even if older files are available in the WinSxS dir.

When we update a particular binary we release a new version of the whole component, and that new version is stored alongside the original one in the component store. The higher version of the component is projected onto the system, but the older version in the store isn’t touched.

https://docs.microsoft.com/en-us/archive/blogs/askcore/what-is-the-winsxs-directory-in-windows-2008-and-windows-vista-and-why-is-it-so-large

It looks like there are a number of new checks that also consider files in the WinSXS directory vulnerable. Given the changes to the the Windows OS from XP/2003 to Vista/2008 +, I think this may need to be changed.
CVE-2019-0618
CVE-2019-0662
CVE-2019-0903
CVE-2019-1102
CVE-2020-0881
CVE-2020-0883
CVE-2020-0964

I'd suggest to skip/exclude WinSxS. The Projected file is where it's needed (i.e. System32) so looking into WinSxS seems irrelevant.

I would love to skip WinSxS. It's challenging to assess. But I remain concerned about false negatives resulting from ignoring vulnerable files under WinSxS.

My understanding is that applications with version-specific dependencies can still use components under WinSxS even if they are not projected on the system or the latest version.

And, some files appear to be used but not projected on the filesystem.