예제 #1
0
    def _store_preloaded_file(self, filepath=None, fd=None):
        if not filepath and not fd:
            raise ValueError(
                "Please provide either the path to the file or a file-like "
                "object containing the data.")

        if filepath and fd:
            self.log(
                "debug", "Please provide either the path to the file or a "
                "file-like object containing the data, not both."
                "Choosing the filepath for now.")

        if fame_config.remote:
            if filepath:
                response = send_file_to_remote(filepath, '/files/')
            else:
                response = send_file_to_remote(fd, '/files/')

            return File(response.json()['file'])
        else:
            if filepath:
                with open(filepath, 'rb') as f:
                    return File(filename=os.path.basename(filepath), stream=f)
            else:
                return File(filename=self._file['names'][0], stream=fd)
예제 #2
0
    def add_extracted_file(self, filepath, automatic_analysis=True):
        self.log('debug', u"Adding extracted file '{}'".format(filepath))

        fd = open(filepath, 'rb')
        filename = os.path.basename(filepath)
        f = File(filename=filename, stream=fd, create=False)

        if not f.existing:
            if fame_config.remote:
                response = send_file_to_remote(filepath, '/files/')
                f = File(response.json()['file'])
            else:
                f = File(filename=os.path.basename(filepath), stream=fd)

            # Automatically analyze extracted file if magic is enabled and module did not disable it
            if self.magic_enabled() and automatic_analysis:
                modules = None
                config = Config.get(name="extracted").get_values()
                if config is not None and "modules" in config:
                    modules = config["modules"].split()
                f.analyze(self['groups'], self['analyst'], modules,
                          self['options'])

        fd.close()

        self.append_to('extracted_files', f['_id'])
        f.add_parent_analysis(self)
예제 #3
0
    def __init__(self, values):
        self['status'] = self.STATUS_PENDING
        self['executed_modules'] = []
        self['pending_modules'] = []
        self['waiting_modules'] = []
        self['canceled_modules'] = []
        self['tags'] = []
        self['iocs'] = []
        self['results'] = {}
        self['generated_files'] = {}
        self['extracted_files'] = []
        self['support_files'] = {}
        self['logs'] = []
        self['extractions'] = []
        self['probable_names'] = []
        self['options'] = {}
        self['date'] = datetime.datetime.now()
        self['end_date'] = None
        self['groups'] = []
        self['analyst'] = []
        MongoDict.__init__(self, values)

        self._file = File(store.files.find_one({'_id': self['file']}))

        if '_id' not in self:
            self._init_threat_intelligence()
            self.save()

            if self['modules']:
                self.queue_modules(self['modules'])
            else:
                self._automatic()
예제 #4
0
파일: files.py 프로젝트: x0rzkov/fame
    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)
예제 #5
0
파일: files.py 프로젝트: x0rzkov/fame
    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)
예제 #6
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)
예제 #7
0
파일: files.py 프로젝트: x0rzkov/fame
    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'])
예제 #8
0
파일: analyses.py 프로젝트: ehrenb/fame
    def _get_object_to_analyze(self):
        file = request.files.get('file') or None
        url = request.form.get('url') or None
        hash = request.form.get('hash') or None

        f = None
        if file:
            f = File(filename=file.filename, stream=file.stream)
        elif url:
            stream = StringIO(url)
            f = File(filename='url', stream=stream)
            if not f.existing:
                f.update_value('type', 'url')
                f.update_value('names', [url])
        elif hash:
            f = File(hash=hash)
        else:
            flash('You have to submit a file, a URL or a hash', 'danger')
        return f
예제 #9
0
    def add_extracted_file(self, filepath):
        self.log('debug', "Adding extracted file '{}'".format(filepath))

        fd = open(filepath, 'rb')
        filename = os.path.basename(filepath)
        f = File(filename=filename, stream=fd, create=False)

        if not f.existing:
            if fame_config.remote:
                response = send_file_to_remote(filepath, '/files/')
                f = File(response.json()['file'])
            else:
                f = File(filename=os.path.basename(filepath), stream=fd)

            f.analyze(self['groups'], self['analyst'], None, self['options'])

        fd.close()

        self.append_to('extracted_files', f['_id'])
        f.add_parent_analysis(self)
예제 #10
0
파일: files.py 프로젝트: x0rzkov/fame
    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)
