Пример #1
0
    def testExpandUsersHomeDirectoryPath(self):
        """Tests the ExpandUsersHomeDirectoryPath function."""
        user_account_artifact1 = artifacts.UserAccountArtifact(
            user_directory='C:\\Users\\Test1', username='******')
        user_account_artifact2 = artifacts.UserAccountArtifact(
            user_directory='%SystemDrive%\\Users\\Test2', username='******')

        path = '%%users.homedir%%\\Profile'
        expanded_paths = path_helper.PathHelper.ExpandUsersHomeDirectoryPath(
            path, '\\', [user_account_artifact1, user_account_artifact2])

        expected_expanded_paths = [
            '\\Users\\Test1\\Profile', '\\Users\\Test2\\Profile'
        ]
        self.assertEqual(expanded_paths, expected_expanded_paths)

        path = 'C:\\Temp'
        expanded_paths = path_helper.PathHelper.ExpandUsersHomeDirectoryPath(
            path, '\\', [user_account_artifact1, user_account_artifact2])

        expected_expanded_paths = ['\\Temp']
        self.assertEqual(expanded_paths, expected_expanded_paths)

        path = 'C:\\Temp\\%%users.homedir%%'
        expanded_paths = path_helper.PathHelper.ExpandUsersHomeDirectoryPath(
            path, '\\', [user_account_artifact1, user_account_artifact2])

        expected_expanded_paths = ['\\Temp\\%%users.homedir%%']
        self.assertEqual(expanded_paths, expected_expanded_paths)
Пример #2
0
  def testExpandUsersVariablePathSegments(self):
    """Tests the _ExpandUsersVariablePathSegments function."""
    user_account_artifact1 = artifacts.UserAccountArtifact(
        identifier='1000', path_separator='\\',
        user_directory='C:\\Users\\Test1', username='******')
    user_account_artifact2 = artifacts.UserAccountArtifact(
        identifier='1001', path_separator='\\',
        user_directory='%SystemDrive%\\Users\\Test2', username='******')

    user_accounts = [user_account_artifact1, user_account_artifact2]

    path_segments = ['%%users.appdata%%', 'Microsoft', 'Windows', 'Recent']
    expanded_paths = path_helper.PathHelper._ExpandUsersVariablePathSegments(
        path_segments, '\\', user_accounts)

    expected_expanded_paths = [
        '\\Users\\Test1\\AppData\\Roaming\\Microsoft\\Windows\\Recent',
        '\\Users\\Test1\\Application Data\\Microsoft\\Windows\\Recent',
        '\\Users\\Test2\\AppData\\Roaming\\Microsoft\\Windows\\Recent',
        '\\Users\\Test2\\Application Data\\Microsoft\\Windows\\Recent']
    self.assertEqual(sorted(expanded_paths), expected_expanded_paths)

    path_segments = ['C:', 'Windows']
    expanded_paths = path_helper.PathHelper._ExpandUsersVariablePathSegments(
        path_segments, '\\', user_accounts)

    expected_expanded_paths = ['\\Windows']
    self.assertEqual(sorted(expanded_paths), expected_expanded_paths)
Пример #3
0
    def testExpandUsersHomeDirectoryPathSegments(self):
        """Tests the _ExpandUsersHomeDirectoryPathSegments function."""
        user_account_artifact1 = artifacts.UserAccountArtifact(
            user_directory='/home/Test1', username='******')
        user_account_artifact2 = artifacts.UserAccountArtifact(
            user_directory='/Users/Test2', username='******')
        user_account_artifact3 = artifacts.UserAccountArtifact(
            username='******')

        user_accounts = [
            user_account_artifact1, user_account_artifact2,
            user_account_artifact3
        ]

        path_segments = ['%%users.homedir%%', '.bashrc']
        expanded_paths = (
            path_helper.PathHelper._ExpandUsersHomeDirectoryPathSegments(
                path_segments, '/', user_accounts))

        expected_expanded_paths = [
            '/home/Test1/.bashrc', '/Users/Test2/.bashrc'
        ]
        self.assertEqual(expanded_paths, expected_expanded_paths)

        user_account_artifact1 = artifacts.UserAccountArtifact(
            path_separator='\\',
            user_directory='C:\\Users\\Test1',
            username='******')
        user_account_artifact2 = artifacts.UserAccountArtifact(
            path_separator='\\',
            user_directory='%SystemDrive%\\Users\\Test2',
            username='******')

        user_accounts = [user_account_artifact1, user_account_artifact2]

        path_segments = ['%%users.userprofile%%', 'Profile']
        expanded_paths = (
            path_helper.PathHelper._ExpandUsersHomeDirectoryPathSegments(
                path_segments, '\\', user_accounts))

        expected_expanded_paths = [
            '\\Users\\Test1\\Profile', '\\Users\\Test2\\Profile'
        ]
        self.assertEqual(expanded_paths, expected_expanded_paths)

        path_segments = ['C:', 'Temp']
        expanded_paths = (
            path_helper.PathHelper._ExpandUsersHomeDirectoryPathSegments(
                path_segments, '\\', user_accounts))

        expected_expanded_paths = ['\\Temp']
        self.assertEqual(expanded_paths, expected_expanded_paths)

        path_segments = ['C:', 'Temp', '%%users.userprofile%%']
        expanded_paths = (
            path_helper.PathHelper._ExpandUsersHomeDirectoryPathSegments(
                path_segments, '\\', user_accounts))

        expected_expanded_paths = ['\\Temp\\%%users.userprofile%%']
        self.assertEqual(expanded_paths, expected_expanded_paths)
