Jump to content

在軟件行業,可用性和安全性一直是個矛盾。許多第三方程序可以通過存儲用戶的憑據方便用戶使用。然而,事實證明,這種便利通常是以安全性性為代價的,從而導緻密碼被盜的風險。以這種方式收集的憑據可以在實際的網絡攻擊期間使用。

攻擊者如何擴展其訪問權限很明顯,憑據盜竊是很危險的。但是,有必要強調憑據盜竊可能產生的影響規模。

許多人傾向於在不同的程序中使用相同的密碼,並且很少更改他們的密碼。到了修改密碼的時候,許多人都遵循可預測的模式。

因此,當攻擊者可以從一個來源獲得密碼時,他們可以嘗試使用它來攻擊其他資源,包括一些更受保護的資源。因此,對於每個安全的程序A,用戶可以在不太安全的程序B 上使用相同的密碼或模式,這可能導致程序A 的安全性降低。

此外,如果發現有人在其他不太安全的地方使用他們的操作系統密碼,那麼攻擊者就會打開一個全新的可能性世界。

例如,假設某人X 對他的Windows 帳戶域和Linux FTP 文件服務器使用相同的密碼。在這種情況下,X用戶使用常用程序WinSCP在文件服務器上管理自己的文件。儘管WinSCP 建議不建議保存密碼,但是X用戶每週都會訪問這個文件服務器,所以他們更願意節省時間,保存密碼。

1.png

WinSCP 不建議保存密碼

正如我們稍後將演示的那樣,用戶的密碼可以很容易地從WinSCP存儲密碼的地方獲取。可以在X 的個人計算機上立足的攻擊者可以獲得他們的域帳戶密碼,只是因為它被不安全地保存了。最重要的是,密碼對於連接到文件服務器是有效的。該文件服務器可能包含攻擊者現在可以訪問的敏感信息文件。那樣,攻擊者可以使用像BloodHound 這樣的工具來估計他們可以在一個組織內傳播多遠。

以WinSCP為例進行具體分析WinSCP是常用的一種SFTP客戶端和FTP客戶端,用於在Windows本地計算機和遠程服務器之間通過FTP、FTPS、SCP和SFTP複製文件。

測試版本:5.19.6 (Build 12002 2202-02-22)

憑據存儲在哪裡?

WinSCP將加密後的用戶密碼存儲在如下所示的註冊表項下的一個名為Password 的值中。

加图1.png

如何恢復憑據?

WinSCP工具對用戶密碼的位數進行對稱數學運算。它獲取密碼的每個字節,計算0xFF(11111111)的補碼,然後用字節0xA3(10100011)對其進行異或運算。

加密過程包括找到補碼並執行一次異或運算。然後將密碼存儲在密碼註冊表值中。由於這些數學運算是對稱的,我們需要做的就是以相反的順序再次執行相同的兩個運算,以獲得原始值。

例如,讓我們以一個常用的密碼為例:Aa123456。 “1D3D6D6E6F68696A”密碼在WinSCP工具上的存儲方式如下。

在下圖中,我們看到了解密密碼的步驟:

2.png

解密存儲在WinSCP 中的密碼

密碼與主機名和用戶名一起保存。要從密碼註冊表值中獲取它,我們必須找到密碼開頭的索引。這個計算非常簡單,根據WinSCP版本,註冊表值的第一個或第三個字節是連接的用戶名、主機名和密碼的長度。起始索引是長度的下一個字節,其值乘以2。長度和起始索引都以相同的方式加密。

主機名和用戶名也保存在不同的註冊表值上,因此我們知道它們的長度和值。我們所做的就是從索引中解密密碼註冊表的值:開始索引+用戶名長度+主機名長度,我們就會得到我們的密碼。

3.png

連接的用戶名、主機名和密碼的位置

野外利用

我們已經看到在多個客戶環境中執行了以下腳本:

4.png

可疑的PowerShell編碼命令

-enc表示EncodedCommand,這意味著將使用一個base-64編碼的字符串作為命令。

在解碼的腳本中,我們可以看到嘗試解密WinSCP 密碼:

5.png

用於提取和解密WinSCP 密碼的PowerShell 腳本

6.png

Cortex XDR阻止了讀取存儲在WinSCP中的密碼的嘗試

以Git為例進行具體分析測試版本:2.35.1.windows.2。

憑據存儲在哪裡?

Git 允許同時使用密碼和個人訪問令牌(PAT)。

當用戶想通過保存他們的Git憑據來節省時間時,他們可以使用以下命令:

gitconfigcredential.helper'store'使用這個命令,Git將以純文本的形式無限期地將用戶的憑據保存在磁盤上。

可能包含密碼的文件:

加图2.png

Git 允許使用PAT 作為憑據,而不是傳統的密碼使用。這些令牌更加模塊化,因為可以創建任意數量的訪問令牌,每個令牌具有不同的權限和過期日期。