예제 #11
0
    def _get_object_to_analyze(self):
        file = request.files.get('file') or None
        url = request.form.get('url') or None
        hash = request.form.get('hash') or None

        f = None
        if file:
            f = File(filename=file.filename, stream=file.stream)
        elif url:
            stream = StringIO(url)
            f = File(filename='url', stream=stream)
            if not f.existing:
                f.update_value('type', 'url')
                f.update_value('names', [url])
        elif hash:
            config = Config.get(name="virustotal")
            if config:
                try:
                    config = config.get_values()

                    params = {'apikey': config.api_key, 'hash': hash}
                    response = requests.get(
                        'https://www.virustotal.com/vtapi/v2/file/download',
                        params=params)
                    if response.status_code == 403:
                        flash('This requires a valid API key.', 'danger')
                    elif response.status_code == 404:
                        flash('No file found with this hash.', 'danger')
                    elif response.status_code == 200:
                        f = File(filename='{}.bin'.format(hash),
                                 stream=StringIO(response.content))
                except MissingConfiguration:
                    flash("VirusTotal is not properly configured.", 'danger')
            else:
                flash(
                    "There seems to be a problem with your installation (no 'virustotal' configuration)",
                    'danger')
        else:
            flash('You have to submit a file, a URL or a hash', 'danger')

        return f
예제 #12
0
    def __init__(self, values):
        self['status'] = self.STATUS_PENDING
        self['executed_modules'] = []
        self['pending_modules'] = []
        self['waiting_modules'] = []
        self['canceled_modules'] = []
        self['preloading_modules'] = []
        self['tags'] = []
        self['iocs'] = []
        self['results'] = {}
        self['generated_files'] = {}
        self['extracted_files'] = []
        self['support_files'] = {}
        self['logs'] = []
        self['extractions'] = []
        self['probable_names'] = []
        self['options'] = {}
        self['date'] = datetime.datetime.now()
        self['end_date'] = None
        self['groups'] = []
        self['analyst'] = []
        MongoDict.__init__(self, values)

        self._file = File(store.files.find_one({'_id': self['file']}))

        if '_id' not in self:
            self._init_threat_intelligence()

            # Sort preloading and processing modules
            if self['modules']:
                processing = []
                for module_name in self['modules']:
                    module = dispatcher.get_module(module_name)
                    if module is not None:
                        if module.info['type'] == "Preloading":
                            self['preloading_modules'].append(module_name)
                        else:
                            processing.append(module_name)

                self['modules'] = processing

            self.save()

            if self['modules']:
                self.queue_modules(self['modules'])

            self._automatic()
            self.resume()
예제 #13
0
    def _store_preloaded_file(self, filepath=None, fd=None):
        if not filepath and not fd:
            raise ValueError(
                "Please provide either the path to the file or a file-like "
                "object containing the data.")

        if filepath and fd:
            self.log(
                "debug", "Please provide either the path to the file or a "
                "file-like object containing the data, not both. "
                "Chosing the file-like object for now.")
            response = send_file_to_remote(fd, '/files/')
        else:
            response = send_file_to_remote(filepath, '/files/')

        return File(json_util.loads(response.text)['file'])
예제 #14
0
파일: files.py 프로젝트: x0rzkov/fame
    def submit_to_av(self, id, module):
        """Submit a file to an Antivirus module.

        .. :quickref: File; Submit file to an antivirus module

        If succesful, the response will be ``"ok"``. Otherwise, it will be an
        error message.

        :param id: id of the file to submit.
        :param module: name of the module to submit the file to.
        """
        f = File(get_or_404(current_user.files, _id=id))

        for av_module in dispatcher.get_antivirus_modules():
            if av_module.name == module:
                av_module.submit(f['filepath'])
                f.update_value(['antivirus', module], True)
                break
        else:
            return make_response("antivirus module '{}' not present / enabled.".format(module))

        return make_response("ok")
