Skip to content

Commit 444e3dd

Browse files
committed
Properly format computer accounts for tgs roasting
1 parent 393be37 commit 444e3dd

2 files changed

Lines changed: 14 additions & 4 deletions

File tree

nxc/protocols/ldap.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,7 @@ def kerberoasting(self):
10671067
"MemberOf",
10681068
"pwdLastSet",
10691069
"lastLogon",
1070+
"objectClass",
10701071
]
10711072
resp = self.search(searchFilter, attributes, 0)
10721073
resp_parsed = parse_result_attributes(resp)
@@ -1111,6 +1112,7 @@ def kerberoasting(self):
11111112
sessionKey,
11121113
user["sAMAccountName"],
11131114
downLevelLogonName,
1115+
is_computer="computer" in user.get("objectClass", [])
11141116
)
11151117

11161118
pwdLastSet = "<never>" if str(user.get("pwdLastSet", 0)) == "0" else str(datetime.fromtimestamp(self.getUnixTime(int(user["pwdLastSet"]))))

nxc/protocols/ldap/kerberos.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def __init__(self, connection):
4646
if self.password is None:
4747
self.password = ""
4848

49-
def output_tgs(self, tgs, old_session_key, session_key, username, spn, fd=None):
49+
def output_tgs(self, tgs, old_session_key, session_key, username, spn, fd=None, is_computer=False):
5050
decoded_tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
5151

5252
# According to RFC4757 (RC4-HMAC) the cipher part is like:
@@ -69,16 +69,24 @@ def output_tgs(self, tgs, old_session_key, session_key, username, spn, fd=None):
6969
etype = enc["etype"]
7070
cipher = enc["cipher"].asOctets()
7171
realm = decoded_tgs["ticket"]["realm"]
72-
7372
spn_fmt = spn.replace(":", "~")
73+
74+
# Replace username if it's a computer account
75+
if is_computer:
76+
account = f"host{username.rstrip('$').lower()}.{str(realm).lower()}"
77+
else:
78+
if username.endswith("$"):
79+
nxc_logger.fail("Account ends with $, but is_computer is False. TGS output is likely to be incorrect.")
80+
account = username
81+
7482
if etype in (constants.EncryptionTypes.rc4_hmac.value, constants.EncryptionTypes.des_cbc_md5.value):
7583
chk = hexlify(cipher[:16]).decode()
7684
data = hexlify(cipher[16:]).decode()
77-
entry = f"$krb5tgs${etype}$*{username}${realm}${spn_fmt}*${chk}${data}"
85+
entry = f"$krb5tgs${etype}$*{account}${realm}${spn_fmt}*${chk}${data}"
7886
elif etype in (constants.EncryptionTypes.aes128_cts_hmac_sha1_96.value, constants.EncryptionTypes.aes256_cts_hmac_sha1_96.value):
7987
chk = hexlify(cipher[-12:]).decode()
8088
data = hexlify(cipher[:-12]).decode()
81-
entry = f"$krb5tgs${etype}${username}${realm}$*{spn_fmt}*${chk}${data}"
89+
entry = f"$krb5tgs${etype}${account}${realm}$*{spn_fmt}*${chk}${data}"
8290
else:
8391
nxc_logger.fail(f"Skipping {decoded_tgs['ticket']['sname']['name-string'][0]}/{decoded_tgs['ticket']['sname']['name-string'][1]} due to incompatible e-type {decoded_tgs['ticket']['enc-part']['etype']:d}")
8492

0 commit comments

Comments
 (0)