Пример #4
0
    def _CreateTestKnowledgeBaseWindows(self):
        """Creates a knowlege base for testing Windows paths.

    Creates a knowledge base with 2 user accounts.

    Returns:
      KnowledgeBase: knowledge base.
    """
        knowledge_base = knowledge_base_engine.KnowledgeBase()

        test_user1 = artifacts.UserAccountArtifact(
            identifier='1000',
            path_separator='\\',
            user_directory='C:\\Users\\testuser1',
            username='******')
        knowledge_base.AddUserAccount(test_user1)

        test_user2 = artifacts.UserAccountArtifact(
            identifier='1001',
            path_separator='\\',
            user_directory='%SystemDrive%\\Users\\testuser2',
            username='******')
        knowledge_base.AddUserAccount(test_user2)

        return knowledge_base
Пример #5
0
    def testBuildFindSpecsWithFileSystem(self):
        """Tests the BuildFindSpecs function for file type artifacts."""
        knowledge_base = knowledge_base_engine.KnowledgeBase()

        testuser1 = artifacts.UserAccountArtifact(
            identifier='1000',
            user_directory='C:\\\\Users\\\\testuser1',
            username='******')
        knowledge_base.AddUserAccount(testuser1)

        testuser2 = artifacts.UserAccountArtifact(
            identifier='1001',
            user_directory='C:\\\\Users\\\\testuser2',
            username='******')
        knowledge_base.AddUserAccount(testuser2)

        test_filter_file = self._CreateTestArtifactDefinitionsFilterHelper(
            ['TestFiles', 'TestFiles2'], knowledge_base)

        environment_variable = artifacts.EnvironmentVariableArtifact(
            case_sensitive=False, name='SystemDrive', value='C:')

        test_filter_file.BuildFindSpecs(
            environment_variables=[environment_variable])
        find_specs_per_source_type = knowledge_base.GetValue(
            test_filter_file.KNOWLEDGE_BASE_VALUE)
        find_specs = find_specs_per_source_type.get(
            artifact_types.TYPE_INDICATOR_FILE, [])

        # Should build 15 FindSpec entries.
        self.assertEqual(len(find_specs), 15)

        # Last find_spec should contain the testuser2 profile path.
        location_segments = sorted(
            [find_spec._location_segments for find_spec in find_specs])
        path_segments = [
            'Users', 'testuser2', 'Documents', 'WindowsPowerShell',
            'profile\\.ps1'
        ]
        self.assertEqual(location_segments[2], path_segments)

        path_spec = path_spec_factory.Factory.NewPathSpec(
            dfvfs_definitions.TYPE_INDICATOR_OS, location='.')
        file_system = path_spec_resolver.Resolver.OpenFileSystem(path_spec)
        searcher = file_system_searcher.FileSystemSearcher(
            file_system, path_spec)

        path_spec_generator = searcher.Find(find_specs=find_specs)
        self.assertIsNotNone(path_spec_generator)

        path_specs = list(path_spec_generator)

        # Two evtx, one symbolic link to evtx, one AUTHORS, two filter_*.txt files,
        # total 6 path specifications.
        self.assertEqual(len(path_specs), 6)

        file_system.Close()
