Exemple #1
0
    def add_comment(self, id):
        if comments_enabled():
            f = File(get_or_404(current_user.files, _id=id))

            if current_user.has_permission('add_probable_name'):
                probable_name = request.form.get('probable_name')
            else:
                probable_name = None

            comment = request.form.get('comment')
            analysis_id = request.form.get('analysis')
            notify = request.form.get('notify')

            if comment:
                # If there is an analysis ID, make sure it is accessible
                if analysis_id:
                    get_or_404(current_user.analyses, _id=analysis_id)

                f.add_comment(current_user['_id'], comment, analysis_id, probable_name)
                if notify:
                    self.notify_new_comment(f, analysis_id, current_user['_id'], comment)

            else:
                flash('Comment should not be empty', 'danger')

        return redirect(request.referrer)
Exemple #2
0
    def default_sharing(self, id):
        """Change a user's default sharing.

        .. :quickref: User; Change default sharing

        When used on another user account, requires the `manage_users` permission.

        :param id: user id.

        :>json User user: modified user.
        """
        self.ensure_permission(id)

        user = User(get_or_404(User.get_collection(), _id=id))
        groups = request.form.get('groups', '').split(',')

        for group in groups:
            if group in user['groups']:
                break
        else:
            flash('You have to at least keep one of your groups.', 'danger')
            return redirect(request.referrer)

        user.update_value('default_sharing', groups)

        return redirect({'user': clean_users(user)}, request.referrer)
Exemple #3
0
    def get(self, id):
        """Get a user.

        .. :quickref: User; Get a user

        The user is returned in the ``user`` field.

        :param id: user id

        :>json ObjectId _id: user's ObjectId.
        :>json string name: full name.
        :>json string: email address.
        :>json boolean enabled: ``True`` if the user is enabled.
        :>json list groups: list of groups the user belongs to.
        :>json list default_sharing: list of groups used by the user as default sharing preferences.
        :>json list permissions: list of user's permissions
        """
        self.ensure_permission(id)
        user = User(get_or_404(User.get_collection(), _id=id))

        return render(
            {
                'user': clean_users(user),
                'permissions': dispatcher.permissions
            }, 'users/profile.html')
Exemple #4
0
    def change_type(self, id):
        f = File(get_or_404(current_user.files, _id=id))
        new_type = request.form.get('type')

        f.update_value("type", new_type)

        return redirect(request.referrer)
Exemple #5
0
    def update(self, id):
        """Update a user.

        .. :quickref: User; Update existing user

        Requires the `manage_users` permission.

        When succesful, the new user will be returned in the ``user`` field.
        Otherwise, an ``errors`` field will list errors.

        :form name: full name
        :form email: email address
        :form groups: comma-delimited list of groups
        :form permission_VALUE: specify a value different than ``0`` or ``False``
            for all permissions the user should have.
        """
        name = request.form.get('name')
        email = request.form.get('email').lower()
        groups = [g for g in request.form.get('groups', '').split(',') if g]

        user = User(get_or_404(User.get_collection(), _id=id))

        if not self._valid_form(name, email, groups, user['email']):
            return validation_error()

        user['name'] = name
        user['email'] = email
        user['groups'] = groups
        user['permissions'] = self.get_permissions(user['permissions'])
        user.save()

        return redirect({'user': clean_users(user)},
                        url_for('UsersView:get', id=user['_id']))
Exemple #6
0
    def get(self, id):
        """Get the object with `id`.

        .. :quickref: File; Get an object

        Resulting object is in the ``file`` field.

        :param id: id of the object.

        :>json dict _id: ObjectId dict.
        :>json string md5: MD5 hash.
        :>json string sha1: SHA1 hash.
        :>json string sha256: SHA256 hash.
        :>json string type: FAME type.
        :>json string mime: mime type.
        :>json string detailed_type: detailed type.
        :>json list groups: list of groups (as strings) that have access to this file.
        :>json list owners: list of groups (as strings) that submitted this file.
        :>json list probable_names: list of probable names (as strings).
        :>json list analysis: list of analyses' ObjectIds.
        :>json list parent_analyses: list of analyses (as ObjectIds) that extracted this object.
        :>json dict antivirus: dict with antivirus names as keys.
        """
        file = {'file': enrich_comments(clean_files(get_or_404(current_user.files, _id=id)))}
        return return_file(file)
Exemple #7
0
    def configuration(self, id):
        """Configure a named configuration.

        .. :quickref: Module; Configure a named configuration

        Requires the `manage_modules` permission.

        For each configuration available, you should set the value in a form
        parameter named ``config_NAME``. For boolean values, any value not ``0``
        or ``False`` is considered to be ``True``.

        If successful, will return the named configuration in ``config``.
        Otherwise, errors will be available in ``errors``.

        :param id: id of the named configuration.
        """
        config = Config(get_or_404(Config.get_collection(), _id=id))

        if request.method == "POST":
            errors = update_config(config['config'])
            if errors is not None:
                return errors

            config.save()
            dispatcher.reload()
            return redirect({'config': config}, url_for('ModulesView:index'))
        else:
            return render({'config': config}, 'modules/configuration.html')