雖然可以以更模塊化和更細粒度的方式控制用戶的操作,每個操作都與特定的PAT 相關聯,但是擁有用戶PAT的任何人都可以查看用戶可以訪問的所有存儲庫。

這些標籤也以明文形式出現在上面提到的相同文件中。

如何恢復憑據?

任何閱讀這些文件的人都會以純文本形式看到用戶名、密碼或令牌以及相關的Git 存儲庫。

以RDCMan為例進行具體分析測試版本:2.83

RDCMan可以管理多個遠程桌面連接。它對於管理需要定期訪問計算機的服務器實驗室非常有用,比如自動簽入系統和數據中心。

憑據存儲在哪裡?

當用戶決定使用RDCMan 保存會話密碼時,默認配置文件將為%localappdata%\Microsoft\Remote Desktop Connection Manager\RDCMan.settings。

這個文件是一個XML文件,包含關於每個RDP連接的通用元數據。在這些數據中,有一個名為CredentialsProfiles的XML標籤引起了我們的注意。

我們可以看到,在這個標籤下,還有另一個名為CredentialsProfiles的標籤,其中還有credentialsProfile XML標籤,以及一個Password 標籤。

7.png

查看RDCMan.settings中的XML標籤

如何恢復憑據?

要檢索密碼,我們必須在使用RDCMan程序的用戶的上下文中執行命令。這是因為密碼是使用數據保護API (DATA Protection API, DPAPI)保存的,該API 可以分別使用CryptProtectData和CryptUnprotectData函數對任何類型的數據進行對稱加密和解密。

因此,為了獲得密碼,我們需要調用CryptUnprotectData函數。

通常,唯一可以解密數據的用戶是與加密數據的用戶具有相同登錄憑據的用戶。

儘管從RDCMan 收集憑據需要攻擊者採取比我們其他一些示例中所需的額外步驟,在相關用戶的上下文中運行軟件,但結果對攻擊者來說具有很大的價值。如果成功,攻擊者就有可能獲得該特定用戶連接到的所有計算機的所有用戶和密碼。

一旦攻擊者能夠在用戶的上下文中執行命令,為了收集憑據,剩下要做的就是:

打開RDCMan.settings 文件並檢查密碼XML 標籤;

使用base64 解碼標籤中的字符串;

使用解碼的密碼字符串調用CryptUnprotectData;

使用UTF-8(或其他相關格式)對結果進行解碼;

刪除不必要的空字符;

看看上面的例子,保存在文件中的密碼是:

AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA8/nnW5aFNUi0AKiTG4y9UQAAAAACAAAAAAAQZgAAAAEAACAAAADIjLLw0X4z9RDdWgPpqabLU7hTcJ1HVlFklpzX3eA14QAAAAAOgAAAAAIAACAAAAB01OvDCNCjaEhrq8J8hRm/SKyc ef7nR52ZkqcPLJqMsCAAAACg2htaeRsutDziS3FISeEAg3DsBpGxBGpPeWlUSVnXOkAAAAB5Tei9g5KWcVIhOKQ2cXxr5ONUOHMEEH5h3Lmp12mPlWaaZ6y8dGIVz8WnNKr4e73dhqNU8NyzI7RZBamS6DG6解密後的密碼是Aa123456。

8.png

從RDCMan中恢復密碼

以OpenVPN為例進行具體分析測試版本:2.5.029。

OpenVPN 是一個虛擬專用網絡系統,它實現了在路由或橋接配置和遠程訪問設施中創建安全的點對點連接的技術。

憑據存儲在哪裡?

OpenVPN 將用戶的密碼存儲在如下所示的註冊表項下的一個名為auth-data 的值中。

加图3.png

如何恢復憑據?

OpenVPN還使用了DPAPI機制,並附加了可選的熵參數(可以設置為NULL)。

當在加密階段使用可選的熵DATA_BLOB結構時,必須在解密階段使用相同的DATA_BLOB結構。

在OpenVPN的情況下,熵保存在一個名為熵的註冊表值中。熵註冊值也存儲在如下路徑。

加图4.png

因此,使用來自auth-data 和熵(來自熵)的密碼調用CryptUnprotectData 將為我們提供會話密碼。

熵註冊表值包含一個額外的字節00,所以我們只需要省略它。

9.png

上面是恢復OpenVPN密碼的PowerShell腳本。下面,通過reg.exe (POC) 顯示auth-data 和entropy 註冊表值的方式。

以基於Chromium 的瀏覽器為例進行具體分析測試版:

Google Chrome——測試版本:103.0.5060.53(官方版本)(64 位);

Microsoft Edge——測試版本:103.0.1264.37(官方版本)(64 位);

Opera——測試版本:88.0.4412.53;

Chromium 項目包括Chromium,它是Google Chrome 瀏覽器背後的開源項目。

在典型的使用例程中,許多人傾向於在上網時保存密碼。

10.png

Google Chrome 版本102.0.5005.115(官方版本)(64 位)保存的密碼

憑據存儲在哪裡?

在使用基於Chromium 的瀏覽器(如Microsoft Edge、Opera 或Google Chrome)時,密碼被加密位於SQLite 數據庫文件中,通常稱為登錄數據。

