Affected Versions

微软表明的影响版本
Microsoft Visual Studio 2017 version 15.9 (includes 15.0 - 15.8) < 15.9.59
Microsoft Visual Studio 2022 version 17.2 < 17.2.23
Microsoft Visual Studio 2019 version 16.11 (includes 16.0 - 16.10) < 16.11.33
Microsoft Visual Studio 2022 version 17.4 < 17.4.15
Microsoft Visual Studio 2022 version 17.6 < 17.6.11
Microsoft Visual Studio 2015 Update 3 < 14.0.27560.00

实测版本VS2022 17.7.4也可以,具体原理参考cve-2024-20656,分析的很详细了

procmon分析

vs调试一个文件看看StandardCollector.Service.exe过程,可以看到该文件是使用APIDELETE_ON_CLOSE中的标志创建的CreateFile,并且不共享对其他进程的任何访问权限。简而言之,这将阻止其他进程打开该文件的句柄,并且一旦句柄关闭,文件将被删除。 QQ_1728045377180.png

结束调试,可以看到将创建一个新文件夹,该文件夹使用相同的 GUID。但前面加上字符串Report。在我们的例子中,它看起来像这样C:\Windows\Temp\Report.76914557-4A42-4586-B0D9-C8904F9BFEFF。许多文件操作都在此文件夹中执行,包括文件移动、删除和 dacl 重置。 QQ_1728045435055.png

利用VSDiagnostics,开启会话,跟正常情况一样,会创建.scratch目录 image.png

结束会话,可以发现跟visual studio的差别是,可以看到VSDiagnostics使用的是目录输出,新创建了一个目录,然后在下面创建了Report.xxxx.diagsession文件,最后移动到父文件夹中去。仔细看可以发现在SetRenameInformationFile之后才调用SetSecutityFile重置DACl。 image.png

可以看到修复之后的版本执行同样操作时,DACL重置是在受限目录内执行的。 image.png

实现

首先创建了两个文件夹,打开第一个文件夹 QQ_1728356509448.png

在DoMain中,主要做了这几件事。

  • 创建从exploit1 == exploit2的 junction
  • 调用watch函数,其中主要创建start线程。start函数通过VSDiagnostics start sessionid /scratchLocation:file开始一个会话。同时监测exploit2目录下是否创建了.scratch结尾的文件,如果存在则获取文件名中的uuid,创建Global\\GLOBALROOT\\RPC Control\\Report.{uuid}.diagsession ====> C:\\Programdata的符号链接。
  • 创建Trigger线程,Trigger主要通过调用VSDiagnostics stop sessionid /output:file来停止会话从而创建report.{uuid}.diagession文件,
  • 监测exploit2文件夹中有没有发生文件创建删除等变化,如果存在,则切换挂载点,创建符号链接从 exploit1 = \RPC Control

QQ_1728560375850.png

接着替换一下target,设置为C:\\Programdata\\Microsoft,调用DoMain重复上述过程。 image.png

观察procmon会发现,SetSecutityFile的时候,由于设置了符号链接会把C:\\Programdata\\Microsoft下的文件DACL都进行重置。

image.png

最终就是利用VS默认的安装程序提权,个人感觉似乎不需要先链接到C:\Programdata,两次都会对MofCompiler.exe进行重置DACL。 image.png