Exemple #8
0
    def download_support_file(self, id, module, filename):
        """Download a support file.

        .. :quickref: Analysis; Download a support file.

        :param id: id of the analysis.
        :param module: name of the module.
        :param filename: name of the file to download.
        """
        analysis = get_or_404(current_user.analyses, _id=id)

        filepath = os.path.join(fame_config.storage_path, 'support_files',
                                module, str(analysis['_id']),
                                secure_filename(filename))
        if os.path.isfile(filepath):
            return file_download(filepath)
        else:
            # This code is here for compatibility
            # with older analyses
            filepath = os.path.join(fame_config.storage_path, 'support_files',
                                    str(analysis['_id']),
                                    secure_filename(filename))
            if os.path.isfile(filepath):
                return file_download(filepath)
            else:
                abort(404)
Exemple #9
0
    def add_group(self, id):
        f = File(get_or_404(current_user.files, _id=id))
        group = request.form.get('group')

        f.add_groups([group])

        return redirect(request.referrer)
Exemple #10
0
    def download(self, id):
        """Download the file with `id`.

        .. :quickref: File; Download a file

        :param id: id of the file to download.
        """
        f = File(get_or_404(current_user.files, _id=id))
        return file_download(f['filepath'])
Exemple #11
0
    def get(self, id):
        """Get the analysis with `id`.

        .. :quickref: Analysis; Get an analysis

        Resulting object is in the ``analysis`` field.

        :param id: id of the analysis.

        :>json dict _id: ObjectId dict.
        :>json dict analyst: analyst's ObjectId.
        :>json dict date: date dict.
        :>json list executed_modules: list of executed modules.
        :>json list pending_modules: list of pending modules.
        :>json list waiting_modules: list of waiting modules.
        :>json list canceled_modules: list of canceled modules.
        :>json list executed_modules: list of executed modules.
        :>json string module: the name of the target module.
        :>json string status: status of the analysis (one of `pending`, `running`, `finished` or `error`).
        :>json list tags: the list of tags.
        :>json list probable_names: the list of probable names.
        :>json list iocs: list of dict describing observables.
        :>json dict results: detailed results for each module, with the module name being the key.
        :>json dict generated_files: a dict of generated files, the key being the file type.
        :>json list extracted_files: a list of extracted files.
        :>json dict support_files: a dict of support files, the key being the module name.
        """
        analysis = {
            'analysis':
            clean_analyses(get_or_404(current_user.analyses, _id=id))
        }
        file = current_user.files.find_one(
            {'_id': analysis['analysis']['file']})
        analysis['analysis']['file'] = clean_files(file)
        ti_modules = [
            m.name for m in dispatcher.get_threat_intelligence_modules()
        ]
        av_modules = [m.name for m in dispatcher.get_antivirus_modules()]

        if 'extracted_files' in analysis['analysis']:
            files = []
            for id in analysis['analysis']['extracted_files']:
                files.append(current_user.files.find_one({'_id': id}))
            analysis['analysis']['extracted_files'] = clean_files(files)

        modules = dict()
        for module in ModuleInfo.get_collection().find():
            modules[module['name']] = ModuleInfo(module)

        return render(analysis,
                      'analyses/show.html',
                      ctx={
                          'analysis': analysis,
                          'modules': modules,
                          'av_modules': av_modules,
                          'ti_modules': ti_modules
                      })
Exemple #12
0
    def get_sha1(self, sha1):
        """Get the object with `sha1`.

        .. :quickref: File; Get an object by SHA1

        :param sha1: sha1 of the object.

        :>json file file: list of files (see :http:get:`/files/(id)` for details on the format of a file).
        """
        file = {'file': clean_files(get_or_404(current_user.files, sha1=sha1))}
        return return_file(file)
Exemple #13
0
    def refresh_iocs(self, id):
        """Refresh IOCs with Threat Intel modules

        .. :quickref: Analysis; Refresh IOCs with Threat Intel modules.

        :param id: id of the analysis.
        """
        analysis = Analysis(get_or_404(current_user.analyses, _id=id))
        analysis.refresh_iocs()

        return redirect(analysis, url_for('AnalysesView:get', id=analysis["_id"]))
Exemple #14
0
    def get_md5(self, md5):
        """Get the object with `md5`.

        .. :quickref: File; Get an object by MD5

        :param md5: md5 of the object.

        :>json file file: list of files (see :http:get:`/files/(id)` for details on the format of a file).
        """
        file = {'file': clean_files(get_or_404(current_user.files, md5=md5))}
        return return_file(file)