Пример #6
0
    def _ParseKey(self, mediator, registry_key, value_name):
        """Parses a Windows Registry key for a preprocessing attribute.

    Args:
      mediator (PreprocessMediator): mediates interactions between preprocess
          plugins and other components, such as storage and knowledge base.
      registry_key (dfwinreg.WinRegistryKey): Windows Registry key.
      value_name (str): name of the Windows Registry value or None if not
          specified.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
        user_account = artifacts.UserAccountArtifact(
            identifier=registry_key.name, path_separator='\\')

        registry_value = registry_key.GetValueByName('ProfileImagePath')
        if registry_value:
            profile_path = registry_value.GetDataAsObject()
            username = self._GetUsernameFromProfilePath(profile_path)

            user_account.user_directory = profile_path or None
            user_account.username = username or None

        try:
            mediator.AddUserAccount(user_account)
        except KeyError:
            mediator.ProducePreprocessingWarning(
                self.ARTIFACT_DEFINITION_NAME,
                ('Unable to add user account: "{0!s}" to knowledge '
                 'base').format(username))
Пример #7
0
  def _ParseFileObject(self, knowledge_base, file_object):
    """Parses a passwd file-like object.

    A passwd file consist of colon seperated values in the format:
    "username:password:uid:gid:full name:home directory:shell".

    Args:
      knowledge_base (KnowledgeBase): to fill with preprocessing information.
      file_object (dfvfs.FileIO): file-like object.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
    text_file_object = text_file.TextFile(file_object)

    try:
      reader = csv.reader(text_file_object, delimiter=b':')
    except csv.Error:
      raise errors.PreProcessFail(u'Unable to read: {0:s}.'.format(self._PATH))

    for row in reader:
      if len(row) < 7 or not row[0] or not row[2]:
        # TODO: add and store preprocessing errors.
        continue

      user_account = artifacts.UserAccountArtifact(
          identifier=row[2], username=row[0])
      user_account.group_identifier = row[3] or None
      user_account.full_name = row[4] or None
      user_account.user_directory = row[5] or None
      user_account.shell = row[6] or None

      # TODO: refactor the use of store number.
      user_account.store_number = 0
      knowledge_base.SetUserAccount(user_account)