每個配置文件都有一個密碼數據庫,即它的登錄數據文件。

用於加密密碼的密鑰位於父文件夾中的名為本地狀態的JSON 文件中。

例如:

登錄數據位置:

加图5.png

區域位置:

Google Chrome: %localappdata%\google\chrome\user data\local state

Microsoft Edge: %localappdata%\microsoft\edge\user data\local state

Opera: %appdata%\opera software\opera stable\local state

如何恢復憑據?

登錄數據庫中的每個密碼都使用高級加密標準(AES) 以GCM 模式進行加密。 AES GCM是一種對稱加密方法,因此相同的密鑰對加密和解密都有效。 AES算法對每個128位數據塊使用不同的密鑰,該密鑰基於前一個塊的計算。對於第一個塊,可以選擇使用初始化向量(IV)。

要解密基於Chromium 的瀏覽器保存的密碼,我們需要:

加密的密碼;

初始化向量;

AES 密鑰;

讓我們看看如何檢索它們:

加密密碼

可以從登錄數據數據庫中導出:加密的密碼從password_value列中取出,從第15位的字母到末尾的16個字母。 [15:-16]

初始化向量

位於相同的password_value 字段列中,從第3 位的字母到第15 位的字母。 [3:15]

AES密鑰

寫在本地狀態JSON 文件中,在密鑰os_crypt 和encrypted_key 下,用base64 解碼。

基於Chromium 的瀏覽器使用DPAPI 機制保存AES 密鑰,因此要獲取它,我們必須從base64 解碼它並在用戶的上下文中使用CryptUnprotectData。

來自谷歌Chrome的示例:

11.png

保存在Google Chrome 本地狀態JSON 文件中的密碼

它以五個字母開頭的前綴保存:DPAPI。

12.png

保存在Google Chrome 中的解碼密碼

如果攻擊者能夠在用戶的上下文中運行,那麼完成收集用戶憑據所需要做的就是:

複製登錄數據和本地狀態文件;

從本地狀態JSON文件中獲取AES GCM密鑰;

解碼(base64),解密(CryptUnprotectData)並從密鑰中刪除填充;

使用解密的AES GCM 密鑰解密登錄數據數據庫中的每個密碼;

13.png

用於恢復Chrome 中保存的密碼的POC

你可以閱讀有關如何在Python 中提取Chrome 密碼的更多信息。

野外利用

我們看到在excel.exe中使用regsvr32.exe運行了以下DLL:

加图6.png

(kgnkudbadmpogg.dll 的SHA256:6599FEE8C7ADF30A00889A7070600F472F8CEAD8EA4DD1A85E724ED15F2AED0F)

在一系列操作之後,最終的有效負載試圖訪問Microsoft Edge 憑據文件:

登錄數據文件(SQLite 數據庫文件)如下所示:

加图7.png

本地狀態文件(包含加密密鑰)如下所示:

加图8.png

14.png

Cortex XDR 檢測到讀取保存在Microsoft Edge 瀏覽器中的密碼的嘗試

以Firefox瀏覽器為例進行具體分析測試版本:Firefox 版本101.0.1(64 位)

使用其他瀏覽器(例如Mozilla Firefox)時,密碼保存行為模式也很重要。

15.png

Firefox 版本101.0.1(64 位)保存的密碼

憑據存儲在哪裡?

與基於Chromium 的瀏覽器類似,在Mozilla Firefox 瀏覽器中,每個配置文件也有自己的密碼文件。

此文件名為logins.json,位於以下位置中:

加图9.png

用戶名和密碼均以加密方式保存。

16.png

Firefox 的logins.json 文件中保存的密碼

如何恢復憑據?

logins.json 文件中的每個用戶名和密碼都使用PKCS #11 加密標准進行加密。 Firefox 開發了NSS 庫,以便在其瀏覽器(nss3.dll) 中採用此標準。

NSS 將私鑰存儲在名為key3.db 或key4.db 的文件中,具體取決於NSS 版本。

要檢索用戶的密碼,攻擊者必須訪問其中一個文件和logins.json 文件。

因此,如果攻擊者能夠獲得在同一台計算機上運行的權限,那麼竊取密碼的過程將是:

攻擊者復制logins.json 文件;

加載NSS 庫(nss3.dll);

從logins.json 的副本中解碼(base64) encryptedUsername 和encryptedPassword;

將每個輸入存儲在一個SecItem 對像中,該對象稍後在整個NSS 中用於來回傳遞二進制數據塊;

創建用於輸出的SecItem 對象;

使用nss3.dll 中的PK11 解密函數解密每個encryptedUsername 和encryptedPassword 輸入對象,並將數據存儲在新的SecItem 輸出對像中;

與基於Chromium 的瀏覽器的情況不同,攻擊者不必在用戶的上下文中運行以獲取用戶的密碼,而是可以利用任何有權訪問目標用戶的文件系統配置文件的用戶。

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...