Exemple #15
0
    def get_sha256(self, sha256):
        """Get the object with `sha256`.

        .. :quickref: File; Get an object by SHA256

        :param sha256: sha256 of the object.

        :>json file file: list of files (see :http:get:`/files/(id)` for details on the format of a file).
        """
        file = {'file': enrich_comments(clean_files(get_or_404(current_user.files, sha256=sha256)))}
        return return_file(file)
Exemple #16
0
    def remove_group(self, id):
        f = File(get_or_404(current_user.files, _id=id))

        group = request.form.get('group')

        if group in f['owners']:
            flash('This group submitted this file themselves. You cannot neuralize them.', 'danger')
        else:
            f.remove_group(group)

        return redirect(request.referrer)
Exemple #17
0
def update_queue(module, new_queue):
    if new_queue == '':
        flash('queue cannot be empty', 'danger')
        return validation_error()
    elif module['queue'] != new_queue:
        module.update_setting_value('queue', new_queue)
        updates = Internals(
            get_or_404(Internals.get_collection(), name="updates"))
        updates.update_value("last_update", time())

        flash(
            'Workers will reload once they are done with their current tasks',
            'success')
Exemple #18
0
    def download_support_file(self, id, filename):
        """Download a support file.

        .. :quickref: Analysis; Download a support file.

        :param id: id of the analysis.
        :param filename: name of the file to download.
        """
        analysis = get_or_404(current_user.analyses, _id=id)
        filepath = os.path.join(fame_config.storage_path, 'support_files',
                                str(analysis['_id']),
                                secure_filename(filename))

        return file_download(filepath)
Exemple #19
0
    def get_md5(self, md5):
        """Get the object with `md5`.

        .. :quickref: File; Get an object by MD5

        :param md5: md5 of the object.

        :>json file file: list of files (see :http:get:`/files/(id)` for details on the format of a file).
        """
        return return_file({
            "file":
            enrich_comments(
                clean_files(get_or_404(current_user.files, md5=md5.lower())))
        })
Exemple #20
0
    def get_file(self, id, filehash):
        analysis = Analysis(get_or_404(current_user.analyses, _id=id))

        for file_type in analysis['generated_files']:
            for filepath in analysis['generated_files'][file_type]:
                filepath = filepath.encode('utf-8')
                if filehash == md5(filepath).hexdigest():
                    return file_download(filehash)

        filepath = analysis._file['filepath'].encode('utf-8')
        if filehash == md5(filepath).hexdigest():
            return file_download(analysis.get_main_file())

        return abort(404)
Exemple #21
0
    def add_comment(self, id):
        if comments_enabled():
            f = File(get_or_404(current_user.files, _id=id))

            if current_user.has_permission("add_probable_name"):
                probable_name = request.form.get("probable_name")
            else:
                probable_name = None

            comment = request.form.get("comment")
            analysis_id = request.form.get("analysis")
            notify = request.form.get("notify")

            if comment:
                # If there is an analysis ID, make sure it is accessible
                if analysis_id:
                    get_or_404(current_user.analyses, _id=analysis_id)

                f.add_comment(current_user["_id"], comment, analysis_id,
                              probable_name, notify)
            else:
                flash("Comment should not be empty", "danger")

        return redirect(request.referrer)
Exemple #22
0
    def enable(self, id):
        """Enable a module

        .. :quickref: Module; Enable a module

        Requires the `manage_modules` permission.

        If successful, will return the module in ``module``.
        Otherwise, errors will be available in ``errors``.

        :param id: id of the module to enable.
        """
        module = ModuleInfo(get_or_404(ModuleInfo.get_collection(), _id=id))

        if 'error' in module:
            flash(
                "Cannot enable '{}' because of errors installing dependencies."
                .format(module['name']), 'danger')
            return validation_error(url_for('ModulesView:index'))

        # See if module is properly configured
        module_class = get_class(module['path'], module['class'])
        module_class.info = module
        try:
            module_class()
        except MissingConfiguration as e:
            if e.name:
                flash(
                    "You must configure '{}' before trying to enable '{}'".
                    format(e.name, module['name']), 'warning')
                return validation_error(
                    url_for('ModulesView:configuration', id=e.id))
            else:
                flash(
                    "You must configure '{}' before trying to enable it.".
                    format(module['name']), 'warning')
                return validation_error(
                    url_for('ModulesView:configure', id=module['_id']))

        module.update_value('enabled', True)
        dispatcher.reload()

        readme = module.get_readme()
        if readme:
            flash(readme, 'persistent')

        return redirect({'module': clean_modules(module)},
                        url_for('ModulesView:index'))
