Skip to content

Commit

Permalink
spn fix, multi hop cross domain auth added
Browse files Browse the repository at this point in the history
  • Loading branch information
SkelSec committed Feb 18, 2025
1 parent 2aacaa4 commit 53b5564
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
14 changes: 13 additions & 1 deletion minikerberos/aioclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -845,9 +845,21 @@ async def get_referral_ticket(self, target_domain, target_ip = None):
tgs, encpart, key = await self.get_TGS(crossrealm_spn)
logger.debug('Got referral ticket!')

for _ in range(10): # 10 is arbitrary, but I fail to imagine a scenario where we would need more than 10 referrals
if encpart['sname']['name-string'][1].upper() == target_domain.upper():
break

kirbi = Kirbi.from_ticketdata(tgs, encpart)
# otherwise we have to do this again with the new krbtgt
logger.debug('The referral ticket is not for the target domain, getting new referral ticket from %s' % encpart['sname']['name-string'][1])

kirbi = Kirbi.from_ticketdata(tgs, encpart)
newt = self.target.get_newtarget(encpart['sname']['name-string'][1], port=88)
newc = KerberosCredential.from_kirbi(kirbi, encoding='kirbi')
new_factory = KerberosClientFactory(newt, newc, newt.proxies)
newclient = new_factory.get_client()
tgs, encpart, key, new_factory = await newclient.get_referral_ticket(target_domain, target_ip)

kirbi = Kirbi.from_ticketdata(tgs, encpart)
target_addr = target_domain
if target_ip is not None:
target_addr = target_ip
Expand Down
10 changes: 9 additions & 1 deletion minikerberos/common/spn.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ def __init__(self):
self.username = None
self.service = None #the service we are trying to get a ticket for (eg. cifs/mssql...)
self.domain = None #the kerberos realm
self.port = None #the port the service is running on

# https://docs.microsoft.com/en-us/windows/desktop/ad/name-formats-for-unique-spns
#def from_spn(self):
Expand Down Expand Up @@ -45,16 +46,23 @@ def from_spn(s, override_realm:str = None):
raise Exception('The following SPN is incorrect without additionally setting the realm: %s' % s)
if override_realm is not None:
kt.domain = override_realm
if kt.domain.find(':') != -1:
kt.domain, kt.port = kt.domain.split(':', 1)
return kt

def get_principalname(self):
if self.service:
if self.port:
return [self.service, '%s:%s' % (self.username, self.port)]
return [self.service, self.username]
return [self.username]

def get_formatted_pname(self):
if self.service:
return '%s/%s@%s' % (self.service, self.username, self.domain)
if self.port:
return '%s/%s:%s@%s' % (self.service, self.username, self.port, self.domain)
else:
return '%s/%s@%s' % (self.service, self.username, self.domain)
return '%s@%s' % (self.username, self.domain)

def __str__(self):
Expand Down

0 comments on commit 53b5564

Please sign in to comment.