Code Monkey home page Code Monkey logo

sccmhunter's Introduction

Sponsored by SpecterOps Black Hat USA Arsenal 2024 @garrfoster on Twitter

image

SCCMHunter

SCCMHunter is a post-ex tool built to streamline identifying, profiling, and attacking SCCM related assets in an Active Directory domain. Please checkout the wiki for detailed usage.

Please note

This tool was developed and tested in a lab environment. Your mileage may vary on performance. If you run into any problems please don't hesitate to open an issue.

Installation

I strongly encourage using a python virtual environment for installation


git clone https://github.com/garrettfoster13/sccmhunter.git
cd sccmhunter
virtualenv --python=python3 .
source bin/activate
pip3 install -r requirements.txt
python3 sccmhunter.py -h

References

Huge thanks to the below for all their research and hard work and
@_mayyhem
Coercing NTLM Authentication from SCCM
SCCM Site Takeover via Automatic Client Push Installation

@TechBrandon
Push Comes To Shove: exploring the attack surface of SCCM Client Push Accounts
Push Comes To Shove: Bypassing Kerberos Authentication of SCCM Client Push Accounts.

@Raiona_ZA
Identifying and retrieving credentials from SCCM/MECM Task Sequences

@_xpn_
Exploring SCCM by Unobfuscating Network Access Accounts

@subat0mik
The Phantom Credentials of SCCM: Why the NAA Won’t Die

@HackingDave
Owning One to Rule Them All

sccmhunter's People

Contributors

garrettfoster13 avatar i128 avatar jsatest avatar mayyhem avatar ralphdesmangles avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

sccmhunter's Issues

pipx compatibility

First off, excellent tool, thanks very much Garrett.

Any chance you could make this compatible with pipx please so it takes care of managing the virtual env for us? Makes life so much easier.

Thanks again

MSSQL stacked query is broken

Hi guys !

The -stacked parameter for the mssql command is now broken, and the output is no more "stacked".
I guess the problem comes from the #48 pull request.

Add collection querying

Recent user requested an update to view the members of a collection for targeting. In this case, there was a collection that identified specific system where endpoint security products were not installed. Viewing the memberships of this group was valuable to the progress of their op.

Error when using the "show -all" command

Hi,

Thank you for this tool!

When I use the command show -all I get the below error. The root cause seems to be that the earlier enumeration never produced the file groups.csv:
sccmhunter1

"IndexError" when executing commands in a SCCM database

Using the dev branch I have successfully added a domain user account to SCCM's database and supposedly have full administrative rights there. However, using the command admin I get a database shell but then things starts to fail. None of the commands I have tested works:

sccmhunter3

Malformed filter

Trying to execute the 'find' command and getting an error about malformed filter:

python sccmhunter.py find -u 'User1' -p 'password' -t target.com -dc-ip 192.168.1.50
│ /home/user1/.local/share/virtualenvs/sccmhunter-3buROxXy/lib/python3.11/site-packages/ldap3/op │
│ eration/search.py:214 in parse_filter                                                            │
│                                                                                                  │
│   211 │   │   │   │   │   start_pos = pos                                                        │
│   212 │   │   │   │   state = SEARCH_MATCH_OR_CLOSE                                              │
│   213 │   │   │   else:                                                                          │
│ ❱ 214 │   │   │   │   raise LDAPInvalidFilterError('malformed filter')                           │
│   215 │   │   if len(root.elements) != 1:                                                        │
│   216 │   │   │   raise LDAPInvalidFilterError('missing boolean operator in filter')             │
│   217 │   │   return root                                                                        │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
LDAPInvalidFilterError: malformed filter

UnicodeEncodeError: 'charmap' codec can't encode characters

Hi, when running 'find' or 'smb' i've got an error:
UnicodeEncodeError: 'charmap' codec can't encode characters in position 72-76: character maps to <undefined>

OS: Windows 10
Running inside venv

image

console output:

PS > python3 .\sccmhunter.py smb -u admin -p 10203040 -d corp.exmaple.com -dc-ip 10.10.10.10

                                                                                          (
                                    888                         d8                         \
 dP"Y  e88'888  e88'888 888 888 8e  888 ee  8888 8888 888 8e   d88    ,e e,  888,8,        )
C88b  d888  '8 d888  '8 888 888 88b 888 88b 8888 8888 888 88b d88888 d88 88b 888 "    ##-------->
 Y88D Y888   , Y888   , 888 888 888 888 888 Y888 888P 888 888  888   888   , 888           )
