Skip to content

Commit 74c2526

Browse files
committed
Update kerberoast command output to be idiomatic
The output currently shows as username\domain. Most of the time, tools output usernames in the opposite way where the domain is first, and then the username
1 parent 71ccfd9 commit 74c2526

1 file changed

Lines changed: 9 additions & 33 deletions

File tree

nxc/protocols/ldap.py

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def create_conn_obj(self):
201201
target_domain = sub(
202202
r",DC=",
203203
".",
204-
base_dn[base_dn.lower().find("dc="):],
204+
base_dn[base_dn.lower().find("dc=") :],
205205
flags=IGNORECASE,
206206
)[3:]
207207
except ConnectionRefusedError as e:
@@ -322,12 +322,7 @@ def enum_host_info(self):
322322
self.output_filename = os.path.expanduser(f"~/.nxc/logs/{self.hostname}_{self.host}".replace(":", "-"))
323323

324324
try:
325-
self.db.add_host(
326-
self.host,
327-
self.hostname,
328-
self.domain,
329-
self.server_os
330-
)
325+
self.db.add_host(self.host, self.hostname, self.domain, self.server_os)
331326
except Exception as e:
332327
self.logger.debug(f"Error adding host {self.host} into db: {e!s}")
333328

@@ -343,7 +338,7 @@ def print_host_info(self):
343338
self.logger.display(f"{self.server_os} (name:{self.hostname}) (domain:{self.domain}) ({signing}) ({cbt_status}) {ntlm}")
344339

345340
def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False):
346-
self.username = username if not self.username else self.username # With ccache we get the username from the ticket
341+
self.username = username if not self.username else self.username # With ccache we get the username from the ticket
347342
self.password = password
348343
self.domain = domain
349344
self.kdcHost = kdcHost
@@ -875,27 +870,12 @@ def resolve_and_display_hostname(name, domain_name=None):
875870
trust_direction = int(trust["trustDirection"])
876871
trust_type = int(trust["trustType"])
877872
trust_attributes = int(trust["trustAttributes"])
878-
873+
879874
# See: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/e9a2d23c-c31e-4a6f-88a0-6646fdb51a3c
880-
trust_attribute_flags = {
881-
0x1: "Non-Transitive",
882-
0x2: "Uplevel-Only",
883-
0x4: "Quarantined Domain",
884-
0x8: "Forest Transitive",
885-
0x10: "Cross Organization",
886-
0x20: "Within Forest",
887-
0x40: "Treat as External",
888-
0x80: "Uses RC4 Encryption",
889-
0x200: "Cross Organization No TGT Delegation",
890-
0x800: "Cross Organization Enable TGT Delegation",
891-
0x2000: "PAM Trust"
892-
}
875+
trust_attribute_flags = {0x1: "Non-Transitive", 0x2: "Uplevel-Only", 0x4: "Quarantined Domain", 0x8: "Forest Transitive", 0x10: "Cross Organization", 0x20: "Within Forest", 0x40: "Treat as External", 0x80: "Uses RC4 Encryption", 0x200: "Cross Organization No TGT Delegation", 0x800: "Cross Organization Enable TGT Delegation", 0x2000: "PAM Trust"}
893876

894877
# For check if multiple posibble flags, like Uplevel-Only, Treat as External
895-
trust_attributes_text = ", ".join(
896-
text for flag, text in trust_attribute_flags.items()
897-
if trust_attributes & flag
898-
) or "Other" # If Trust attrs not known
878+
trust_attributes_text = ", ".join(text for flag, text in trust_attribute_flags.items() if trust_attributes & flag) or "Other" # If Trust attrs not known
899879

900880
# Convert trust direction/type to human-readable format
901881
direction_text = {
@@ -1050,7 +1030,7 @@ def kerberoasting(self):
10501030
self.logger.debug(f"Exception: {e}", exc_info=True)
10511031
self.logger.fail(f"Principal: {downLevelLogonName} - {e}")
10521032
else:
1053-
self.logger.fail(f"Error retrieving TGT for {self.username}\\{self.domain} from {self.kdcHost}")
1033+
self.logger.fail(f"Error retrieving TGT for {self.domain}\\{self.username} from {self.kdcHost}")
10541034

10551035
def query(self):
10561036
"""
@@ -1111,14 +1091,10 @@ def printTable(items, header):
11111091
self.logger.highlight(outputFormat.format(*row))
11121092

11131093
# Building the search filter
1114-
search_filter = (f"(&(|(UserAccountControl:1.2.840.113556.1.4.803:={UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION})"
1115-
f"(UserAccountControl:1.2.840.113556.1.4.803:={UF_TRUSTED_FOR_DELEGATION})"
1116-
"(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))"
1117-
f"(!(UserAccountControl:1.2.840.113556.1.4.803:={UF_ACCOUNTDISABLE})))")
1094+
search_filter = f"(&(|(UserAccountControl:1.2.840.113556.1.4.803:={UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION})(UserAccountControl:1.2.840.113556.1.4.803:={UF_TRUSTED_FOR_DELEGATION})(msDS-AllowedToDelegateTo=*)(msDS-AllowedToActOnBehalfOfOtherIdentity=*))(!(UserAccountControl:1.2.840.113556.1.4.803:={UF_ACCOUNTDISABLE})))"
11181095
# f"(!(UserAccountControl:1.2.840.113556.1.4.803:={UF_SERVER_TRUST_ACCOUNT})))") This would filter out RBCD to DCs
11191096

1120-
attributes = ["sAMAccountName", "pwdLastSet", "userAccountControl", "objectCategory",
1121-
"msDS-AllowedToActOnBehalfOfOtherIdentity", "msDS-AllowedToDelegateTo"]
1097+
attributes = ["sAMAccountName", "pwdLastSet", "userAccountControl", "objectCategory", "msDS-AllowedToActOnBehalfOfOtherIdentity", "msDS-AllowedToDelegateTo"]
11221098

11231099
resp = self.search(search_filter, attributes)
11241100
answers = []

0 commit comments

Comments
 (0)