联想电脑预装软件Lenovo Vantage的提权漏洞
被广泛安装在联想设备中的Lenovo Vantage软件受到了一个权限提升漏洞的影响。
Vantage自2016年发布以来,就已正式取代了联想解决方案中心(LSC)成为联想推荐的设备平台管理和系统更新工具。而到了2018年11月,LSC结束了使命,你可能还记得美国去年报告的LSC权限升级漏洞。
问题的核心在于一个目录遍历漏洞,它可以通过操作应用和插件的名字,使得由普通帐户控制的任意可执行文件或DLL在不安全的情况下被执行。
如果你的设备上运行了联想Vantage软件,那么建议你升级到最新版本,目前漏洞已被分配编号CVE-2020-8319和CVE-2020-8324。
演示地址:https://youtu.be/2NiDRtjwYts
CVE-2020-8319和CVE-2020-8324
联想Vantage依赖于一个名为System Interface Foundation
的服务。该服务会通过一个复杂的插件系统来执行联想所指定的各种动作。而这些插件可在计算机上执行任何操作,从执行系统更新到读取电池电量,这通常和Vantage软件中的功能相对应。
每个插件在其安装目录中都有一个已签名的PackageManifest.xml
文件,其中描述插件是应该在用户权限下运行还是以SYSTEM权限运行。而在我的测试笔记本上,似乎有5个插件可以以SYSTEM权限运行,其中一个是LenvoAppScenarioSystem
插件。
Plugin Manifest文件:
The Contract
如前所述,每个插件都提供了与底层服务的contract,这会通过一个UMDF驱动接口的IPC机制向任何用户开放。每个插件都在IPC接口上公开的contract中提供了许多功能。除了插件contract外,服务本身也有自己的内部contract,用于执行更新和其他软件的维护任务,而内部contract中提供的相关命令是Install-PendingUpdates
。
通常来说,当从Lenovo下载新的插件时,最终会被放置在%PROGRAMDATA%\Lenovo\ImController\Plugins
文件夹中,名字为插件名字加上下划线。
例如,我们得到了LenvoAppScenarioSystem
插件,则预更新文件夹将是%PROGRAMDATA%\Lenovo\ImController\Plugins\LenovoAppScenarioSystem_
。
一旦更新文件夹准备好了,每2分钟或大约180秒就会触发一个插件更新计时器,覆盖PROGRAMDATA%\Lenovo\ImController\Plugins\LenovoAppScenarioSystem
文件夹中的文件。
Good things come in twos
那么,为什么选择使用LenovoAppScenarioPluginSystem
插件进行攻击呢?第一个原因是联想Vantage插件可以在用户或系统帐户下运行,而LenovoAppScenarioPluginSystem
插件以SYSTEM权限运行。
第二个原因是签名检查。联想会拒绝执行非联想签名插件。假如这里存在一个路径遍历漏洞,可对相关插件进行恶意替换的话,签名就会影响加载。
那么,我们如何利用LenovoAppScenarioPluginSystem
?先使用UDMF驱动程序接口向命令broker发送一个精心设计的请求。
<InstallPendingRequest>
<PackageList>
<Package name=""..\..\..\LenovoAppScenarioPluginSystem""/>
</PackageList>
</InstallPendingRequest>
由于未检查包名属性,ImController
服务现在在%PROGRAMDATA%\Lenovo\LenovoAppScenarioPluginSystem_
下搜索。你可能已经猜到,普通用户是可以写入这个位置的。然后就会将恶意文件夹复制到PROGRAMDATA%\Lenovo\ImController\Plugins\LenovoAppScenarioSystem_
中,准备好启动计时器,将插件放置到最终位置。
绕过
以上已有普通帐户替换插件文件的方法,现在我们需要一种方法来绕过签名检查。在插件broker服务加载任何插件DLL之前,都会检查DLL是否由联想证书签名。如果DLL没有有效的联想证书签名,broker将拒绝加载插件。
但LenovoAppScenarioPluginSystem插件有一些不同,它依赖于其他DLL,特别是一个名为TouchScreenContronlDLL.dll
的本地DLL文件。经过分析,我们发现会通过DllImport属性导入本地DLL。
namespace Lenovo.Modern.Plugins.SmartSetting.AppScenarioSettingPluginSystem
{
public class DependDll
{
public static bool GetTouchScreenStatus()
{
int num = 0;
try
{
num = DependDll.GetTouchStatus();
}
catch
{
}
return num == 2;
}
public static int SetTouchScreenStatus(bool isOpen)
{
if (isOpen)
{
return DependDll.TouchScreenContronl(1);
}
return DependDll.TouchScreenContronl(0);
}
[DllImport("TouchScreenContronlDLL.dll")]
public static extern int TouchScreenContronl(int ops);
[DllImport("TouchScreenContronlDLL.dll")]
public static extern int GetTouchStatus();
}
}
不幸的是,由于联想开发人员的疏忽,联想插件eco系统中的信任链被打破了。由于插件本身加载的DLL不会进行证书检查,所以我们现在有了一个有效的攻击链。在进行自定义插件更新之前,用恶意DLL替换TouchScreenContronlDLL.dll
,从而使我们能够获得SYSTEM权限。
后续
最后一步是确定如何在使用LenovoAppScenarioPluginSystem
时调用导出的GetTouchStatus
函数。我们发现每个插件都可以将自己的contract暴露给contract broker,下面是插件所暴露的contract。
LenovoAppScenarioPluginSystem
暴露的contract:
现在已经知道了contract,一个执行Get-TouchScreenState
命令的broker请求最终将加载受我们控制的TouchScreenContronlDLL.dll
。
现在我们已经有了所有需要的信息,配合C#代码和meterperter,在等待更新计时器触发大约2分钟后,我们得到了SYSTEM权限的shell。
修复
联想于2020年3月16日发布了 System Interface Foundation的更新。现在联想Vantage在自动更新时会检查包名是否有效,以及加载的DLL是否被签名。
2020年1月16日——将漏洞详细信息发送给Lenovo PSIRT
2020年1月17日——联想开发团队确认漏洞存在
2020年3月16日——联想发布了System Interface Foundation更新,修复了两个漏洞
2020年3月19日——确认修复有效
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://www.pentestpartners.com/security-blog/privesc-in-lenovo-vantage-two-minutes-later/
最新评论