garrettfoster13 / sccmhunter

MIT License
643 stars 80 forks source link

LDAPInvalidFilterError: malformed filter #69

Open loudpenguin opened 4 days ago

loudpenguin commented 4 days ago

Running sccmhunter, i'm also getting an error regarding a malformed filter

`

python3 sccmhunter.py find -dc-ip [REDACTED] -d [REDACTED] -u [REDACTED] -p '[REDACTED]'

/root/sccmhunter/lib/attacks/http.py:87: SyntaxWarning: invalid escape sequence '[' result = re.search("PolicyCategory=\"NAAConfig\".?<![CDATA[https://([^]]+)", deflatedData, re.DOTALL + re.MULTILINE) /root/sccmhunter/lib/scripts/sccmwtf.py:191: SyntaxWarning: invalid escape sequence '[' result = re.search("PolicyCategory=\"NAAConfig\".?<![CDATA[https://([^]]+)", decompressed, re.DOTALL + re.MULTILINE) /root/sccmhunter/lib/scripts/sccmwtf.py:294: SyntaxWarning: invalid escape sequence '[' result = re.search("PolicyCategory=\"NAAConfig\".?<![CDATA[https://([^]]+)", deflatedData, re.DOTALL + re.MULTILINE) SCCMHunter v1.0.5 by @garrfoster [09:56:52] INFO table CAS already exists [09:56:55] INFO [] Checking for System Management Container. [09:56:55] INFO [+] Found System Management Container. Parsing DACL. [09:57:43] INFO [+] Found 14 computers with Full Control ACE [09:57:43] INFO [] Querying LDAP for published Sites and Management Points [09:57:43] INFO [+] Found 1 Management Points in LDAP. [09:57:43] INFO [*] Querying LDAP for potential PXE enabled distribution points [09:57:51] INFO [+] Found 42 potential Distribution Points in LDAP. ╭──────────────────────────────────────────────────────────────────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ /root/sccmhunter/lib/commands/find.py:32 in main │ │ │ │ 29 │ logs_dir = initlogger(debug) │ │ 30 │ sccmhunter = SCCMHUNTER(username=username, password=password, domain=domain, target │ │ 31 │ │ │ │ │ │ │ kerberos=kerberos, no_pass=no_pass, hashes=hashes, aes=aes, │ │ ❱ 32 │ sccmhunter.run() │ │ 33 │ │ │ │ /root/sccmhunter/lib/attacks/find.py:122 in run │ │ │ │ 119 │ │ #check for AD extension info │ │ 120 │ │ self.check_schema() │ │ 121 │ │ #check for potential DPs │ │ ❱ 122 │ │ self.check_dps() │ │ 123 │ │ #if they're using DNS only: thoughts and prayers │ │ 124 │ │ self.check_strings() │ │ 125 │ │ │ │ /root/sccmhunter/lib/attacks/find.py:265 in check_dps │ │ │ │ 262 │ │ if potential_dps: │ │ 263 │ │ │ for dn in potential_dps: │ │ 264 │ │ │ │ try: │ │ ❱ 265 │ │ │ │ │ self.ldap_session.extend.standard.paged_search(self.search_base, │ │ 266 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ f"(distinguishedName={dn │ │ 267 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ attributes="dNSHostName" │ │ 268 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ controls=self.controls, │ │ │ │ /root/sccmhunter/lib/python3.12/site-packages/ldap3/extend/init.py:114 in paged_search │ │ │ │ 111 │ │ │ │ │ │ │ │ │ │ paged_size, │ │ 112 │ │ │ │ │ │ │ │ │ │ paged_criticality) │ │ 113 │ │ else: │ │ ❱ 114 │ │ │ return paged_search_accumulator(self._connection, │ │ 115 │ │ │ │ │ │ │ │ │ │ │ search_base, │ │ 116 │ │ │ │ │ │ │ │ │ │ │ search_filter, │ │ 117 │ │ │ │ │ │ │ │ │ │ │ search_scope, /root/sccmhunter/lib/python3.12/site-packages/ldap3/extend/standard/PagedSearch.py:130 in paged_search_accumulator │ │ │ │ 127 │ │ search_base = safe_dn(search_base) │ │ 128 │ │ │ 129 │ responses = [] │ │ ❱ 130 │ for response in paged_search_generator(connection, │ │ 131 │ │ │ │ │ │ │ │ │ │ search_base, │ │ 132 │ │ │ │ │ │ │ │ │ │ search_filter, │ │ 133 │ │ │ │ │ │ │ │ │ │ search_scope, │ │ │ │ /root/sccmhunter/lib/python3.12/site-packages/ldap3/extend/standard/PagedSearch.py:56 in paged_search_generator │ │ │ │ 53 │ cookie = True # performs search operation at least one time │ │ 54 │ cachekey = None # for referrals cache │ │ 55 │ while cookie: │ │ ❱ 56 │ │ result = connection.search(search_base, │ │ 57 │ │ │ │ │ │ │ │ search_filter, │ │ 58 │ │ │ │ │ │ │ │ search_scope, │ │ 59 │ │ │ │ │ │ │ │ dereference_aliases, │ │ │ │ /root/sccmhunter/lib/python3.12/site-packages/ldap3/core/connection.py:838 in search │ │ │ │ 835 │ │ │ │ │ │ │ log(ERROR, '%s for <%s>', self.last_error, self) │ │ 836 │ │ │ │ │ │ raise LDAPAttributeError(self.last_error) │ │ 837 │ │ │ │ │ ❱ 838 │ │ │ request = search_operation(search_base, │ │ 839 │ │ │ │ │ │ │ │ │ search_filter, │ │ 840 │ │ │ │ │ │ │ │ │ search_scope, │ │ 841 │ │ │ │ │ │ │ │ │ dereference_aliases, │ │ │ │ /root/sccmhunter/lib/python3.12/site-packages/ldap3/operation/search.py:371 in search_operation │ │ │ │ 368 │ request['sizeLimit'] = Integer0ToMax(size_limit) │ │ 369 │ request['timeLimit'] = Integer0ToMax(time_limit) │ │ 370 │ request['typesOnly'] = TypesOnly(True) if types_only else TypesOnly(False) │ │ ❱ 371 │ request['filter'] = compile_filter(parse_filter(search_filter, schema, auto_escape, │ │ 372 │ if not isinstance(attributes, SEQUENCE_TYPES): │ │ 373 │ │ attributes = [NO_ATTRIBUTES] │ │ 374
│ │ │ /root/sccmhunter/lib/python3.12/site-packages/ldap3/operation/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 `

