def obj_create(self, bundle, **kwargs): """ Handles creating Samples through the API. :param bundle: Bundle containing the information to create the Sample. :type bundle: Tastypie Bundle object. :returns: Bundle object. :raises BadRequest: If filedata is not provided or creation fails. """ analyst = bundle.request.user.username type_ = bundle.data.get('upload_type', None) if not type_: raise BadRequest('Must provide an upload type.') if type_ not in ('metadata', 'file'): raise BadRequest('Not a valid upload type.') if type_ == 'metadata': filename = bundle.data.get('filename', None) md5 = bundle.data.get('md5', None) password = None filedata = None elif type_ == 'file': md5 = None password = bundle.data.get('password', None) file_ = bundle.data.get('filedata', None) if not file_: raise BadRequest("Upload type of 'file' but no file uploaded.") filedata = file_ filename = None campaign = bundle.data.get('campaign', None) confidence = bundle.data.get('confidence', None) source = bundle.data.get('source', None) reference = bundle.data.get('reference', None) file_format = bundle.data.get('file_format', None) parent_md5 = bundle.data.get('parent_md5', None) bucket_list = bundle.data.get('bucket_list', None) ticket = bundle.data.get('ticket', None) sample_md5 = handle_uploaded_file(filedata, source, reference, file_format, password, user=analyst, campaign=campaign, confidence=confidence, parent_md5=parent_md5, filename=filename, md5=md5, bucket_list=bucket_list, ticket=ticket, is_return_only_md5=False) if len(sample_md5) > 0: if not sample_md5[0].get('success') and 'message' in sample_md5[0]: raise BadRequest(sample_md5[0]['message']) return bundle else: raise BadRequest('Unable to create sample from data.')
def obj_create(self, bundle, **kwargs): """ Handles creating Samples through the API. :param bundle: Bundle containing the information to create the Sample. :type bundle: Tastypie Bundle object. :returns: Bundle object. :raises BadRequest: If filedata is not provided or creation fails. """ analyst = bundle.request.user.username type_ = bundle.data.get('upload_type', None) if not type_: raise BadRequest('Must provide an upload type.') if type_ not in ('metadata', 'file'): raise BadRequest('Not a valid upload type.') if type_ == 'metadata': filename = bundle.data.get('filename', None) md5 = bundle.data.get('md5', None) password = None filedata = None elif type_ == 'file': md5 = None password = bundle.data.get('password', None) file_ = bundle.data.get('filedata', None) if not file_: raise BadRequest("Upload type of 'file' but no file uploaded.") filedata = file_ filename = None campaign = bundle.data.get('campaign', None) confidence = bundle.data.get('confidence', None) source = bundle.data.get('source', None) reference = bundle.data.get('reference', None) file_format = bundle.data.get('file_format', None) parent_md5 = bundle.data.get('parent_md5', None) bucket_list = bundle.data.get('bucket_list', None) ticket = bundle.data.get('ticket', None) sample_md5 = handle_uploaded_file(filedata, source, reference, file_format, password, user=analyst, campaign=campaign, confidence=confidence, parent_md5 = parent_md5, filename=filename, md5=md5, bucket_list=bucket_list, ticket=ticket, is_return_only_md5=False) if len(sample_md5) > 0: if not sample_md5[0].get('success') and 'message' in sample_md5[0]: raise BadRequest(sample_md5[0]['message']) return bundle else: raise BadRequest('Unable to create sample from data.')
def add_sample_for_event(event_id, data, analyst, filedata=None, filename=None, md5=None, email_addr=None, inherit_sources=False): """ Add a sample related to this Event. :param event_id: The ObjectId of the Event to associate with. :type event_id: str :param data: The form data. :type data: dict :param analyst: The user adding this Sample. :type analyst: str :param filedata: The sample data. :type filedata: file handle. :param filename: The name of the file. :type filename: str :param md5: The MD5 of the file. :type md5: str :param email_addr: Email address to which to email the sample :type email_addr: str :param inherit_sources: 'True' if Sample should inherit Event's Source(s) :type inherit_sources: bool :returns: dict with keys "success" (boolean) and "message" (str) """ response = { 'success': False, 'message': 'Unknown error; unable to upload file.' } users_sources = user_sources(analyst) event = Event.objects(id=event_id, source__name__in=users_sources).first() if not event: return {'success': False, 'message': "No matching event found"} source = data['source'] reference = data['reference'] file_format = data['file_format'] campaign = data['campaign'] confidence = data['confidence'] bucket_list = data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME] ticket = data[form_consts.Common.TICKET_VARIABLE_NAME] method = data['method'] if filename: filename = filename.strip() # If selected, new sample inherits the campaigns of the related event. if data['inherit_campaigns']: if campaign: event.campaign.append( EmbeddedCampaign(name=campaign, confidence=confidence, analyst=analyst)) campaign = event.campaign inherited_source = event.source if inherit_sources else None try: if filedata: result = handle_uploaded_file(filedata, source, method, reference, file_format, data['password'], analyst, campaign, confidence, related_id=event.id, related_type='Event', filename=filename, bucket_list=bucket_list, ticket=ticket, inherited_source=inherited_source) else: if md5: md5 = md5.strip().lower() result = handle_uploaded_file(None, source, method, reference, file_format, None, analyst, campaign, confidence, related_id=event.id, related_type='Event', filename=filename, md5=md5, bucket_list=bucket_list, ticket=ticket, inherited_source=inherited_source, is_return_only_md5=False) except ZipFileError, zfe: return {'success': False, 'message': zfe.value}
def add_sample_for_event(event_id, data, analyst, filedata=None, filename=None, md5=None, email_addr=None, inherit_sources=False): """ Add a sample related to this Event. :param event_id: The ObjectId of the Event to associate with. :type event_id: str :param data: The form data. :type data: dict :param analyst: The user adding this Sample. :type analyst: str :param filedata: The sample data. :type filedata: file handle. :param filename: The name of the file. :type filename: str :param md5: The MD5 of the file. :type md5: str :param email_addr: Email address to which to email the sample :type email_addr: str :param inherit_sources: 'True' if Sample should inherit Event's Source(s) :type inherit_sources: bool :returns: dict with keys "success" (boolean) and "message" (str) """ response = {'success': False, 'message': 'Unknown error; unable to upload file.'} users_sources = user_sources(analyst) event = Event.objects(id=event_id, source__name__in=users_sources).first() if not event: return {'success': False, 'message': "No matching event found"} source = data['source'] reference = data['reference'] file_format = data['file_format'] campaign = data['campaign'] confidence = data['confidence'] bucket_list = data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME] ticket = data[form_consts.Common.TICKET_VARIABLE_NAME] method = data['method'] if filename: filename = filename.strip() # If selected, new sample inherits the campaigns of the related event. if data['inherit_campaigns']: if campaign: event.campaign.append(EmbeddedCampaign(name=campaign, confidence=confidence, analyst=analyst)) campaign = event.campaign inherited_source = event.source if inherit_sources else None try: if filedata: result = handle_uploaded_file(filedata, source, method, reference, file_format, data['password'], analyst, campaign, confidence, related_id=event.id, related_type='Event', filename=filename, bucket_list=bucket_list, ticket=ticket, inherited_source=inherited_source) else: if md5: md5 = md5.strip().lower() result = handle_uploaded_file(None, source, method, reference, file_format, None, analyst, campaign, confidence, related_id=event.id, related_type='Event', filename=filename, md5=md5, bucket_list=bucket_list, ticket=ticket, inherited_source=inherited_source, is_return_only_md5=False) except ZipFileError, zfe: return {'success': False, 'message': zfe.value}
def upload_child(request, parent_md5): """ Upload a new child sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :param parent_md5: The MD5 of the parent sample. :type parent_md5: str :returns: :class:`django.http.HttpResponse` """ new_samples = [] if request.method == "POST": form = EmailAttachForm(request.user.username, request.POST, request.FILES) if form.is_valid(): if request.FILES or 'filename' in request.POST and 'md5' in request.POST: # Child samples inherit all of the sources of the parent. parent = Sample.objects(md5=parent_md5).first() if not parent: return render_to_response('error.html', {'error': "Unable to find parent."}, RequestContext(request)) source = parent.source campaign_name = request.POST['campaign'] confidence = request.POST['confidence'] parent.campaign.append(EmbeddedCampaign(name=campaign_name, confidence=confidence, analyst=request.user.username)) campaigns = parent.campaign try: if request.FILES: new_samples = handle_uploaded_file(request.FILES["filedata"], source, None, form.cleaned_data["file_format"], form.cleaned_data["password"], user=request.user.username, campaign=campaigns, parent_md5=parent_md5, bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME]) else: filename = request.POST['filename'].strip() md5= request.POST['md5'].strip().lower() if not filename or not md5: error = "Need a file, or a filename and an md5." return render_to_response('error.html', {'error': error}, RequestContext(request)) else: new_samples = handle_uploaded_file(None, source, None, form.cleaned_data["file_format"], form.cleaned_data["password"], user=request.user.username, campaign=campaigns, parent_md5=parent_md5, filename=filename, bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME], md5=md5) except ZipFileError, zfe: return render_to_response('error.html', {'error': zfe.value}, RequestContext(request)) else: return render_to_response('error.html', {'error': "Need a file, or a filename and an md5."}, RequestContext(request)) else: return render_to_response('error.html', {'error': 'form error'}, RequestContext(request))
def upload_file(request): """ Upload a new sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :returns: :class:`django.http.HttpResponse` """ if request.method == 'POST': form = UploadFileForm(request.user, request.POST, request.FILES) email_errmsg = None if form.is_valid(): campaign = form.cleaned_data['campaign'] confidence = form.cleaned_data['confidence'] source = form.cleaned_data['source'] reference = form.cleaned_data['reference'] try: if request.FILES: sample_md5 = handle_uploaded_file( request.FILES['filedata'], source, reference, form.cleaned_data['file_format'], form.cleaned_data['password'], user=request.user.username, campaign=campaign, confidence=confidence, parent_md5 = form.cleaned_data['parent_md5'], bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME]) else: filename = request.POST['filename'].strip() md5 = request.POST['md5'].strip().lower() sample_md5 = handle_uploaded_file( None, source, reference, form.cleaned_data['file_format'], None, user=request.user.username, campaign=campaign, confidence=confidence, parent_md5 = form.cleaned_data['parent_md5'], filename=filename, md5=md5, bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME], is_return_only_md5=False) if 'email' in request.POST: for s in sample_md5: email_errmsg = mail_sample(s, [request.user.email]) except ZipFileError, zfe: return render_to_response('file_upload_response.html', {'response': json.dumps({'success': False, 'message': zfe.value})}, RequestContext(request)) else: response = {'success': False, 'message': 'Unknown error; unable to upload file.'} if len(sample_md5) > 1: filedata = request.FILES['filedata'] message = ('<a href="%s">View Uploaded Samples.</a>' % reverse('crits.samples.views.view_upload_list', args=[filedata.name, sample_md5])) response = {'success': True, 'message': message } elif len(sample_md5) == 1: md5_response = None if not request.FILES: response['success'] = sample_md5[0].get('success', False) if(response['success'] == False): response['message'] = sample_md5[0].get('message', response.get('message')) else: md5_response = sample_md5[0].get('object').md5 else: md5_response = sample_md5[0] response['success'] = True if md5_response != None: response['message'] = ('File uploaded successfully. <a href="%s">View Sample.</a>' % reverse('crits.samples.views.detail', args=[md5_response])) if email_errmsg is not None: msg = "<br>Error sending email: %s" % email_errmsg response['message'] = response['message'] + msg return render_to_response("file_upload_response.html", {'response': json.dumps(response)}, RequestContext(request)) else: return render_to_response('file_upload_response.html', {'response': json.dumps({'success': False, 'form': form.as_table()})}, RequestContext(request))
def upload_file(request, related_md5=None): """ Upload a new sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :param related_md5: The MD5 of a related sample. :type related_md5: str :returns: :class:`django.http.HttpResponse` """ if request.method == 'POST': form = UploadFileForm(request.user, request.POST, request.FILES) email_errmsg = None if form.is_valid(): response = { 'success': False, 'message': 'Unknown error; unable to upload file.' } inherited_source = None backdoor = form.cleaned_data['backdoor'] campaign = form.cleaned_data['campaign'] confidence = form.cleaned_data['confidence'] source = form.cleaned_data['source_name'] source_method = form.cleaned_data['source_method'] source_reference = form.cleaned_data['source_reference'] source_tlp = form.cleaned_data['source_tlp'] user = request.user description = form.cleaned_data['description'] related_id = form.cleaned_data.get('related_id', None) related_type = form.cleaned_data.get('related_type', None) relationship_type = form.cleaned_data.get('relationship_type', None) if related_md5: reload_page = True else: reload_page = False related_md5 = form.cleaned_data['related_md5'] if related_md5: related_sample = Sample.objects(md5=related_md5).first() if not related_sample: response['message'] = ( "Upload Failed. Unable to locate related sample. %s" % related_md5) return render(request, "file_upload_response.html", {'response': json.dumps(response)}) # If selected, new sample inherits the campaigns of the related sample. if form.cleaned_data['inherit_campaigns']: if campaign: related_sample.campaign.append( EmbeddedCampaign(name=campaign, confidence=confidence, analyst=user)) campaign = related_sample.campaign # If selected, new sample inherits the sources of the related sample if form.cleaned_data['inherit_sources']: inherited_source = related_sample.source elif related_id: related_obj = class_from_id(related_type, related_id) if not related_obj: response['success'] = False response['message'] = ( "Upload Failed. Unable to locate related Item") return render( request, "file_upload_response.html", {'response': json.dumps(response)}, ) else: if form.cleaned_data['inherit_campaigns']: if campaign: related_obj.campaign.append( EmbeddedCampaign(name=campaign, confidence=confidence, analyst=user)) campaign = related_obj.campaign if form.cleaned_data['inherit_sources']: inherited_source = related_obj.source backdoor_name = None backdoor_version = None if backdoor: backdoor = backdoor.split('|||') if len(backdoor) == 2: (backdoor_name, backdoor_version) = backdoor[0], backdoor[1] try: if request.FILES: result = handle_uploaded_file( request.FILES['filedata'], source, source_method=source_method, source_reference=source_reference, source_tlp=source_tlp, file_format=form.cleaned_data['file_format'], password=form.cleaned_data['password'], user=user, campaign=campaign, confidence=confidence, related_md5=related_md5, related_id=related_id, related_type=related_type, relationship_type=relationship_type, bucket_list=form.cleaned_data[ form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, backdoor_name=backdoor_name, backdoor_version=backdoor_version, description=description) else: result = handle_uploaded_file( None, source, source_method=source_method, source_reference=source_reference, source_tlp=source_tlp, file_format=form.cleaned_data['file_format'], password=None, user=user, campaign=campaign, confidence=confidence, related_md5=related_md5, related_id=related_id, related_type=related_type, relationship_type=relationship_type, filename=request.POST['filename'].strip(), md5=request.POST['md5'].strip().lower(), sha1=request.POST['sha1'].strip().lower(), sha256=request.POST['sha256'].strip().lower(), bucket_list=form.cleaned_data[ form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, is_return_only_md5=False, backdoor_name=backdoor_name, backdoor_version=backdoor_version, description=description) except ZipFileError, zfe: return render( request, 'file_upload_response.html', { 'response': json.dumps({ 'success': False, 'message': zfe.value }) }) else: # zip file upload, etc; result is a list of strings (1 hash per file) if len(result) > 0 and not isinstance(result[0], dict): filedata = request.FILES['filedata'] message = ('<a href="%s">View Uploaded Samples.</a>' % reverse('crits-samples-views-view_upload_list', args=[filedata.name, result])) response = {'success': True, 'message': message} md5_response = result # regular file upload; result is a list with a single dict else: response['success'] = result[0].get('success', False) response['message'] = result[0].get( 'message', response.get('message')) try: md5_response = [result[0].get('object').md5] except: md5_response = None if response['success']: if request.POST.get('email') and md5_response: for s in md5_response: email_errmsg = mail_sample(s, [request.user.email]) if email_errmsg is not None: msg = "<br>Error emailing sample %s: %s\n" % ( s, email_errmsg) response['message'] = response['message'] + msg if reload_page: response['redirect_url'] = reverse( 'crits-samples-views-detail', args=[related_md5]) return render(request, "file_upload_response.html", {'response': json.dumps(response)}) else: if related_md5: #if this is a 'related' upload, hide field so it doesn't reappear form.fields['related_md5'].widget = forms.HiddenInput() return render( request, 'file_upload_response.html', { 'response': json.dumps({ 'success': False, 'form': form.as_table() }) })
def upload_file(request, related_md5=None): """ Upload a new sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :param related_md5: The MD5 of a related sample. :type related_md5: str :returns: :class:`django.http.HttpResponse` """ if request.method == 'POST': form = UploadFileForm(request.user, request.POST, request.FILES) email_errmsg = None if form.is_valid(): response = { 'success': False, 'message': 'Unknown error; unable to upload file.' } inherited_source = None backdoor = form.cleaned_data['backdoor'] campaign = form.cleaned_data['campaign'] confidence = form.cleaned_data['confidence'] source = form.cleaned_data['source'] method = form.cleaned_data['method'] reference = form.cleaned_data['reference'] analyst = request.user.username if related_md5: reload_page = True else: reload_page = False related_md5 = form.cleaned_data['related_md5'] if related_md5: related_sample = Sample.objects(md5=related_md5).first() if not related_sample: response[ 'message'] = "Upload Failed. Unable to locate related sample." return render_to_response( "file_upload_response.html", {'response': json.dumps(response)}, RequestContext(request)) # If selected, new sample inherits the campaigns of the related sample. if form.cleaned_data['inherit_campaigns']: if campaign: related_sample.campaign.append( EmbeddedCampaign(name=campaign, confidence=confidence, analyst=analyst)) campaign = related_sample.campaign # If selected, new sample inherits the sources of the related sample if form.cleaned_data['inherit_sources']: inherited_source = related_sample.source backdoor_name = None backdoor_version = None if backdoor: backdoor = backdoor.split('|||') if len(backdoor) == 2: (backdoor_name, backdoor_version) = backdoor[0], backdoor[1] try: if request.FILES: result = handle_uploaded_file( request.FILES['filedata'], source, method=method, reference=reference, file_format=form.cleaned_data['file_format'], password=form.cleaned_data['password'], user=analyst, campaign=campaign, confidence=confidence, related_md5=related_md5, bucket_list=form.cleaned_data[ form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, backdoor_name=backdoor_name, backdoor_version=backdoor_version) else: result = handle_uploaded_file( None, source, method=method, reference=reference, file_format=form.cleaned_data['file_format'], password=None, user=analyst, campaign=campaign, confidence=confidence, related_md5=related_md5, filename=request.POST['filename'].strip(), md5=request.POST['md5'].strip().lower(), sha1=request.POST['sha1'].strip().lower(), sha256=request.POST['sha256'].strip().lower(), bucket_list=form.cleaned_data[ form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, is_return_only_md5=False, backdoor_name=backdoor_name, backdoor_version=backdoor_version) except ZipFileError, zfe: return render_to_response( 'file_upload_response.html', { 'response': json.dumps({ 'success': False, 'message': zfe.value }) }, RequestContext(request)) else: if len(result) > 1: filedata = request.FILES['filedata'] message = ('<a href="%s">View Uploaded Samples.</a>' % reverse('crits.samples.views.view_upload_list', args=[filedata.name, result])) response = {'success': True, 'message': message} md5_response = result elif len(result) == 1: md5_response = None if not request.FILES: response['success'] = result[0].get('success', False) if (response['success'] == False): response['message'] = result[0].get( 'message', response.get('message')) else: md5_response = [result[0].get('object').md5] else: md5_response = [result[0]] response['success'] = True if md5_response != None: response['message'] = ( 'File uploaded successfully. <a href="%s">View Sample.</a>' % reverse('crits.samples.views.detail', args=md5_response)) if response['success']: if request.POST.get('email'): for s in md5_response: email_errmsg = mail_sample(s, [request.user.email]) if email_errmsg is not None: msg = "<br>Error emailing sample %s: %s\n" % ( s, email_errmsg) response['message'] = response['message'] + msg if reload_page: response['redirect_url'] = reverse( 'crits.samples.views.detail', args=[related_md5]) return render_to_response("file_upload_response.html", {'response': json.dumps(response)}, RequestContext(request)) else: if related_md5: #if this is a 'related' upload, hide field so it doesn't reappear form.fields['related_md5'].widget = forms.HiddenInput() return render_to_response( 'file_upload_response.html', { 'response': json.dumps({ 'success': False, 'form': form.as_table() }) }, RequestContext(request))
def obj_create(self, bundle, **kwargs): """ Handles creating Samples through the API. :param bundle: Bundle containing the information to create the Sample. :type bundle: Tastypie Bundle object. :returns: HttpResponse. """ user = bundle.request.user type_ = bundle.data.get('upload_type', None) content = {'return_code': 1, 'type': 'Sample'} if not type_: content['message'] = 'Must provide an upload type.' self.crits_response(content) if type_ not in ('metadata', 'file'): content['message'] = 'Not a valid upload type.' self.crits_response(content) if type_ == 'metadata': filename = bundle.data.get('filename', None) md5 = bundle.data.get('md5', None) password = None filedata = None elif type_ == 'file': md5 = None password = bundle.data.get('password', None) file_ = bundle.data.get('filedata', None) if not file_: content['message'] = "Upload type of 'file' but no file uploaded." self.crits_response(content) filedata = file_ filename = None campaign = bundle.data.get('campaign', None) confidence = bundle.data.get('confidence', None) source = bundle.data.get('source', None) method = bundle.data.get('method', "") reference = bundle.data.get('reference', None) tlp = bundle.data.get('tlp', 'amber') file_format = bundle.data.get('file_format', None) related_md5 = bundle.data.get('related_md5', None) related_id = bundle.data.get('related_id', None) related_type = bundle.data.get('related_type', None) backdoor_name = bundle.data.get('backdoor_name', None) backdoor_version = bundle.data.get('backdoor_version', None) description = bundle.data.get('description', None) bucket_list = bundle.data.get('bucket_list', None) ticket = bundle.data.get('ticket', None) sha1 = bundle.data.get('sha1', None) sha256 = bundle.data.get('sha256', None) size = bundle.data.get('size', None) mimetype = bundle.data.get('mimetype', None) if ((related_id and not related_type) or (related_type and not related_id)): content['message'] = "Must specify related_type and related_id" self.crits_response(content) if not user.has_access_to(SampleACL.WRITE): content['message'] = 'User does not have permission to create Object.' self.crits_response(content) sample_md5 = handle_uploaded_file(filedata, source, method, reference, tlp, file_format, password, user=user, description=description, campaign=campaign, confidence=confidence, related_md5=related_md5, related_id=related_id, related_type=related_type, filename=filename, md5=md5, sha1=sha1, sha256=sha256, size=size, mimetype=mimetype, bucket_list=bucket_list, ticket=ticket, is_return_only_md5=False, backdoor_name=backdoor_name, backdoor_version=backdoor_version) result = {'success': False} if len(sample_md5) > 0: result = sample_md5[0] if result.get('message'): content['message'] = result.get('message') if result.get('object'): content['id'] = str(result.get('object').id) if content.get('id'): url = reverse('api_dispatch_detail', kwargs={'resource_name': 'samples', 'api_name': 'v1', 'pk': content.get('id')}) content['url'] = url else: content['message'] = "Could not create Sample for unknown reason." if result['success']: content['return_code'] = 0 self.crits_response(content)
def obj_create(self, bundle, **kwargs): """ Handles creating Samples through the API. :param bundle: Bundle containing the information to create the Sample. :type bundle: Tastypie Bundle object. :returns: HttpResponse. """ user = bundle.request.user type_ = bundle.data.get('upload_type', None) content = {'return_code': 1, 'type': 'Sample'} if not type_: content['message'] = 'Must provide an upload type.' self.crits_response(content) if type_ not in ('metadata', 'file'): content['message'] = 'Not a valid upload type.' self.crits_response(content) if type_ == 'metadata': filename = bundle.data.get('filename', None) md5 = bundle.data.get('md5', None) password = None filedata = None elif type_ == 'file': md5 = None password = bundle.data.get('password', None) file_ = bundle.data.get('filedata', None) if not file_: content[ 'message'] = "Upload type of 'file' but no file uploaded." self.crits_response(content) filedata = file_ filename = None campaign = bundle.data.get('campaign', None) confidence = bundle.data.get('confidence', None) source = bundle.data.get('source', None) method = bundle.data.get('method', "") reference = bundle.data.get('reference', None) tlp = bundle.data.get('tlp', 'amber') file_format = bundle.data.get('file_format', None) related_md5 = bundle.data.get('related_md5', None) related_id = bundle.data.get('related_id', None) related_type = bundle.data.get('related_type', None) backdoor_name = bundle.data.get('backdoor_name', None) backdoor_version = bundle.data.get('backdoor_version', None) description = bundle.data.get('description', None) bucket_list = bundle.data.get('bucket_list', None) ticket = bundle.data.get('ticket', None) sha1 = bundle.data.get('sha1', None) sha256 = bundle.data.get('sha256', None) size = bundle.data.get('size', None) mimetype = bundle.data.get('mimetype', None) if ((related_id and not related_type) or (related_type and not related_id)): content['message'] = "Must specify related_type and related_id" self.crits_response(content) if not user.has_access_to(SampleACL.WRITE): content[ 'message'] = 'User does not have permission to create Object.' self.crits_response(content) sample_md5 = handle_uploaded_file(filedata, source, method, reference, tlp, file_format, password, user=user, description=description, campaign=campaign, confidence=confidence, related_md5=related_md5, related_id=related_id, related_type=related_type, filename=filename, md5=md5, sha1=sha1, sha256=sha256, size=size, mimetype=mimetype, bucket_list=bucket_list, ticket=ticket, is_return_only_md5=False, backdoor_name=backdoor_name, backdoor_version=backdoor_version) result = {'success': False} if len(sample_md5) > 0: result = sample_md5[0] if result.get('message'): content['message'] = result.get('message') if result.get('object'): content['id'] = str(result.get('object').id) if content.get('id'): url = reverse('api_dispatch_detail', kwargs={ 'resource_name': 'samples', 'api_name': 'v1', 'pk': content.get('id') }) content['url'] = url else: content['message'] = "Could not create Sample for unknown reason." if result['success']: content['return_code'] = 0 self.crits_response(content)
def upload_file(request, related_md5=None): """ Upload a new sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :param related_md5: The MD5 of a related sample. :type related_md5: str :returns: :class:`django.http.HttpResponse` """ if request.method == 'POST': form = UploadFileForm(request.user, request.POST, request.FILES) email_errmsg = None if form.is_valid(): response = {'success': False, 'message': 'Unknown error; unable to upload file.'} inherited_source = None backdoor = form.cleaned_data['backdoor'] campaign = form.cleaned_data['campaign'] confidence = form.cleaned_data['confidence'] source = form.cleaned_data['source'] method = form.cleaned_data['method'] reference = form.cleaned_data['reference'] analyst = request.user.username if related_md5: reload_page = True else: reload_page = False related_md5 = form.cleaned_data['related_md5'] if related_md5: related_sample = Sample.objects(md5=related_md5).first() if not related_sample: response['message'] = "Upload Failed. Unable to locate related sample." return render_to_response("file_upload_response.html", {'response': json.dumps(response)}, RequestContext(request)) # If selected, new sample inherits the campaigns of the related sample. if form.cleaned_data['inherit_campaigns']: if campaign: related_sample.campaign.append(EmbeddedCampaign(name=campaign, confidence=confidence, analyst=analyst)) campaign = related_sample.campaign # If selected, new sample inherits the sources of the related sample if form.cleaned_data['inherit_sources']: inherited_source = related_sample.source backdoor_name = None backdoor_version = None if backdoor: backdoor = backdoor.split('|||') if len(backdoor) == 2: (backdoor_name, backdoor_version) = backdoor[0], backdoor[1] try: if request.FILES: result = handle_uploaded_file( request.FILES['filedata'], source, method, reference, form.cleaned_data['file_format'], form.cleaned_data['password'], analyst, campaign, confidence, related_md5, bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, backdoor_name=backdoor_name, backdoor_version=backdoor_version) else: result = handle_uploaded_file( None, source, method, reference, form.cleaned_data['file_format'], None, analyst, campaign, confidence, related_md5 = related_md5, filename=request.POST['filename'].strip(), md5=request.POST['md5'].strip().lower(), bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, is_return_only_md5=False, backdoor_name=backdoor_name, backdoor_version=backdoor_version) except ZipFileError, zfe: return render_to_response('file_upload_response.html', {'response': json.dumps({'success': False, 'message': zfe.value})}, RequestContext(request)) else: if len(result) > 1: filedata = request.FILES['filedata'] message = ('<a href="%s">View Uploaded Samples.</a>' % reverse('crits.samples.views.view_upload_list', args=[filedata.name, result])) response = {'success': True, 'message': message } md5_response = result elif len(result) == 1: md5_response = None if not request.FILES: response['success'] = result[0].get('success', False) if(response['success'] == False): response['message'] = result[0].get('message', response.get('message')) else: md5_response = [result[0].get('object').md5] else: md5_response = [result[0]] response['success'] = True if md5_response != None: response['message'] = ('File uploaded successfully. <a href="%s">View Sample.</a>' % reverse('crits.samples.views.detail', args=md5_response)) if response['success']: if request.POST.get('email'): for s in md5_response: email_errmsg = mail_sample(s, [request.user.email]) if email_errmsg is not None: msg = "<br>Error emailing sample %s: %s\n" % (s, email_errmsg) response['message'] = response['message'] + msg if reload_page: response['redirect_url'] = reverse('crits.samples.views.detail', args=[related_md5]) return render_to_response("file_upload_response.html", {'response': json.dumps(response)}, RequestContext(request)) else: if related_md5: #if this is a 'related' upload, hide field so it doesn't reappear form.fields['related_md5'].widget = forms.HiddenInput() return render_to_response('file_upload_response.html', {'response': json.dumps({'success': False, 'form': form.as_table()})}, RequestContext(request))
def add_sample_for_event(event_id, data, analyst, filedata=None, filename=None, md5=None): """ Add a sample related to this Event. :param event_id: The ObjectId of the Event to associate with. :type event_id: str :param data: The form data. :type data: dict :param analyst: The user adding this Sample. :type analyst: str :param filedata: The sample data. :type filedata: file handle. :param filename: The name of the file. :type filename: str :param md5: The MD5 of the file. :type md5: str :returns: dict with keys "success" (boolean) and "error" (str) """ sources = user_sources(analyst) event = Event.objects(id=event_id, source__name__in=sources).first() if not event: error = "No matching event found" return {'success': False, 'error': error} source = data['source'] campaign = data['campaign'] confidence = data['confidence'] reference = data['source_reference'] file_format = data['file_format'] password = data['password'] bucket_list = data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME] ticket = data[form_consts.Common.TICKET_VARIABLE_NAME] try: if filedata: sample_md5 = handle_uploaded_file(filedata, source, reference, file_format, password, analyst, campaign=campaign, confidence=confidence, bucket_list=bucket_list, ticket=ticket) else: if not filename or not md5: error = "Need a file, or a filename and an md5" return {'success': False, 'error': error} else: sample_md5 = handle_uploaded_file(None, source, reference, file_format, password, analyst, campaign=campaign, confidence=confidence, bucket_list=bucket_list, ticket=ticket, filename=filename.strip(), md5=md5.strip()) except ZipFileError, zfe: return {'success': False, 'error': zfe.value}
def upload_child(request, parent_md5): """ Upload a new child sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :param parent_md5: The MD5 of the parent sample. :type parent_md5: str :returns: :class:`django.http.HttpResponse` """ new_samples = [] if request.method == "POST": form = EmailAttachForm(request.user.username, request.POST, request.FILES) if form.is_valid(): if request.FILES or 'filename' in request.POST and 'md5' in request.POST: # Child samples inherit all of the sources of the parent. parent = Sample.objects(md5=parent_md5).first() if not parent: return render_to_response( 'error.html', {'error': "Unable to find parent."}, RequestContext(request)) source = parent.source campaign_name = request.POST['campaign'] confidence = request.POST['confidence'] parent.campaign.append( EmbeddedCampaign(name=campaign_name, confidence=confidence, analyst=request.user.username)) campaigns = parent.campaign try: if request.FILES: new_samples = handle_uploaded_file( request.FILES["filedata"], source, None, form.cleaned_data["file_format"], form.cleaned_data["password"], user=request.user.username, campaign=campaigns, parent_md5=parent_md5, bucket_list=form.cleaned_data[ form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME]) else: filename = request.POST['filename'].strip() md5 = request.POST['md5'].strip().lower() if not filename or not md5: error = "Need a file, or a filename and an md5." return render_to_response('error.html', {'error': error}, RequestContext(request)) else: new_samples = handle_uploaded_file( None, source, None, form.cleaned_data["file_format"], form.cleaned_data["password"], user=request.user.username, campaign=campaigns, parent_md5=parent_md5, filename=filename, bucket_list=form.cleaned_data[ form_consts.Common. BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME], md5=md5) except ZipFileError, zfe: return render_to_response('error.html', {'error': zfe.value}, RequestContext(request)) else: return render_to_response( 'error.html', {'error': "Need a file, or a filename and an md5."}, RequestContext(request)) else: return render_to_response('error.html', {'error': 'form error'}, RequestContext(request))
def upload_file(request): """ Upload a new sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :returns: :class:`django.http.HttpResponse` """ if request.method == 'POST': form = UploadFileForm(request.user, request.POST, request.FILES) email_errmsg = None if form.is_valid(): campaign = form.cleaned_data['campaign'] confidence = form.cleaned_data['confidence'] source = form.cleaned_data['source'] reference = form.cleaned_data['reference'] try: if request.FILES: sample_md5 = handle_uploaded_file( request.FILES['filedata'], source, reference, form.cleaned_data['file_format'], form.cleaned_data['password'], user=request.user.username, campaign=campaign, confidence=confidence, parent_md5=form.cleaned_data['parent_md5'], bucket_list=form.cleaned_data[ form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME]) else: filename = request.POST['filename'].strip() md5 = request.POST['md5'].strip().lower() sample_md5 = handle_uploaded_file( None, source, reference, form.cleaned_data['file_format'], None, user=request.user.username, campaign=campaign, confidence=confidence, parent_md5=form.cleaned_data['parent_md5'], filename=filename, md5=md5, bucket_list=form.cleaned_data[ form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[ form_consts.Common.TICKET_VARIABLE_NAME], is_return_only_md5=False) if 'email' in request.POST: for s in sample_md5: email_errmsg = mail_sample(s, [request.user.email]) except ZipFileError, zfe: return render_to_response( 'file_upload_response.html', { 'response': json.dumps({ 'success': False, 'message': zfe.value }) }, RequestContext(request)) else: response = { 'success': False, 'message': 'Unknown error; unable to upload file.' } if len(sample_md5) > 1: filedata = request.FILES['filedata'] message = ('<a href="%s">View Uploaded Samples.</a>' % reverse('crits.samples.views.view_upload_list', args=[filedata.name, sample_md5])) response = {'success': True, 'message': message} elif len(sample_md5) == 1: md5_response = None if not request.FILES: response['success'] = sample_md5[0].get( 'success', False) if (response['success'] == False): response['message'] = sample_md5[0].get( 'message', response.get('message')) else: md5_response = sample_md5[0].get('object').md5 else: md5_response = sample_md5[0] response['success'] = True if md5_response != None: response['message'] = ( 'File uploaded successfully. <a href="%s">View Sample.</a>' % reverse('crits.samples.views.detail', args=[md5_response])) if email_errmsg is not None: msg = "<br>Error sending email: %s" % email_errmsg response['message'] = response['message'] + msg return render_to_response("file_upload_response.html", {'response': json.dumps(response)}, RequestContext(request)) else: return render_to_response( 'file_upload_response.html', { 'response': json.dumps({ 'success': False, 'form': form.as_table() }) }, RequestContext(request))
def upload_file(request, related_md5=None): """ Upload a new sample. :param request: Django request object (Required) :type request: :class:`django.http.HttpRequest` :param related_md5: The MD5 of a related sample. :type related_md5: str :returns: :class:`django.http.HttpResponse` """ if request.method == 'POST': form = UploadFileForm(request.user, request.POST, request.FILES) email_errmsg = None if form.is_valid(): response = {'success': False, 'message': 'Unknown error; unable to upload file.'} inherited_source = None backdoor = form.cleaned_data['backdoor'] campaign = form.cleaned_data['campaign'] confidence = form.cleaned_data['confidence'] source = form.cleaned_data['source_name'] source_method = form.cleaned_data['source_method'] source_reference = form.cleaned_data['source_reference'] source_tlp = form.cleaned_data['source_tlp'] user = request.user description = form.cleaned_data['description'] related_id = form.cleaned_data.get('related_id', None) related_type = form.cleaned_data.get('related_type', None) relationship_type = form.cleaned_data.get('relationship_type', None) if related_md5: reload_page = True else: reload_page = False related_md5 = form.cleaned_data['related_md5'] if related_md5: related_sample = Sample.objects(md5=related_md5).first() if not related_sample: response['message'] = ("Upload Failed. Unable to locate related sample. %s" % related_md5) return render(request, "file_upload_response.html", {'response': json.dumps(response)}) # If selected, new sample inherits the campaigns of the related sample. if form.cleaned_data['inherit_campaigns']: if campaign: related_sample.campaign.append(EmbeddedCampaign(name=campaign, confidence=confidence, analyst=user)) campaign = related_sample.campaign # If selected, new sample inherits the sources of the related sample if form.cleaned_data['inherit_sources']: inherited_source = related_sample.source elif related_id: related_obj = class_from_id(related_type, related_id) if not related_obj: response['success'] = False response['message'] = ("Upload Failed. Unable to locate related Item") return render(request, "file_upload_response.html",{'response': json.dumps(response)}, ) else: if form.cleaned_data['inherit_campaigns']: if campaign: related_obj.campaign.append(EmbeddedCampaign(name=campaign, confidence=confidence, analyst=user)) campaign = related_obj.campaign if form.cleaned_data['inherit_sources']: inherited_source = related_obj.source backdoor_name = None backdoor_version = None if backdoor: backdoor = backdoor.split('|||') if len(backdoor) == 2: (backdoor_name, backdoor_version) = backdoor[0], backdoor[1] try: if request.FILES: result = handle_uploaded_file( request.FILES['filedata'], source, source_method=source_method, source_reference=source_reference, source_tlp=source_tlp, file_format=form.cleaned_data['file_format'], password=form.cleaned_data['password'], user=user, campaign=campaign, confidence=confidence, related_md5=related_md5, related_id=related_id, related_type=related_type, relationship_type=relationship_type, bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, backdoor_name=backdoor_name, backdoor_version=backdoor_version, description=description) else: result = handle_uploaded_file( None, source, source_method=source_method, source_reference=source_reference, source_tlp=source_tlp, file_format=form.cleaned_data['file_format'], password=None, user=user, campaign=campaign, confidence=confidence, related_md5 = related_md5, related_id=related_id, related_type=related_type, relationship_type=relationship_type, filename=request.POST['filename'].strip(), md5=request.POST['md5'].strip().lower(), sha1=request.POST['sha1'].strip().lower(), sha256=request.POST['sha256'].strip().lower(), bucket_list=form.cleaned_data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME], ticket=form.cleaned_data[form_consts.Common.TICKET_VARIABLE_NAME], inherited_source=inherited_source, is_return_only_md5=False, backdoor_name=backdoor_name, backdoor_version=backdoor_version, description=description) except ZipFileError, zfe: return render(request, 'file_upload_response.html', {'response': json.dumps({'success': False, 'message': zfe.value})}) else: # zip file upload, etc; result is a list of strings (1 hash per file) if len(result) > 0 and not isinstance(result[0], dict): filedata = request.FILES['filedata'] message = ('<a href="%s">View Uploaded Samples.</a>' % reverse('crits-samples-views-view_upload_list', args=[filedata.name, result])) response = {'success': True, 'message': message } md5_response = result # regular file upload; result is a list with a single dict else: response['success'] = result[0].get('success', False) response['message'] = result[0].get('message', response.get('message')) try: md5_response = [result[0].get('object').md5] except: md5_response = None if response['success']: if request.POST.get('email') and md5_response: for s in md5_response: email_errmsg = mail_sample(s, [request.user.email]) if email_errmsg is not None: msg = "<br>Error emailing sample %s: %s\n" % (s, email_errmsg) response['message'] = response['message'] + msg if reload_page: response['redirect_url'] = reverse('crits-samples-views-detail', args=[related_md5]) return render(request, "file_upload_response.html", {'response': json.dumps(response)}) else: if related_md5: #if this is a 'related' upload, hide field so it doesn't reappear form.fields['related_md5'].widget = forms.HiddenInput() return render(request, 'file_upload_response.html', {'response': json.dumps({'success': False, 'form': form.as_table()})})