Skip to content

Commit

Permalink
Merge pull request fortra#1276 from SecureAuthCorp/ccache-refactor
Browse files Browse the repository at this point in the history
CCache refactor
  • Loading branch information
0xdeaddood authored Mar 11, 2022
2 parents 6042675 + 6e288da commit 1271d36
Show file tree
Hide file tree
Showing 16 changed files with 320 additions and 323 deletions.
26 changes: 4 additions & 22 deletions examples/GetUserSPNs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# Impacket - Collection of Python classes for working with network protocols.
#
# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.
# SECUREAUTH LABS. Copyright (C) 2022 SecureAuth Corporation. All rights reserved.
#
# This software is provided under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
Expand Down Expand Up @@ -34,7 +34,6 @@
from __future__ import print_function
import argparse
import logging
import os
import sys
from datetime import datetime
from binascii import hexlify, unhexlify
Expand Down Expand Up @@ -130,26 +129,9 @@ def getUnixTime(t):
return t

def getTGT(self):
try:
ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
except:
# No cache present
pass
else:
# retrieve user and domain information from CCache file if needed
if self.__domain == '':
domain = ccache.principal.realm['data']
else:
domain = self.__domain
logging.debug("Using Kerberos Cache: %s" % os.getenv('KRB5CCNAME'))
principal = 'krbtgt/%s@%s' % (domain.upper(), domain.upper())
creds = ccache.getCredential(principal)
if creds is not None:
TGT = creds.toTGT()
logging.debug('Using TGT from cache')
return TGT
else:
logging.debug("No valid credentials found in cache. ")
domain, _, TGT, _ = CCache.parseFile(self.__domain)
if TGT is not None:
return TGT

