360-CERT [三六零CERT](javascript:void(0)???? 昨天

0x00 漏洞詳情
說起dll劫持,可能很多人還以為這是一種非常雞肋的漏洞。不過我有關注到一些安全研究者披露過一些比較特殊的dll劫持的場景能夠導緻LPE甚至RCE。前一段時間我無意中發現了cisco webex teams中的dll加載機制存在漏洞可以通過dll劫持實作本地提權,并且據我所知沒有人提到過這種dll劫持的場景。
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-webex-teams-dll-drsnH5AN
安裝好cisco webex teams之後我發現它被安裝到
C:\Users\username\AppData\Local\CiscoSpark,我決定看一眼日志current_log.txt。
看起來有幾個dll第一次沒有加載成功,第二次才加載成功的。這很奇怪,
CiscoCollabHost.exe想從dependencies目錄中加載這些dll,error code 126意味着"The specified module could not be found",但是dependencies目錄和CiscoCollabHost.exe是在同一個目錄下的,并且dependencies目錄裡面也有這些dll。是以一定是哪裡出了問題…
直到我在IDA中找到spark-windows-media.dll中對應的代碼,又花了一些時間,我才意識這是怎麼回事。
在AddDllDirectory的文檔中微軟說參數應該是"An absolute path to the directory to add to the search path"。不過微軟并沒有說不能用相對路徑,也沒有說如果你用了相對路徑會發生什麼。更坑爹的是如果你像這裡一樣用了L"\dependencies"這樣的相對路徑,實際上windows會把它當成"C:\dependencies"!
我們可以自己寫一段代碼試一試:
PCWSTR pcwstr = L"\\dependencies";
if(!AddDllDirectory(pcwstr))
{
std::cout << "failed!\n";
}
LoadLibraryExW(L"test.dll", 0, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
std::cout << "Hello World!\n";
編譯出poc.exe,然後把poc.exe放到C:\example\poc.exe,
如果C:\dependencies\test.dll和C:\example\dependencies\test.dll同時存在,被加載的會是C:\dependencies\test.dll。
是以這裡利用這個漏洞就很簡單了,把wmeclient.dll放到C:\dependencies\wmeclient.dll,受害者打開cisco webex teams成功登入之後這個wmeclient.dll就會被cisco webex teams加載執行。直接将PE檔案寫到C槽根目錄是需要管理者權限的,但是在C槽根目錄建立一個目錄然後把你的PE檔案寫到這個目錄是不需要管理者權限的。
考慮另外一種exe和加載的dll不在同一個路徑的情況,如果C:\abc\def\poc.exe想要加載C:\abc\lib\test.dll,可不可以寫成LoadLibraryW(L"…\lib\test.dll")呢?這也是會導緻漏洞的,同樣windows會把"…\lib\test.dll"直接當成"C:\lib\test.dll"。我在另外某個知名廠商的産品中發現了這樣的代碼,我已經報告給了廠商,還在等廠商給我答複。我可能會在90天的期限或者廠商釋出安全公告之後補充更多細節。
不僅僅是加載dll相關的路徑windows是這麼處理的,像CreateProcess這樣的函數如果給它一個相對路徑也可能導緻漏洞。因為有些廠商的産品有windows版也有linux版,開發者可能會将這兩個平台的代碼混在一起,比如如果你寫出了這樣的代碼:
TCHAR szCmdLine[] = {TEXT("\\bin\\whoami")};
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
PROCESS_INFORMATION pi;
CreateProcess(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
windows會加上C:\和.exe,也就是說把whoami.exe放到C:\bin\whoami.exe那麼它就會被執行。我在cisco DCNM中發現了類似于這樣的代碼,它們告訴我這個問題隻在server 2019上存在而server 2019并不是DCNM預設支援的環境,是以cisco将我報告的這個問題當成了bug處理:
https://bst.cloudapps.cisco.com/bugsearch/bug/CSCvv65124
我也向MSRC報告過我的發現,不過MSRC說這是default behavior。我覺得出現這些問題主要的鍋還是微軟。
漏洞産生和發現的過程都非常具有戲劇性:如果dll加載失敗的時候開發者認真調試檢查就能避免這樣的漏洞(也正因為如此這種dll劫持的場景一般不會發生);如果不是我看了一眼程式的日志也不會有接下來這一系列有趣的發現。我還沒有看到有人提過這些并且很有可能還有類似的沒有被人發現的漏洞,同時也要提醒windows平台的開發者現在windows系統加載dll的機制仍不完善,注意确認自己的dll被正确加載。
0x01 時間線
2020-06-30 發現漏洞并報告給cisco PSIRT
2020-07-01 cisco PSIRT配置設定了PSIRT-0447917012
2020-07-10 cisco PSIRT沒有能夠成功複現,我提供了更多細節,強調隻有使用者成功登入之後才能觸發漏洞
2020-07-15 cisco PSIRT确認
2020-08-05 cisco PSIRT告知漏洞會在8月27日釋出的新版本中修複,9月2日釋出安全公告