예제 #15
0
    def each_with_type(self, target, file_type):
        self.joe = JoeSandbox(apikey=self.apikey, accept_tac=True)
        self.analysis_url = "https://jbxcloud.joesecurity.org/analysis/{}/0/html"
        self.results = dict()
        analysis = ""
        try:
            if file_type == 'url':
                analysis = self.joe.analysis_search(target)
            else:
                sha256 = ""
                basename = os.path.basename(target)
                with open(target, 'r+b') as f:
                    filef = File(filename=basename, stream=f)
                    sha256 = filef['sha256']
                analysis = self.joe.analysis_search(sha256)
            if not self.force_submit and len(analysis):
                self.webid = analysis[0]['webid']
                analysis_info = self.joe.analysis_info(self.webid)
                self.analysisid = analysis_info["analysisid"]
            else:
                data = self.submit_file(target, file_type)
                self.submission_id = data["submission_id"]
                # Wait for analysis to be over
                self.wait_for_analysis()

            # Add report URL to results
            self.results['URL'] = self.analysis_url.format(self.analysisid)

            # Get report, and extract IOCs
            self.process_report()

            # Get unpacked executables
            self.get_unpacked_executables()
        except (JoeException, Exception) as error:
            self.log("debug", "{}".format(error))

        return True
예제 #16
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)
예제 #17
0
 def _get_file_from_filepath(self, filepath, fd):
     return File(filename=os.path.basename(filepath), stream=fd)
예제 #18
0
    def post(self):
        """Create a new analysis.

        .. :quickref: Analysis; Create an analysis

        Launch a new analysis. You have to specify on which object this analysis
        will be made, by specifying one of:

        * ``file_id`` for an existing object
        * ``file`` for file uploads
        * ``url``
        * ``hash`` if VirusTotal sample retrieval is enabled.

        You should also supply all enabled analysis options with the name
        ``options[OPTION_NAME]``. For boolean options, any value different than
        ``0`` or ``False`` means the option is enabled.

        If the submitted object already exists (and ``file_id`` was not specified),
        the response will be a file object. When a new analysis was successfuly
        created, the analysis object will be returned, in the ``analysis`` field.

        If there was error in your submission, they will be returned in the
        ``errors`` field.

        **Example request**::

            headers = {
                'Accept': "application/json",
                'X-API-KEY': FAME_API_KEY
            }

            with open(filepath, 'rb') as f:
                params = {
                    'options[allow_internet_access]':  "on",
                    'options[analysis_time]': "300",
                    'groups': "cert"
                }

                files = {
                    'file': f
                }

                r = requests.post(ENDPOINT, data=params, files=files, headers=headers)

        :form string file_id: (optional) the id of the object on which this analysis should run.
        :form file file: (optional) file to analyze.
        :form string url: (optional) url to analyze.
        :form string hash: (optional) hash to analyze.
        :form string module: (optional) the name of the target module.
        :form string groups: a comma-separated list of groups that will have access to this analysis.
        :form string comment: comment to add to this object.
        :form string option[*]: value of each enabled option.
        """
        file_id = request.form.get('file_id')
        modules = filter(None, request.form.get('modules', '').split(','))
        groups = request.form.get('groups', '').split(',')
        comment = request.form.get('comment', '')

        options = get_options()
        if options is None:
            return validation_error()

        valid_submission = self._validate_form(groups, modules, options)
        if not valid_submission:
            return validation_error()

        if file_id is not None:
            f = File(get_or_404(current_user.files, _id=file_id))
            analysis = {
                'analysis':
                f.analyze(groups, current_user['_id'], modules, options)
            }
            return redirect(
                analysis,
                url_for('AnalysesView:get', id=analysis['analysis']['_id']))
        else:
            # When this is a new submission, validate the comment
            if not self._validate_comment(comment):
                return validation_error()

            f = self._get_object_to_analyze()
            if f is not None:
                f.add_owners(set(current_user['groups']) & set(groups))

                if comment:
                    f.add_comment(current_user['_id'], comment)

                if f.existing:
                    f.add_groups(groups)
                    flash(
                        "File already exists, so the analysis was not launched."
                    )

                    return redirect(clean_files(f),
                                    url_for('FilesView:get', id=f['_id']))
                else:
                    analysis = {
                        'analysis':
                        clean_analyses(
                            f.analyze(groups, current_user['_id'], modules,
                                      options))
                    }
                    analysis['analysis']['file'] = clean_files(f)

                    return redirect(
                        analysis,
                        url_for('AnalysesView:get',
                                id=analysis['analysis']['_id']))
            else:
                return render_template('analyses/new.html',
                                       options=dispatcher.options)
예제 #19
0
 def _get_file_from_filepath(self, filepath, fd=None):
     response = send_file_to_remote(filepath, '/files/')
     return File(json_util.loads(response.text)['file'])
예제 #20
0
파일: files.py 프로젝트: x0rzkov/fame
    def post(self):
        file = request.files['file']
        f = File(filename=secure_filename(file.filename), stream=file.stream)

        return render_json({'file': f})