Пример #8
0
    def _ParseKey(self, knowledge_base, registry_key, value_name):
        """Parses a Windows Registry key for a preprocessing attribute.

    Args:
      knowledge_base (KnowledgeBase): to fill with preprocessing information.
      registry_key (dfwinreg.WinRegistryKey): Windows Registry key.
      value_name (str): name of the Windows Registry value.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
        user_account = artifacts.UserAccountArtifact(
            identifier=registry_key.name)

        registry_value = registry_key.GetValueByName('ProfileImagePath')
        if registry_value:
            profile_path = registry_value.GetDataAsObject()
            username = self._GetUsernameFromProfilePath(profile_path)

            user_account.user_directory = profile_path or None
            user_account.username = username or None

        try:
            knowledge_base.AddUserAccount(user_account)
        except KeyError:
            # TODO: add and store preprocessing errors.
            pass
Пример #9
0
    def _ParseKey(self, knowledge_base, registry_key):
        """Parses a Windows Registry key for a preprocessing attribute.

    Args:
      knowledge_base (KnowledgeBase): to fill with preprocessing information.
      registry_key (WinRegistryKey): Windows Registry key.
    """
        for subkey in registry_key.GetSubkeys():
            if not subkey.name:
                # TODO: add and store preprocessing errors.
                continue

            user_account = artifacts.UserAccountArtifact(
                identifier=subkey.name)

            registry_value = subkey.GetValueByName(u'ProfileImagePath')
            if registry_value:
                profile_path = registry_value.GetDataAsObject()
                username = self._GetUsernameFromPath(profile_path)

                user_account.user_directory = profile_path or None
                user_account.username = username or None

            # TODO: refactor the use of store number.
            user_account.store_number = 0
            knowledge_base.SetUserAccount(user_account)
Пример #10
0
  def testGetAttributeNames(self):
    """Tests the GetAttributeNames function."""
    attribute_container = artifacts.UserAccountArtifact()

    expected_attribute_names = [
        'full_name', 'group_identifier', 'identifier', 'user_directory',
        'username']

    attribute_names = sorted(attribute_container.GetAttributeNames())
    self.assertEqual(attribute_names, expected_attribute_names)
Пример #11
0
  def testAddUserAccount(self):
    """Tests the AddUserAccount function."""
    knowledge_base_object = knowledge_base.KnowledgeBase()

    user_account = artifacts.UserAccountArtifact(
        identifier='1000', user_directory='/home/testuser',
        username='******')
    knowledge_base_object.AddUserAccount(user_account)

    with self.assertRaises(KeyError):
      knowledge_base_object.AddUserAccount(user_account)
Пример #12
0
    def testExpandUsersVariablePath(self):
        """Tests the ExpandUsersVariablePath function."""
        user_account_artifact1 = artifacts.UserAccountArtifact(
            user_directory='C:\\Users\\Test1', username='******')
        user_account_artifact2 = artifacts.UserAccountArtifact(
            user_directory='%SystemDrive%\\Users\\Test2', username='******')

        user_accounts = [user_account_artifact1, user_account_artifact2]

        path = '%%users.appdata%%\\Microsoft\\Windows\\Recent'
        expanded_paths = path_helper.PathHelper.ExpandUsersVariablePath(
            path, '\\', user_accounts)

        expected_expanded_paths = [
            '\\Users\\Test1\\AppData\\Roaming\\Microsoft\\Windows\\Recent',
            '\\Users\\Test1\\Application Data\\Microsoft\\Windows\\Recent',
            '\\Users\\Test2\\AppData\\Roaming\\Microsoft\\Windows\\Recent',
            '\\Users\\Test2\\Application Data\\Microsoft\\Windows\\Recent'
        ]
        self.assertEqual(sorted(expanded_paths), expected_expanded_paths)
Пример #13
0
  def testHasUserAccounts(self):
    """Tests the HasUserAccounts function."""
    knowledge_base_object = knowledge_base.KnowledgeBase()

    self.assertFalse(knowledge_base_object.HasUserAccounts())

    user_account = artifacts.UserAccountArtifact(
        identifier='1000', user_directory='/home/testuser',
        username='******')
    knowledge_base_object.AddUserAccount(user_account)

    self.assertTrue(knowledge_base_object.HasUserAccounts())
Пример #14
0
  def testUserAccountsProperty(self):
    """Tests the user accounts property."""
    knowledge_base_object = knowledge_base.KnowledgeBase()

    self.assertEqual(len(knowledge_base_object.user_accounts), 0)

    user_account = artifacts.UserAccountArtifact(
        identifier='1000', user_directory='/home/testuser',
        username='******')
    knowledge_base_object.AddUserAccount(user_account)

    self.assertEqual(len(knowledge_base_object.user_accounts), 1)
Пример #15
0
    def _ParseFileEntry(self, knowledge_base, file_entry):
        """Parses artifact file system data for a preprocessing attribute.

    Args:
      knowledge_base (KnowledgeBase): to fill with preprocessing information.
      file_entry (dfvfs.FileEntry): file entry that contains the artifact
          value data.

    Returns:
      bool: True if all the preprocessing attributes were found and
          the preprocessor plugin is done.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
        root_key = self._GetPlistRootKey(file_entry)
        if not root_key:
            location = getattr(file_entry.path_spec, 'location', '')
            raise errors.PreProcessFail(
                ('Unable to read: {0:s} plist: {1:s} with error: missing root '
                 'key.').format(self.ARTIFACT_DEFINITION_NAME, location))

        try:
            match = self._GetKeysDefaultEmpty(root_key, self._KEYS)
        except KeyError as exception:
            location = getattr(file_entry.path_spec, 'location', '')
            raise errors.PreProcessFail(
                'Unable to read: {0:s} plist: {1:s} with error: {2!s}'.format(
                    self.ARTIFACT_DEFINITION_NAME, location, exception))

        name = match.get('name', [None])[0]
        uid = match.get('uid', [None])[0]

        if not name or not uid:
            # TODO: add and store preprocessing errors.
            return False

        user_account = artifacts.UserAccountArtifact(identifier=uid,
                                                     username=name)
        user_account.group_identifier = match.get('gid', [None])[0]
        user_account.full_name = match.get('realname', [None])[0]
        user_account.shell = match.get('shell', [None])[0]
        user_account.user_directory = match.get('home', [None])[0]

        try:
            knowledge_base.AddUserAccount(user_account)
        except KeyError:
            # TODO: add and store preprocessing errors.
            pass

        return False