Exemple #23
0
    def repository_delete(self, id):
        """Delete a repository

        .. :quickref: Module; Delete repository

        Requires the `manage_modules` permission.
        Returns "ok".

        :param id: id of the repository.
        """
        repository = Repository(get_or_404(Repository.get_collection(),
                                           _id=id))
        repository.delete()
        dispatcher.reload()

        return redirect('ok', url_for('ModulesView:index'))
Exemple #24
0
    def disable(self, id):
        """Disable a module

        .. :quickref: Module; Disable a module

        Requires the `manage_modules` permission.

        :param id: id of the module to disable.
        :>json Module module: resulting module.
        """
        module = ModuleInfo(get_or_404(ModuleInfo.get_collection(), _id=id))
        module.update_value('enabled', False)
        dispatcher.reload()

        return redirect({'module': clean_modules(module)},
                        url_for('ModulesView:index'))
Exemple #25
0
    def disable(self, id):
        """Disable a user.

        .. :quickref: User; Disable a user

        Requires the `manage_users` permission.

        :param id: user id.

        :>json User user: modified user.
        """
        user = User(get_or_404(User.get_collection(), _id=id))
        user.update_value('enabled', False)

        return redirect({'user': clean_users(user)},
                        url_for('UsersView:index'))
Exemple #26
0
    def _save_analysis_file(self, id, path):
        file = request.files['file']
        analysis = Analysis(get_or_404(current_user.analyses, _id=id))
        dirpath = os.path.join(path, str(analysis['_id']))
        filepath = os.path.join(dirpath, secure_filename(file.filename))

        # Create parent dirs if they don't exist
        try:
            os.makedirs(dirpath)
        except:
            pass

        with open(filepath, "wb") as fd:
            copyfileobj(file.stream, fd)

        return filepath
Exemple #27
0
    def repository_update(self, id):
        """Update a repository

        .. :quickref: Module; Update repository

        Requires the `manage_modules` permission.

        :param id: id of the repository.

        :>json Repository repository: the repository.
        """
        repository = Repository(get_or_404(Repository.get_collection(),
                                           _id=id))
        repository.pull()

        return redirect({'repository': clean_repositories(repository)},
                        url_for('ModulesView:index'))
Exemple #28
0
    def reset_api(self, id):
        """Reset a user's API key.

        .. :quickref: User; Reset API key

        When used on another user account, requires the `manage_users` permission.

        :param id: user id.

        :>json User user: modified user.
        """
        self.ensure_permission(id)

        user = User(get_or_404(User.get_collection(), _id=id))
        user.update_value('api_key', User.generate_api_key())

        return redirect({'user': clean_users(user)}, request.referrer)
Exemple #29
0
    def get(self, id):
        """Get the object with `id`.

        .. :quickref: File; Get an object

        Resulting object is in the ``file`` field.

        :param id: id of the object.

        :>json dict _id: ObjectId dict.
        :>json string md5: MD5 hash.
        :>json string sha1: SHA1 hash.
        :>json string sha256: SHA256 hash.
        :>json string type: FAME type.
        :>json string mime: mime type.
        :>json string detailed_type: detailed type.
        :>json list groups: list of groups (as strings) that have access to this file.
        :>json list owners: list of groups (as strings) that submitted this file.
        :>json list probable_names: list of probable names (as strings).
        :>json list analysis: list of analyses' ObjectIds.
        :>json list parent_analyses: list of analyses (as ObjectIds) that extracted this object.
        :>json dict antivirus: dict with antivirus names as keys.
        """
        file = {'file': clean_files(get_or_404(current_user.files, _id=id))}
        analyses = list(
            current_user.analyses.find(
                {'_id': {
                    '$in': file['file']['analysis']
                }}))
        file['av_modules'] = [
            m.name for m in dispatcher.get_antivirus_modules()
        ]

        for analysis in analyses:
            if 'analyst' in analysis:
                analyst = store.users.find_one({'_id': analysis['analyst']})
                analysis['analyst'] = clean_users(analyst)

        file['file']['analysis'] = clean_analyses(analyses)
        return render(file,
                      'files/show.html',
                      ctx={
                          'data': file,
                          'options': dispatcher.options
                      })
Exemple #30
0
    def reload(self):
        """Reload the workers

        .. :quickref: Module; Reload workers

        Requires the `manage_modules` permission.

        Returns "ok".
        """
        for repository in Repository.get_collection().find():
            dispatcher.update_modules(Repository(repository))

        updates = Internals(
            get_or_404(Internals.get_collection(), name="updates"))
        updates.update_value("last_update", time())

        flash(
            'Workers will reload once they are done with their current tasks',
            'success')

        return redirect('ok', url_for('ModulesView:index'))