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 })
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)
def index(self): """Get the list of objects. .. :quickref: File; Get the list of objects Response is paginated and will only contain 25 results. The most recent objects appear first. :query page: page number. :type page: int :>json list files: list of files (see :http:get:`/files/(id)` for details on the format of a file). """ page = int(request.args.get('page', 1)) files = current_user.files.find().sort( '_id', DESCENDING).limit(PER_PAGE).skip((page - 1) * PER_PAGE) pagination = Pagination(page=page, per_page=PER_PAGE, total=files.count(), css_framework='bootstrap3') files = {'files': clean_files(list(files))} return render(files, 'files/index.html', ctx={ 'data': files, 'pagination': pagination })
def index(self): """Get the list of analyses. .. :quickref: Analysis; Get the list of analyses Response is paginated and will only contain 25 results. The most recent analyses appear first. :query page: page number. :type page: int :>json list analyses: list of analyses (see :http:get:`/analyses/(id)` for details on the format of an analysis). """ page = int(request.args.get('page', 1)) analyses = current_user.analyses.find().sort('_id', DESCENDING).limit(PER_PAGE).skip((page - 1) * PER_PAGE) pagination = Pagination(page=page, per_page=PER_PAGE, total=analyses.count(), css_framework='bootstrap3') analyses = {'analyses': clean_analyses(list(analyses))} for analysis in analyses['analyses']: file = current_user.files.find_one({'_id': analysis['file']}) analysis['file'] = clean_files(file) if 'analyst' in analysis: analyst = store.users.find_one({'_id': analysis['analyst']}) analysis['analyst'] = clean_users(analyst) return render(analyses, 'analyses/index.html', ctx={'data': analyses, 'pagination': pagination})
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)
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)
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)
def post(self): query = request.form['query'] files = [] for file in current_user.files.find({'$text': {'$search': query}}): files.append(file) analyses = [] for analysis in current_user.analyses.find( {'$text': { '$search': query }}): file = current_user.files.find_one({'_id': analysis['file']}) analysis['file'] = clean_files(file) analyses.append(analysis) results = { 'files': clean_files(files), 'analyses': clean_analyses(analyses) } return render(results, 'search.html')
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()))) })
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 })
def get_hash(self, file_hash): """Get the object with `file_hash`. .. :quickref: File; Get an object by a hash :param hash: hash of the object. :>json file file: list of files (see :http:get:`/files/(id)` for details on the format of a file). """ hash_type = {64: "sha256", 40: "sha1", 32: "md5"} # If the hash has an unknown length, return 400 if len(file_hash) not in hash_type: abort(400) hash_filter = {hash_type[len(file_hash)]: file_hash.lower()} return return_file({ "file": enrich_comments( clean_files(get_or_404(current_user.files, **hash_filter))) })
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)