garrettfoster13 commented 4 days ago

Trouble with this is I'd need to see the filter it's breaking on or is malformed. If you can add a print statement on a new line below https://github.com/garrettfoster13/sccmhunter/blob/1184ff5241d4b31bea629c325ee007df54843d60/lib/attacks/find.py#L263 print(dn) to print the distinguishedname its filtering for I can narrow down what might be the issue.

loudpenguin commented 4 days ago

I added the print statement like you requested. I had to redact the data a bit, so the words are modified but the format is exactly the same as far as letters, capitals, spaces, etc:

DEBUG: dn = CN=BLRSCCMDP01,OU=Vivamus Fermentum,OU=Mauris Fermentum,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=ANTSCCM01P,OU=Vivamus Fermentum,OU=Curabitur,OU=Efficitur Risus,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=TURSCCM02P,OU=Vivamus Fermentum,OU=Curabitur,OU=Efficitur Risus,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=MILSCCM01P,OU=Vivamus Fermentum,OU=Curabitur,OU=Efficitur Risus,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=PARSCCM01P,OU=Vivamus Fermentum,OU=Curabitur,OU=Efficitur Risus,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=TURSCCM01P,OU=Vivamus Fermentum,OU=Curabitur,OU=Efficitur Risus,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=EUKOELSCCM01,OU=Vivamus Fermentum,OU=Curabitur,OU=Efficitur Risus,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=AP1SCCMDP01,OU=Vivamus Fermentum,OU=Sem Sed,OU=Mauris Fermentum,OU=Member Fermentum,DC=PULVINAR,DC=COM
DEBUG: dn = CN=AP2SCCMDP01,OU=Vivamus Fermentum,OU=Aliquet (AP2),OU=Mauris Fermentum,OU=Member Fermentum,DC=PULVINAR,DC=COM
loudpenguin commented 4 days ago

perhaps its the parentheses

garrettfoster13 commented 4 days ago

(AP2) probably this

Yeah think an escape_filter_chars() function is needed to fix this one