Пример #16
0
    def _ParseFileEntry(self, mediator, file_entry):
        """Parses artifact file system data for a preprocessing attribute.

    Args:
      mediator (PreprocessMediator): mediates interactions between preprocess
          plugins and other components, such as storage and knowledge base.
      file_entry (dfvfs.FileEntry): file entry that contains the artifact
          value data.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
        file_object = file_entry.GetFileObject()

        try:
            plist_file = plist.PlistFile()
            plist_file.Read(file_object)
            match = self._GetTopLevelKeys(plist_file.root_key, self._KEYS)

        except (IOError, plistlib.InvalidFileException) as exception:
            mediator.ProducePreprocessingWarning(
                self.ARTIFACT_DEFINITION_NAME,
                'Unable to read plist with error: {0!s}.'.format(exception))
            return

        name = match.get('name', [None])[0]
        uid = match.get('uid', [None])[0]

        if not name or not uid:
            mediator.ProducePreprocessingWarning(
                self.ARTIFACT_DEFINITION_NAME,
                'Missing name or user identifier')
            return

        user_account = artifacts.UserAccountArtifact(identifier=uid,
                                                     username=name)
        user_account.group_identifier = match.get('gid', [None])[0]
        user_account.full_name = match.get('realname', [None])[0]
        user_account.shell = match.get('shell', [None])[0]
        user_account.user_directory = match.get('home', [None])[0]

        try:
            mediator.AddUserAccount(user_account)
        except KeyError:
            mediator.ProducePreprocessingWarning(
                self.ARTIFACT_DEFINITION_NAME,
                'Unable to add user account: {0:s} to knowledge base.'.format(
                    name))
Пример #17
0
  def testGetSystemConfigurationArtifact(self):
    """Tests the GetSystemConfigurationArtifact function."""
    knowledge_base_object = knowledge_base.KnowledgeBase()

    hostname_artifact = artifacts.HostnameArtifact(name='myhost.mydomain')
    knowledge_base_object.SetHostname(hostname_artifact)

    user_account = artifacts.UserAccountArtifact(
        identifier='1000', user_directory='/home/testuser',
        username='******')
    knowledge_base_object.AddUserAccount(user_account)

    system_configuration = (
        knowledge_base_object.GetSystemConfigurationArtifact())
    self.assertIsNotNone(system_configuration)
    self.assertIsNotNone(system_configuration.hostname)
    self.assertEqual(system_configuration.hostname.name, 'myhost.mydomain')
Пример #18
0
  def testGetUsernameByIdentifier(self):
    """Tests the GetUsernameByIdentifier function."""
    knowledge_base_object = knowledge_base.KnowledgeBase()

    user_account = artifacts.UserAccountArtifact(
        identifier='1000', user_directory='/home/testuser',
        username='******')
    knowledge_base_object.AddUserAccount(user_account)

    usename = knowledge_base_object.GetUsernameByIdentifier('1000')
    self.assertEqual(usename, 'testuser')

    usename = knowledge_base_object.GetUsernameByIdentifier(1000)
    self.assertEqual(usename, '')

    usename = knowledge_base_object.GetUsernameByIdentifier('1001')
    self.assertEqual(usename, '')
Пример #19
0
  def testReadSystemConfigurationArtifact(self):
    """Tests the ReadSystemConfigurationArtifact function."""
    knowledge_base_object = knowledge_base.KnowledgeBase()

    system_configuration = artifacts.SystemConfigurationArtifact()
    system_configuration.hostname = artifacts.HostnameArtifact(
        name='myhost.mydomain')

    user_account = artifacts.UserAccountArtifact(
        identifier='1000', user_directory='/home/testuser',
        username='******')
    system_configuration.user_accounts.append(user_account)

    knowledge_base_object.ReadSystemConfigurationArtifact(system_configuration)

    hostname = knowledge_base_object.GetHostname()
    self.assertEqual(hostname, 'myhost.mydomain')
Пример #20
0
  def _SetUserAccounts(self, knowledge_base_object, users):
    """Sets the user accounts in the knowledge base.

    Args:
      knowledge_base_object (KnowledgeBase): knowledge base.
      users (list[dict[str,str])): users.
    """
    for user in users:
      identifier = user.get('sid', user.get('uid', None))
      if not identifier:
        continue

      user_account = artifacts.UserAccountArtifact(
          identifier=identifier, user_directory=user.get('path', None),
          username=user.get('name', None))

      knowledge_base_object.AddUserAccount(user_account)
Пример #21
0
  def _ParseFileData(self, knowledge_base, file_object):
    """Parses file content (data) for user account preprocessing attributes.

    Args:
      knowledge_base (KnowledgeBase): to fill with preprocessing information.
      file_object (dfvfs.FileIO): file-like object that contains the artifact
          value data.

    Returns:
      bool: True if all the preprocessing attributes were found and
          the preprocessor plugin is done.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
    result = False
    text_file_object = dfvfs_text_file.TextFile(file_object)

    try:
      reader = csv.reader(text_file_object, delimiter=b':')
    except csv.Error as exception:
      raise errors.PreProcessFail(
          'Unable to read: {0:s} with error: {1!s}'.format(
              self.ARTIFACT_DEFINITION_NAME, exception))

    for row in reader:
      if len(row) < 7 or not row[0] or not row[2]:
        # TODO: add and store preprocessing errors.
        continue

      user_account = artifacts.UserAccountArtifact(
          identifier=row[2], username=row[0])
      user_account.group_identifier = row[3] or None
      user_account.full_name = row[4] or None
      user_account.user_directory = row[5] or None
      user_account.shell = row[6] or None

      try:
        knowledge_base.AddUserAccount(user_account)
        result = True
      except KeyError:
        # TODO: add and store preprocessing errors.
        pass

    return result