# No TGT in cache, request it
userName = Principal(self.__username, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
Expand Down
43 changes: 4 additions & 39 deletions examples/addcomputer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# Impacket - Collection of Python classes for working with network protocols.
#
# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.
# SECUREAUTH LABS. Copyright (C) 2022 SecureAuth Corporation. All rights reserved.
#
# This software is provided under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
Expand Down Expand Up @@ -40,7 +40,6 @@
import string
import random
import ssl
import os
from binascii import unhexlify


Expand Down Expand Up @@ -307,43 +306,9 @@ def LDAP3KerberosLogin(self, connection, user, password, domain='', lmhash='', n
if TGT is not None or TGS is not None:
useCache = False

targetName = 'ldap/%s' % self.__target
if useCache:
try:
ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
except Exception as e:
# No cache present
print(e)
pass
else:
# retrieve domain information from CCache file if needed
if domain == '':
domain = ccache.principal.realm['data'].decode('utf-8')
logging.debug('Domain retrieved from CCache: %s' % domain)

logging.debug('Using Kerberos Cache: %s' % os.getenv('KRB5CCNAME'))
principal = 'ldap/%s@%s' % (self.__target.upper(), domain.upper())

creds = ccache.getCredential(principal)
if creds is None:
# Let's try for the TGT and go from there
principal = 'krbtgt/%s@%s' % (domain.upper(), domain.upper())
creds = ccache.getCredential(principal)
if creds is not None:
TGT = creds.toTGT()
logging.debug('Using TGT from cache')
else:
logging.debug('No valid credentials found in cache')
else:
TGS = creds.toTGS(principal)
logging.debug('Using TGS from cache')

# retrieve user information from CCache file if needed
if user == '' and creds is not None:
user = creds['client'].prettyPrint().split(b'@')[0].decode('utf-8')
logging.debug('Username retrieved from CCache: %s' % user)
elif user == '' and len(ccache.principal.components) > 0:
user = ccache.principal.components[0]['data'].decode('utf-8')
logging.debug('Username retrieved from CCache: %s' % user)
domain, user, TGT, TGS = CCache.parseFile(domain, user, targetName)

# First of all, we need to get a TGT for the user
userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
Expand All @@ -357,7 +322,7 @@ def LDAP3KerberosLogin(self, connection, user, password, domain='', lmhash='', n
sessionKey = TGT['sessionKey']

if TGS is None:
serverName = Principal('ldap/%s' % self.__target, type=constants.PrincipalNameType.NT_SRV_INST.value)
serverName = Principal(targetName, type=constants.PrincipalNameType.NT_SRV_INST.value)
tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher,
sessionKey)
else:
Expand Down
29 changes: 9 additions & 20 deletions examples/getST.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# Impacket - Collection of Python classes for working with network protocols.
#
# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.
# SECUREAUTH LABS. Copyright (C) 2022 SecureAuth Corporation. All rights reserved.
#
# This software is provided under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
Expand Down Expand Up @@ -59,8 +59,7 @@
from impacket.krb5.ccache import CCache
from impacket.krb5.crypto import Key, _enctype_table, _HMACMD5, _AES256CTS, Enctype
from impacket.krb5.constants import TicketFlags, encodeFlags
from impacket.krb5.kerberosv5 import getKerberosTGS
from impacket.krb5.kerberosv5 import getKerberosTGT, sendReceive
from impacket.krb5.kerberosv5 import getKerberosTGS, getKerberosTGT, sendReceive
from impacket.krb5.types import Principal, KerberosTime, Ticket
from impacket.ntlm import compute_nthash
from impacket.winregistry import hexdump
Expand Down Expand Up @@ -618,25 +617,15 @@ def doS4U(self, tgt, cipher, oldSessionKey, sessionKey, nthash, aesKey, kdcHost)
return r, cipher, sessionKey, newSessionKey

def run(self):
tgt = None

# Do we have a TGT cached?
tgt = None
try:
ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
logging.debug("Using Kerberos Cache: %s" % os.getenv('KRB5CCNAME'))
principal = 'krbtgt/%s@%s' % (self.__domain.upper(), self.__domain.upper())
creds = ccache.getCredential(principal)
if creds is not None:
# ToDo: Check this TGT belogns to the right principal
TGT = creds.toTGT()
tgt, cipher, sessionKey = TGT['KDC_REP'], TGT['cipher'], TGT['sessionKey']
oldSessionKey = sessionKey
logging.info('Using TGT from cache')
else:
logging.debug("No valid credentials found in cache. ")
except:
# No cache present
pass
domain, _, TGT, _ = CCache.parseFile(self.__domain)

# ToDo: Check this TGT belogns to the right principal
if TGT is not None:
tgt, cipher, sessionKey = TGT['KDC_REP'], TGT['cipher'], TGT['sessionKey']
oldSessionKey = sessionKey

if tgt is None:
# Still no TGT
Expand Down
41 changes: 3 additions & 38 deletions examples/rbcd.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import ssl
import ldapdomaindump
from binascii import unhexlify
import os
from ldap3.protocol.formatters.formatters import format_sid

from impacket import version
Expand Down Expand Up @@ -92,43 +91,9 @@ def ldap3_kerberos_login(connection, target, user, password, domain='', lmhash='
if TGT is not None or TGS is not None:
useCache = False

target = 'ldap/%s' % target
if useCache:
try:
ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
except Exception as e:
# No cache present
print(e)
pass
else:
# retrieve domain information from CCache file if needed
if domain == '':
domain = ccache.principal.realm['data'].decode('utf-8')
logging.debug('Domain retrieved from CCache: %s' % domain)

logging.debug('Using Kerberos Cache: %s' % os.getenv('KRB5CCNAME'))
principal = 'ldap/%s@%s' % (target.upper(), domain.upper())

creds = ccache.getCredential(principal)
if creds is None:
# Let's try for the TGT and go from there
principal = 'krbtgt/%s@%s' % (domain.upper(), domain.upper())
creds = ccache.getCredential(principal)
if creds is not None:
TGT = creds.toTGT()
logging.debug('Using TGT from cache')
else:
logging.debug('No valid credentials found in cache')
else:
TGS = creds.toTGS(principal)
logging.debug('Using TGS from cache')

# retrieve user information from CCache file if needed
if user == '' and creds is not None:
user = creds['client'].prettyPrint().split(b'@')[0].decode('utf-8')
logging.debug('Username retrieved from CCache: %s' % user)
elif user == '' and len(ccache.principal.components) > 0:
user = ccache.principal.components[0]['data'].decode('utf-8')
logging.debug('Username retrieved from CCache: %s' % user)
domain, user, TGT, TGS = CCache.parseFile(domain, user, target)

# First of all, we need to get a TGT for the user
userName = Principal(user, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
Expand All @@ -142,7 +107,7 @@ def ldap3_kerberos_login(connection, target, user, password, domain='', lmhash='
sessionKey = TGT['sessionKey']

if TGS is None:
serverName = Principal('ldap/%s' % target, type=constants.PrincipalNameType.NT_SRV_INST.value)
serverName = Principal(target, type=constants.PrincipalNameType.NT_SRV_INST.value)
tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(serverName, domain, kdcHost, tgt, cipher,
sessionKey)
else:
Expand Down
Loading

0 comments on commit 1271d36

Please sign in to comment.