diff --git a/clouds/azure/AzureRT b/clouds/azure/AzureRT index 5830ad8..7848ebc 160000 --- a/clouds/azure/AzureRT +++ b/clouds/azure/AzureRT @@ -1 +1 @@ -Subproject commit 5830ad897e323325e854e70b7c69ffad623b7d17 +Subproject commit 7848ebc1e348a1c1811a048961f4b65255e3a532 diff --git a/file-formats/PackMyPayload b/file-formats/PackMyPayload index 75f6270..6ce9975 160000 --- a/file-formats/PackMyPayload +++ b/file-formats/PackMyPayload @@ -1 +1 @@ -Subproject commit 75f6270d0417d749b56c718d0d8ad0003c74d785 +Subproject commit 6ce9975ae639ac16b7dce5c6461a066d8988cec8 diff --git a/networks/exchangeRecon.py b/networks/exchangeRecon.py index f0e981b..51da3ea 100644 --- a/networks/exchangeRecon.py +++ b/networks/exchangeRecon.py @@ -348,7 +348,7 @@ class ExchangeRecon: MAX_RECONNECTS = 3 MAX_REDIRECTS = 10 HEADERS = { - 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', @@ -788,24 +788,25 @@ class ExchangeRecon: if resp['code'] in [301, 302, 303] and followRedirect: Logger.dbg(f'Following redirect. Depth: {redirect}...') - location = urlparse(resp['headers']['location']) - port = 80 if location.scheme == 'http' else 443 - host = location.netloc - if not host: host = self.hostname - if ':' in location.netloc: - port = int(location.netloc.split(':')[1]) - host = location.netloc.split(':')[0] + if 'location' in resp['headers'].keys(): + location = urlparse(resp['headers']['location']) + port = 80 if location.scheme == 'http' else 443 + host = location.netloc + if not host: host = self.hostname + if ':' in location.netloc: + port = int(location.netloc.split(':')[1]) + host = location.netloc.split(':')[0] - if self.connect(host, port): - pos = resp['headers']['location'].find(location.path) - return self.http( - method = 'GET', - url = resp['headers']['location'][pos:], - host = host, - data = '', - headers = headers, - followRedirect = redirect < ExchangeRecon.MAX_REDIRECTS, - redirect = redirect + 1) + if self.connect(host, port): + pos = resp['headers']['location'].find(location.path) + return self.http( + method = 'GET', + url = resp['headers']['location'][pos:], + host = host, + data = '', + headers = headers, + followRedirect = redirect < ExchangeRecon.MAX_REDIRECTS, + redirect = redirect + 1) return resp, raw @@ -1148,6 +1149,7 @@ class ExchangeRecon: except Exception: server = ExchangeRecon._smtpconnect(host, port, _ssl) if not server: + Logger.info('Could not interact with SMTP.') return None code, msg = server.ehlo() diff --git a/red-teaming/Handy-BloodHound-Cypher-Queries.md b/red-teaming/Handy-BloodHound-Cypher-Queries.md index 0ad1db6..759c564 100644 --- a/red-teaming/Handy-BloodHound-Cypher-Queries.md +++ b/red-teaming/Handy-BloodHound-Cypher-Queries.md @@ -25,6 +25,8 @@ MATCH (u {highvalue: true}) WHERE toLower(u.name) ENDS WITH "" RETURN MATCH (c {hasspn: True}) RETURN c.name as name, c.allowedtodelegate as AllowedToDelegate, c.unconstraineddelegation as UnconstrainedDelegation, c.admincount as AdminCount, c.serviceprincipalnames as SPNs ``` +### Principals with most Outbound Controlled objects + - Returns Top 100 **Outbound Control Rights** --> **First Degree Object Control** principals in domain: ``` MATCH p=(u)-[r1]->(n) WHERE r1.isacl=true @@ -59,6 +61,37 @@ ORDER BY controlled DESC LIMIT 50 ``` +- Returns principals having more than 1000 **Outbound Control Rights** --> **First Degree Object Control** controlled: +``` +MATCH p=(u)-[r1]->(n) WHERE r1.isacl=true +WITH u.name as name, LABELS(u)[1] as type, +COUNT(DISTINCT(n)) as controlled +WHERE name IS NOT NULL AND controlled > 1000 +RETURN type, name, controlled +ORDER BY controlled DESC +``` + +- Returns principals having more than 1000 **Outbound Control Rights** --> **Group Delegated Object Control** controlled and whether that object is member of high privileged group (such a `Domain Admins` or `Domain Controllers`): +``` +MATCH p=(u)-[r1:MemberOf*1..]->(g:Group)-[r2]->(n) WHERE r2.isacl=true +WITH u.name as name, LABELS(u)[1] as type, g.highvalue as highly_privileged, +COUNT(DISTINCT(n)) as controlled +WHERE name IS NOT NULL AND controlled > 1000 +RETURN type, name, highly_privileged, controlled +ORDER BY controlled DESC +``` + +- Returns principals having more than 1000 **Outbound Control Rights** --> **Transitive Object Control** controlled (TAKES ENORMOUS TIME TO COMPUTE! You were warned): +``` +MATCH p=shortestPath((u)-[r1:MemberOf|AddMember|AllExtendedRights|ForceChangePassword|GenericAll|GenericWrite|WriteDacl|WriteOwner|Owns*1..]->(n)) +WHERE u<>n +WITH u.name as name, LABELS(u)[1] as type, +COUNT(DISTINCT(n)) as controlled +WHERE name IS NOT NULL AND controlled > 1000 +RETURN type, name, controlled +ORDER BY controlled DESC +``` + ### Users - Pulls users eligible for ASREP roasting diff --git a/red-teaming/PackMyPayload b/red-teaming/PackMyPayload deleted file mode 160000 index 9707453..0000000 --- a/red-teaming/PackMyPayload +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9707453f60255221b0493aa5e9367d59d7bcc8ab