Пример #22
0
  def testCopyToDict(self):
    """Tests the CopyToDict function."""
    attribute_container = artifacts.UserAccountArtifact(
        full_name='Full Name', group_identifier=1001, identifier=1000,
        user_directory='/home/username', username='******')

    self.assertEqual(attribute_container.username, 'username')

    expected_dict = {
        'full_name': 'Full Name',
        'group_identifier': 1001,
        'identifier': 1000,
        'user_directory': '/home/username',
        'username': '******'}

    test_dict = attribute_container.CopyToDict()

    self.assertEqual(test_dict, expected_dict)
Пример #23
0
  def testCopyToDict(self):
    """Tests the CopyToDict function."""
    user_account = artifacts.UserAccountArtifact(
        full_name=u'Full Name', group_identifier=1001, identifier=1000,
        user_directory=u'/home/username', username=u'username')

    self.assertEqual(user_account.username, u'username')

    expected_dict = {
        u'full_name': u'Full Name',
        u'group_identifier': 1001,
        u'identifier': 1000,
        u'user_directory': u'/home/username',
        u'username': u'username'}

    user_account_dict = user_account.CopyToDict()

    self.assertEqual(user_account_dict, expected_dict)
Пример #24
0
    def _ParsePlistFileEntry(self, knowledge_base, file_entry):
        """Parses an user account plist file.

    Args:
      knowledge_base (KnowledgeBase): to fill with preprocessing information.
      file_entry (dfvfs.FileNetry): file entry of the user account plist file.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
        root_key = self._GetPlistRootKey(file_entry)
        if not root_key:
            location = getattr(file_entry.path_spec, u'location', u'')
            raise errors.PreProcessFail(
                u'Missing root key in plist: {0:s}'.format(location))

        try:
            match = self._GetKeysDefaultEmpty(root_key, self._KEYS)
        except KeyError as exception:
            location = getattr(file_entry.path_spec, u'location', u'')
            raise errors.PreProcessFail(
                u'Unable to read user plist file: {0:s} with error: {1:s}'.
                format(location, exception))

        name = match.get(u'name', [None])[0]
        uid = match.get(u'uid', [None])[0]

        if not name or not uid:
            # TODO: add and store preprocessing errors.
            return

        user_account = artifacts.UserAccountArtifact(identifier=uid,
                                                     username=name)
        user_account.group_identifier = match.get(u'gid', [None])[0]
        user_account.full_name = match.get(u'realname', [None])[0]
        user_account.shell = match.get(u'shell', [None])[0]
        user_account.user_directory = match.get(u'home', [None])[0]

        try:
            knowledge_base.AddUserAccount(user_account)
        except KeyError:
            # TODO: add and store preprocessing errors.
            pass
Пример #25
0
  def _SetUserAccounts(self, knowledge_base_object, users):
    """Sets the user accounts in the knowledge base.

    Args:
      knowledge_base_object (KnowledgeBase): used to store information about
          users.
      users (list[dict[str, str])): users, for example [{'name': 'me',
        'sid': 'S-1', 'uid': '1'}]
    """
    for user in users:
      identifier = user.get('sid', user.get('uid', None))
      if not identifier:
        continue

      user_account_artifact = artifacts.UserAccountArtifact(
          identifier=identifier, user_directory=user.get('path', None),
          username=user.get('name', None))

      knowledge_base_object.AddUserAccount(user_account_artifact)
Пример #26
0
    def _ParseFileData(self, mediator, file_object):
        """Parses file content (data) for user account preprocessing attributes.

    Args:
      mediator (PreprocessMediator): mediates interactions between preprocess
          plugins and other components, such as storage and knowledge base.
      file_object (dfvfs.FileIO): file-like object that contains the artifact
          value data.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
        line_reader = line_reader_file.BinaryLineReader(file_object)

        try:
            reader = line_reader_file.BinaryDSVReader(line_reader, b':')
        except csv.Error as exception:
            raise errors.PreProcessFail(
                'Unable to read: {0:s} with error: {1!s}'.format(
                    self.ARTIFACT_DEFINITION_NAME, exception))

        for line_number, row in enumerate(reader):
            if len(row) < 7 or not row[0] or not row[2]:
                mediator.ProducePreprocessingWarning(
                    self.ARTIFACT_DEFINITION_NAME,
                    'Unsupported number of values in line: {0:d}.'.format(
                        line_number))
                continue

            try:
                username = row[0].decode('utf-8')
            except UnicodeDecodeError:
                mediator.ProducePreprocessingWarning(
                    self.ARTIFACT_DEFINITION_NAME,
                    'Unable to decode username.')
                continue

            try:
                identifier = row[2].decode('utf-8')
            except UnicodeDecodeError:
                mediator.ProducePreprocessingWarning(
                    self.ARTIFACT_DEFINITION_NAME,
                    'Unable to decode user identifier.')
                continue

            group_identifier = None
            if row[3]:
                try:
                    group_identifier = row[3].decode('utf-8')
                except UnicodeDecodeError:
                    mediator.ProducePreprocessingWarning(
                        self.ARTIFACT_DEFINITION_NAME,
                        'Unable to decode group identifier.')

            full_name = None
            if row[4]:
                try:
                    full_name = row[4].decode('utf-8')
                except UnicodeDecodeError:
                    mediator.ProducePreprocessingWarning(
                        self.ARTIFACT_DEFINITION_NAME,
                        'Unable to decode full name.')

            user_directory = None
            if row[5]:
                try:
                    user_directory = row[5].decode('utf-8')
                except UnicodeDecodeError:
                    mediator.ProducePreprocessingWarning(
                        self.ARTIFACT_DEFINITION_NAME,
                        'Unable to decode user directory.')

            shell = None
            if row[6]:
                try:
                    shell = row[6].decode('utf-8')
                except UnicodeDecodeError:
                    mediator.ProducePreprocessingWarning(
                        self.ARTIFACT_DEFINITION_NAME,
                        'Unable to decode shell.')

            user_account = artifacts.UserAccountArtifact(identifier=identifier,
                                                         username=username)
            user_account.group_identifier = group_identifier
            user_account.full_name = full_name
            user_account.user_directory = user_directory
            user_account.shell = shell

            try:
                mediator.AddUserAccount(user_account)
            except KeyError as exception:
                mediator.ProducePreprocessingWarning(
                    self.ARTIFACT_DEFINITION_NAME,
                    'Unable to add user account with error: {0!s}'.format(
                        exception))