d,dP   "88,e8'  "88,e8' 888 888 888 888 888  "88 88"  888 888  888    "YeeP" 888          /
                                                                                         (
                                                                 v0.0.2
                                                                 @garrfoster



[15:20:17] INFO     [-] Existing log file not found, searching LDAP for site servers.
[15:20:18] INFO     [+] Found System Management Container. Parsing DACL.
[15:20:20] INFO     "key 'member' not found"
[15:20:20] INFO     "key 'member' not found"
[15:20:20] INFO     [+] Found 2 computers with Full Control ACE
[15:20:20] INFO     [*] Querying LDAP for published Management Points
[15:20:20] INFO     [+] Found 2 site servers in LDAP.
[15:20:21] INFO     [*] Searching LDAP for anything containing the strings 'SCCM'or 'MECM'
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ C:\Tools\sccmhunter\lib\commands\smb.py:28 in main                                               │
│                                                                                                  │
│   25 │   smbhunter = SMB(username=username, password=password, domain=domain, dc_ip=dc_ip,lda    │
│   26 │   │   │   │   │   │   │   kerberos=kerberos, no_pass=no_pass, hashes=hashes, aes=aes,     │
│   27 │   │   │   │   │   │   │    save=save, logs_dir=logs_dir)                                  │
│ ❱ 28 │   smbhunter.run()                                                                         │
│   29                                                                                             │
│   30                                                                                             │
│   31                                                                                             │
│                                                                                                  │
│ C:\Tools\sccmhunter\lib\attacks\smb.py:57 in run                                                 │
│                                                                                                  │
│    54 │   │   │   │   │   │   │   │   │   target_dom=self.target_dom, dc_ip=self.dc_ip,ldaps=s   │
│    55 │   │   │   │   │   │   │   │   │   kerberos=self.kerberos, no_pass=self.no_pass, hashes   │
│    56 │   │   │   │   │   │   │   │   │   aes=self.aes, debug=self.debug, logs_dir=self.logs_d   │
│ ❱  57 │   │   │   sccmhunter.run()                                                               │
│    58 │   │   │   self.run()                                                                     │
│    59 │                                                                                          │
│    60 │   def read_logs(self):                                                                   │
│                                                                                                  │
│ C:\Tools\sccmhunter\lib\attacks\find.py:238 in run                                               │
│                                                                                                  │
│   235 │   │   else:                                                                              │
│   236 │   │   │   logger.info("[-] No SCCM Servers found.")                                      │
│   237 │   │                                                                                      │
│ ❱ 238 │   │   self.save_csv(_users, _computers, _groups)                                         │
│   239 │   │                                                                                      │
│   240 │   │                                                                                      │
│   241 │   │   # show results                                                                     │
│                                                                                                  │
│ C:\Tools\sccmhunter\lib\attacks\find.py:322 in save_csv                                          │
│                                                                                                  │
│   319 │   │   │   with open(f'{self.logs_dir}/csvs/groups.csv', 'w', newline='') as f:           │
│   320 │   │   │   │   writer = csv.DictWriter(f, fieldnames=group_fields)                        │
│   321 │   │   │   │   writer.writeheader()                                                       │
│ ❱ 322 │   │   │   │   writer.writerows(groups)                                                   │
│   323 │   │   │   f.close()                                                                      │
│   324 │   │                                                                                      │
│   325 │   │   if self.debug:                                                                     │
│                                                                                                  │
│ C:\Users\predator\AppData\Local\Programs\Python\Python310\lib\csv.py:157 in writerows            │
│                                                                                                  │
│   154 │   │   return self.writer.writerow(self._dict_to_list(rowdict))                           │
│   155 │                                                                                          │
│   156 │   def writerows(self, rowdicts):                                                         │
│ ❱ 157 │   │   return self.writer.writerows(map(self._dict_to_list, rowdicts))                    │
│   158                                                                                            │
│   159 # Guard Sniffer's type checking against builds that exclude complex()                      │
│   160 try:                                                                                       │
│                                                                                                  │
│ C:\Users\predator\AppData\Local\Programs\Python\Python310\lib\encodings\cp1252.py:19 in encode   │
│                                                                                                  │
│    16                                                                                            │
│    17 class IncrementalEncoder(codecs.IncrementalEncoder):                                       │
│    18 │   def encode(self, input, final=False):                                                  │
│ ❱  19 │   │   return codecs.charmap_encode(input,self.errors,encoding_table)[0]                  │
│    20                                                                                            │
│    21 class IncrementalDecoder(codecs.IncrementalDecoder):                                       │
│    22 │   def decode(self, input, final=False):                                                  │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
UnicodeEncodeError: 'charmap' codec can't encode characters in position 72-76: character maps to <undefined>

Unexpected mimetype in content-type: 'text/html'

Running the sccmhunter.py script as follows:

python3 sccmhunter.py http -u user -p password -dc-ip DC ip -d domain -auto

Returns the following output:

INFO Found targets from logfile.
INFO [+] Found http://redacted/
INFO [] User selected auto. Attempting to add a machine account then request policies.
INFO [+] computer$ created with password: password
INFO [
] Atempting to grab policy from sccm
Unexpected mimetype in content-type: 'text/html'

Not sure what is causing the issue here...?

Error binding parameter 1: type 'Entry' is not supported

When running sccm hunter I got the following error:

ProgrammingError: Error binding parameter 1: type 'Entry' is not supported

in

sccmhunter/lib/attacks/find.py:326 in add_computer_to_db

In line 315 the code checks if dNSHostName exists in the entry argument. If not, it assignes the "entry" argument as hostname (line 318). This does not work in the later SQL command (line 326).

As workaround I add a return statement in the "else"-condition. Maybe there is a better solution.

relay option question

Hey Garrett thanks for an awesome tool its been really useful on many engagements. I have just one proposal to improve if not lot of effort is needed. The relay option, you implemented the option to add new computer account which is great but not all the time machine account quota is misconfigured, so I was thinking would it even be possible to utilize coercion(Poldarius Coercer) in order to obtain machine account hashes and then relay it to MECM/SCCM HTTP endpoint and then utilize the sccmwtf.py module to obtain policy file.

No such option: -k

  1. Obtained a TGT from getTGT.py
  2. export KRB5CCNAME
  3. run sccmhunter -k -no-pass -u -d -dc-ip

Error:
No such option -k

Help talks about -k option for kerberos.

Thank you!

Unexpected mimetype in content-type: 'text/html'

During registration in the HTTP module, Logan received an unexpected mime type error response. This error has come up before but I haven't been able to reproduce it. I'm leaving this issue open so others can share their experience.

I will be adding an update to the http module to output POST request reponses. If you're willing, please add your redacted results.

Expected string or bytes-like object, got 'NoneType'

Have encountered an issue several times now where device registration fails with the errors "Expected string or bytes-like object, got 'NoneType'" or "Invalid cross-device link". This is using Python v3.11/3.12.

2024-09-13_16-23-25

This is triggered on line:

os.rename(key, newkey)

Not sure if this is fixable within the Python environment itself, but this workaround fixed it:

  1. Add import shutil
  2. Change os.rename(key, newKey) --> shutil.copy(key, newkey)

ERROR in lib.commands

Hello. How can I correct the error: from lib.commands import find, mssql, smb, http, show, admin, dpapi
Modulenotfounderror: No Module Named 'Lib.commands'?

The delete_admin command of the admin function is incorrectly retrieving the adminid

I found an issue in the delete_admin function of the add_admin.py script.

Line 82 of the add_admin.py script uses the following filter for retrieving the adminid:

url = f"https://{self.target_ip}/AdminService/wmi/SMS_Admin/?$filter=DisplayName eq '{self.targetuser}'"

This results in the command not correctly identifying the adminid for a given user, and the command fails with a "Target user is not configured as an SMS Admin".

Propose swapping the filter on line 82 to:

url = f"https://{self.target_ip}/AdminService/wmi/SMS_Admin/?$filter=LogonName eq '{self.targetuser}'"

This matches the filter used in the show_admins command and results in successfully retrieving the adminid for a given target user account.

Unsupported hash MD4 - NoneType object has no attribute split

Looks like there is a dependency on an older python module that supports MD4, while the version I'm using does not.

Installed requests_ntlm==1.2.0 and now that works but getting a 'NoneType' object when attempting to extract policies with the http module.

image

Now with the updated requests_ntlm library

image

Need to add a check for valid "script approver" creds

Currently if you supply any set of credentials for script approval the script command will execute. Need to add a check for valid credentials and error handling when the credentials are invalid. Script execution just fails without any explanation.

Add user agent flag for Admin

Add user agent flag to allow operator to modify the user-agent string used for requests. Otherwise default to python requests.

Issue with the DPAPI

Hello @garrettfoster13, @RalphDesmangles

I have tried to use the DPAPI module and I am getting the following error.

python3 sccmhunter.py dpapi -u Test -d test.com -target 172.16.x.x -p Testpassword

                                                                                          (
                                    888                         d8                         \
 dP"Y  e88'888  e88'888 888 888 8e  888 ee  8888 8888 888 8e   d88    ,e e,  888,8,        )
C88b  d888  '8 d888  '8 888 888 88b 888 88b 8888 8888 888 88b d88888 d88 88b 888 "    ##-------->
 Y88D Y888   , Y888   , 888 888 888 888 888 Y888 888P 888 888  888   888   , 888           )
d,dP   "88,e8'  "88,e8' 888 888 888 888 888  "88 88"  888 888  888    "YeeP" 888          /
                                                                                         (
                                                                 v0.0.2                   
                                                                 @garrfoster                    
    
    
    
[12:02:53] INFO     [*] Querying SCCM configuration via WMI                                                                                                                                                                                 
[12:02:53] INFO     [+] Got 2 SCCM secrets.                                                                                                                                                                                                 
[12:02:53] INFO     [+] Credential file found: DFBE70A7E5CC19A398EBF1B96859CE5D                                                                                                                                                             
[12:02:53] INFO     [+] Retrieving credential file: DFBE70A7E5CC19A398EBF1B96859CE5D                                                                                                                                                        
[12:02:53] INFO     [+] Retrieving masterkey file: C829C67B-4573-4D92-9ECD-AC9609F3E6C1                                                                                                                                                     
[12:02:54] INFO     [!] LSA hashes extraction failed: 'HashRecords'                                                                                                                                                                         
Exception ignored in: <function Registry.__del__ at 0x7f6d22ea7920>
Traceback (most recent call last):
  File "/home/kali/Desktop/tools/sccmhunter/sccmhunter/lib/python3.11/site-packages/impacket/winregistry.py", line 182, in __del__
    self.close()
  File "/home/kali/Desktop/tools/sccmhunter/sccmhunter/lib/python3.11/site-packages/impacket/winregistry.py", line 179, in close
    self.fd.close()
  File "/home/kali/Desktop/tools/sccmhunter/sccmhunter/lib/python3.11/site-packages/impacket/examples/secretsdump.py", line 356, in close
    self.__smbConnection.closeFile(self.__tid, self.__fid)
  File "/home/kali/Desktop/tools/sccmhunter/sccmhunter/lib/python3.11/site-packages/impacket/smbconnection.py", line 603, in closeFile
    return self._SMBConnection.close(treeId, fileId)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/kali/Desktop/tools/sccmhunter/sccmhunter/lib/python3.11/site-packages/impacket/smb3.py", line 1271, in close
    packetID = self.sendSMB(packet)
               ^^^^^^^^^^^^^^^^^^^^
  File "/home/kali/Desktop/tools/sccmhunter/sccmhunter/lib/python3.11/site-packages/impacket/smb3.py", line 423, in sendSMB
    self._NetBIOSSession.send_packet(packet)
  File "/home/kali/Desktop/tools/sccmhunter/sccmhunter/lib/python3.11/site-packages/impacket/nmb.py", line 912, in send_packet
    self._sock.sendall(p.rawData())
OSError: [Errno 9] Bad file descriptor

I have used the systemdpapidump.py module, and it works fine.

sccm_data_type

Within a Python3.9 virtual environment and after installing the requirements, @TinyTiger08 and I are getting sccm_data_type as an error:
image

Using Kali 2023.3, installed packages:
image

Installation issues

Hi,

Thank you for this tool!

I am trying to install SCCMHunter in order to test it but I am faced with two issues:

  1. Using pip3 install . as instructed here does not work. I get the error "ERROR: Directory '.' is not installable. Neither 'setup.py' nor 'pyproject.toml' found.".
  2. Using python3 -m pip install -r requirements.txt works but building wheel takes about ten minutes.

Am I doing something wrong? If not, can building wheel be sped up?

Thanks!

Create confidence levels for Site Server enum

Becausethe FIND module is just checking for full control over the System Managaement container, this creates false positives in networks where other systems may have a similar permission. Most frequently Exchange servers. There are three things that can be checked to calculate this:

  1. Full control ACE for System Management
  2. Presence of default file shares
  3. Presence of SMS Provider

This would reduce the false positive rate substantially. It's still not perfect since Passive site servers will not have any default shares to query. However, the likelihood the site server deosn't have the SMS Provider role is extremely low. So, hiding any site servers that have a confidence score of 33% should be hidden from the oeprators view. The remaining site servers should be sorted in order of confidence levels.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.