Пример #27
0
    def _ParseFileData(self, knowledge_base, file_object):
        """Parses file content (data) for user account preprocessing attributes.

    Args:
      knowledge_base (KnowledgeBase): to fill with preprocessing information.
      file_object (dfvfs.FileIO): file-like object that contains the artifact
          value data.

    Raises:
      errors.PreProcessFail: if the preprocessing fails.
    """
        line_reader = line_reader_file.BinaryLineReader(file_object)

        try:
            reader = line_reader_file.BinaryDSVReader(line_reader, b':')
        except csv.Error as exception:
            raise errors.PreProcessFail(
                'Unable to read: {0:s} with error: {1!s}'.format(
                    self.ARTIFACT_DEFINITION_NAME, exception))

        for row in reader:
            if len(row) < 7 or not row[0] or not row[2]:
                # TODO: add and store preprocessing errors.
                continue

            try:
                username = row[0].decode('utf-8')
            except UnicodeDecodeError:
                # TODO: add and store preprocessing errors.
                logger.error('Unable to decode username.')
                continue

            try:
                identifier = row[2].decode('utf-8')
            except UnicodeDecodeError:
                # TODO: add and store preprocessing errors.
                logger.error('Unable to decode identifier.')
                continue

            group_identifier = None
            if row[3]:
                try:
                    group_identifier = row[3].decode('utf-8')
                except UnicodeDecodeError:
                    # TODO: add and store preprocessing errors.
                    logger.error('Unable to decode group identifier.')

            full_name = None
            if row[4]:
                try:
                    full_name = row[4].decode('utf-8')
                except UnicodeDecodeError:
                    # TODO: add and store preprocessing errors.
                    logger.error('Unable to decode full name.')

            user_directory = None
            if row[5]:
                try:
                    user_directory = row[5].decode('utf-8')
                except UnicodeDecodeError:
                    # TODO: add and store preprocessing errors.
                    logger.error('Unable to decode user directory.')

            shell = None
            if row[6]:
                try:
                    shell = row[6].decode('utf-8')
                except UnicodeDecodeError:
                    # TODO: add and store preprocessing errors.
                    logger.error('Unable to decode shell.')

            user_account = artifacts.UserAccountArtifact(identifier=identifier,
                                                         username=username)
            user_account.group_identifier = group_identifier
            user_account.full_name = full_name
            user_account.user_directory = user_directory
            user_account.shell = shell

            try:
                knowledge_base.AddUserAccount(user_account)
            except KeyError:
                # TODO: add and store preprocessing errors.
                pass
Пример #28
0
    def testBuildFindSpecsFromFileArtifact(self):
        """Tests the BuildFindSpecsFromFileArtifact function for file artifacts."""
        knowledge_base = knowledge_base_engine.KnowledgeBase()
        test_filter_file = self._CreateTestArtifactDefinitionsFilterHelper(
            [], knowledge_base)

        separator = '\\'
        user_accounts = []

        # Test expansion of environment variables.
        path_entry = '%%environ_systemroot%%\\test_data\\*.evtx'
        environment_variable = [
            artifacts.EnvironmentVariableArtifact(case_sensitive=False,
                                                  name='SystemRoot',
                                                  value='C:\\Windows')
        ]

        find_specs = test_filter_file.BuildFindSpecsFromFileArtifact(
            path_entry, separator, environment_variable, user_accounts)

        # Should build 1 find_spec.
        self.assertEqual(len(find_specs), 1)

        # Location segments should be equivalent to \Windows\test_data\*.evtx.
        if py2to3.PY_3:
            # Underscores are not escaped in regular expressions in supported versions
            # of Python 3. See https://bugs.python.org/issue2650.
            path_segments = ['Windows', 'test_data', '.*\\.evtx']
        else:
            path_segments = ['Windows', 'test\\_data', '.*\\.evtx']

        self.assertEqual(find_specs[0]._location_segments, path_segments)

        # Test expansion of globs.
        path_entry = '\\test_data\\**'
        find_specs = test_filter_file.BuildFindSpecsFromFileArtifact(
            path_entry, separator, environment_variable, user_accounts)

        # Glob expansion should by default recurse ten levels.
        self.assertEqual(len(find_specs), 10)

        # Last entry in find_specs list should be 10 levels of depth.
        if py2to3.PY_3:
            # Underscores are not escaped in regular expressions in supported versions
            # of Python 3. See https://bugs.python.org/issue2650
            path_segments = ['test_data']
        else:
            path_segments = ['test\\_data']

        path_segments.extend(
            ['.*', '.*', '.*', '.*', '.*', '.*', '.*', '.*', '.*', '.*'])

        self.assertEqual(find_specs[9]._location_segments, path_segments)

        # Test expansion of user home directories
        separator = '/'
        testuser1 = artifacts.UserAccountArtifact(
            user_directory='/homes/testuser1', username='******')
        testuser2 = artifacts.UserAccountArtifact(
            user_directory='/home/testuser2', username='******')
        user_accounts = [testuser1, testuser2]
        path_entry = '%%users.homedir%%/.thumbnails/**3'

        find_specs = test_filter_file.BuildFindSpecsFromFileArtifact(
            path_entry, separator, environment_variable, user_accounts)

        # Six total find specs should be created for testuser1 and testuser2.
        self.assertEqual(len(find_specs), 6)

        # Last entry in find_specs list should be testuser2 with a depth of 3
        path_segments = [
            'home', 'testuser2', '\\.thumbnails', '.*', '.*', '.*'
        ]
        self.assertEqual(find_specs[5]._location_segments, path_segments)

        # Test Windows path with profile directories and globs with a depth of 4.
        separator = '\\'
        testuser1 = artifacts.UserAccountArtifact(
            user_directory='\\Users\\\\testuser1', username='******')
        testuser2 = artifacts.UserAccountArtifact(
            user_directory='\\Users\\\\testuser2', username='******')
        user_accounts = [testuser1, testuser2]
        path_entry = '%%users.homedir%%\\AppData\\**4'

        find_specs = test_filter_file.BuildFindSpecsFromFileArtifact(
            path_entry, separator, environment_variable, user_accounts)

        # Eight find specs should be created for testuser1 and testuser2.
        self.assertEqual(len(find_specs), 8)

        # Last entry in find_specs list should be testuser2, with a depth of 4.
        path_segments = [
            'Users', 'testuser2', 'AppData', '.*', '.*', '.*', '.*'
        ]
        self.assertEqual(find_specs[7]._location_segments, path_segments)