def add_new_screenshot(request): """ Add a new screenshot. :param request: The Django request. :type request: :class:`django.http.HttpRequest` :returns: :class:`django.http.HttpResponse` """ analyst = request.user.username description = request.POST.get('description', None) reference = request.POST.get('reference', None) method = request.POST.get('method', None) tags = request.POST.get('tags', None) source = request.POST.get('source', None) oid = request.POST.get('oid', None) otype = request.POST.get('otype', None) screenshot_ids = request.POST.get('screenshot_ids', None) screenshot = request.FILES.get('screenshot', None) result = add_screenshot(description, tags, source, method, reference, analyst, screenshot, screenshot_ids, oid, otype) return HttpResponse(json.dumps(result), mimetype="application/json")
def add_new_screenshot(request): """ Add a new screenshot. :param request: The Django request. :type request: :class:`django.http.HttpRequest` :returns: :class:`django.http.HttpResponse` """ user = request.user description = request.POST.get('description', None) reference = request.POST.get('source_reference', None) method = request.POST.get('source_method', None) tlp = request.POST.get('source_tlp', None) tags = request.POST.get('tags', None) source = request.POST.get('source_name', None) oid = request.POST.get('oid', None) otype = request.POST.get('otype', None) screenshot_ids = request.POST.get('screenshot_ids', None) screenshot = request.FILES.get('screenshot', None) acl = get_acl_object(otype) if user.has_access_to(acl.SCREENSHOTS_ADD): result = add_screenshot(description, tags, source, method, reference, tlp, user.username, screenshot, screenshot_ids, oid, otype) else: result = { "success": False, "message": "User does not have permission to add screenshots." } return HttpResponse(json.dumps(result), content_type="application/json")
def add_new_screenshot(request): """ Add a new screenshot. :param request: The Django request. :type request: :class:`django.http.HttpRequest` :returns: :class:`django.http.HttpResponse` """ user = request.user description = request.POST.get('description', None) reference = request.POST.get('source_reference', None) method = request.POST.get('source_method', None) tlp = request.POST.get('source_tlp', None) tags = request.POST.get('tags', None) source = request.POST.get('source_name', None) oid = request.POST.get('oid', None) otype = request.POST.get('otype', None) screenshot_ids = request.POST.get('screenshot_ids', None) screenshot = request.FILES.get('screenshot', None) acl = get_acl_object(otype) if user.has_access_to(acl.SCREENSHOTS_ADD): result = add_screenshot(description, tags, source, method, reference, tlp, user.username, screenshot, screenshot_ids, oid, otype) else: result = {"success":False, "message":"User does not have permission to add screenshots."} return HttpResponse(json.dumps(result), content_type="application/json")
def process_screenshots(self, screenshots): archive = zipfile.ZipFile(io.BytesIO(screenshots)) names = archive.namelist() for name in names: screenshot = archive.read(name) ret = add_screenshot(description='Screenshot from Joe Sandbox', tags=[], source=get_user_organization(self.current_task.user), method=self.name, reference=self.obj.filename, tlp=self.obj.tlp, analyst=str(self.current_task.user), screenshot=io.BytesIO(screenshot), screenshot_ids=[], oid=str(self.obj.id), otype=self.obj._meta['crits_type']) if ret['success']: md5 = hashlib.md5(screenshot).hexdigest() self._add_result("Screenshots", "Screenshot", {'md5': md5}) else: self._warning(ret["message"]) self._notify()
def obj_create(self, bundle, **kwargs): """ Handles creating Screenshots through the API. :param bundle: Bundle containing the information to create the Screenshot. :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 ('ids', 'screenshot'): raise BadRequest('Not a valid upload type.') if type_ == 'ids': screenshot_ids = bundle.data.get('screenshot_ids', None) screenshot = None elif type_ == 'screenshot': screenshot = bundle.data.get('filedata', None) screenshot_ids = None if not screenshot: raise BadRequest( "Upload type of 'screenshot' but no file uploaded.") description = bundle.data.get('description', None) tags = bundle.data.get('tags', None) source = bundle.data.get('source', None) method = bundle.data.get('method', None) reference = bundle.data.get('reference', None) oid = bundle.data.get('oid', None) otype = bundle.data.get('otype', None) if not oid and not otype and not source and not (screenshot or screenshot_ids): raise BadRequest("You must provide a valid set of information.") result = add_screenshot(description, tags, source, method, reference, analyst, screenshot, screenshot_ids, oid, otype) if result['success']: return bundle else: err = result['message'] raise BadRequest('Unable to create screenshot from data. %s' % err)
def obj_create(self, bundle, **kwargs): """ Handles creating Screenshots through the API. :param bundle: Bundle containing the information to create the Screenshot. :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 ('ids', 'screenshot'): raise BadRequest('Not a valid upload type.') if type_ == 'ids': screenshot_ids = bundle.data.get('screenshot_ids', None) screenshot = None elif type_ == 'screenshot': screenshot = bundle.data.get('filedata', None) screenshot_ids = None if not screenshot: raise BadRequest("Upload type of 'screenshot' but no file uploaded.") description = bundle.data.get('description', None) tags = bundle.data.get('tags', None) source = bundle.data.get('source', None) method = bundle.data.get('method', None) reference = bundle.data.get('reference', None) oid = bundle.data.get('oid', None) otype = bundle.data.get('otype', None) if not oid and not otype and not source and not (screenshot or screenshot_ids): raise BadRequest("You must provide a valid set of information.") result = add_screenshot(description, tags, source, method, reference, analyst, screenshot, screenshot_ids, oid, otype) if result['success']: return bundle else: err = result['message'] raise BadRequest('Unable to create screenshot from data. %s' % err)
def run(self, obj, config): self.config = config self.obj = obj obj.filedata.seek(0) data8 = obj.filedata.read(8) obj.filedata.seek(0) if not obj.is_pdf() and not data8.startswith("\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1"): self._debug("preview image started.") try: ofile = io.BytesIO() obj.filedata.seek(0) im = Image.open(io.BytesIO(obj.filedata.read())) # if it's a PNG, then let's convert it to something else and then back to PNG if im.format == 'PNG': tfile = io.BytesIO() im.save(tfile, format='WebP') tfile.seek(0) Image.open(io.BytesIO(tfile.read())).save(ofile, format='PNG', optimize=True) else: im.save(ofile,'PNG', optimize=True) obj.filedata.seek(0) ofile.seek(0) res = add_screenshot(description='Render of an image file', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=ofile, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id') ) ) except IOError as e: self._error("Exception while reading: %s" % str(e)) return False self._add_result('preview', res.get('id'), {'Message': res.get('message')}) return True elif data8.startswith("\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1"): obj.filedata.seek(0) self._debug("preview DOC started.") pdftoppm_path = self.config.get("pdftoppm_path", "/usr/bin/pdftoppm") antiword_path = self.config.get("antiword_path", "/usr/bin/antiword") # The _write_to_file() context manager will delete this file at the # end of the "with" block. with self._write_to_file() as tmp_file: (working_dir, filename) = os.path.split(tmp_file) pdf_fpath = os.path.join(working_dir,'test.pdf') with open(pdf_fpath, 'wb+') as pdf_file: new_env = dict(os.environ) # Copy current environment new_env['LANG'] = 'en_US' #env=dict(os.environ, LANG="en_US") proc1 = subprocess.Popen([antiword_path, '-r', '-s', '-a', 'letter', tmp_file],env=new_env, stdout=pdf_file, stderr=subprocess.PIPE, cwd=working_dir) pdf_file, serr = proc1.communicate() #self._warning("antiOut:%s" % pdf_file) if serr: self._warning("Antiword warning: %s" % serr) if proc1.returncode: msg = ("Antiword could not process the file.") self._error(msg) return False outy = 'page' args = [pdftoppm_path, '-png', pdf_fpath, outy] # pdftoppm does not generate a lot of output, so we should not have to # worry about this hanging because the buffer is full proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=working_dir) output, serr = proc.communicate() for filen in sorted(os.listdir(working_dir)): if filen.endswith(".png"): fileh = open(os.path.join(working_dir,filen), "rb") raw_hash = md5(fileh.read()).hexdigest() fileh.seek(0) res = add_screenshot(description='Render of a pdf document', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=fileh, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id') ) ) self._add_result('preview', res.get('id'), {'Message': res.get('message')}) self._info("id:%s, file: %s" % (res.get('id'), os.path.join(working_dir,filen))) # Note that we are redirecting STDERR to STDOUT, so we can ignore # the second element of the tuple returned by communicate(). #self._warning("Out:%s" % output) if serr: self._warning("Pdftoppm warning: %s" % serr) if proc.returncode: msg = ("Pdftoppm could not process the file.") self._error(msg) return False else: return True else: obj.filedata.seek(0) self._debug("preview PDF started\n") pdftoppm_path = self.config.get("pdftoppm_path", "/usr/bin/pdftoppm") # The _write_to_file() context manager will delete this file at the # end of the "with" block. with self._write_to_file() as tmp_file: (working_dir, filename) = os.path.split(tmp_file) outy = 'page' args = [pdftoppm_path, '-png', tmp_file, outy] # pdftoppm does not generate a lot of output, so we should not have to # worry about this hanging because the buffer is full proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=working_dir) #stderr=subprocess.STDOUT, cwd=working_dir) serr, output = proc.communicate() for filen in sorted(os.listdir(working_dir)): if filen.endswith(".png"): fileh = open(os.path.join(working_dir,filen), "rb") raw_hash = md5(fileh.read()).hexdigest() fileh.seek(0) res = add_screenshot(description='Render of a pdf document', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=fileh, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id') ) ) self._add_result('preview', res.get('id'), {'Message': res.get('message')}) self._info("id:%s, file: %s" % (res.get('id'), os.path.join(working_dir,filen))) # Note that we are redirecting STDERR to STDOUT, so we can ignore # the second element of the tuple returned by communicate(). if serr: self._warning("Pdftoppm warning: %s" % serr) if proc.returncode: msg = ("pdftoppm could not process the file.") self._warning(msg) return False return True
def run(self, obj, config): self.config = config self.obj = obj obj.filedata.seek(0) data8 = obj.filedata.read(8) obj.filedata.seek(0) if not obj.is_pdf() and not data8.startswith( "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1"): self._debug("preview image started.") try: ofile = io.BytesIO() obj.filedata.seek(0) im = Image.open(io.BytesIO(obj.filedata.read())) # if it's a PNG, then let's convert it to something else and then back to PNG if im.format == 'PNG': tfile = io.BytesIO() im.save(tfile, format='WebP') tfile.seek(0) Image.open(io.BytesIO(tfile.read())).save(ofile, format='PNG', optimize=True) else: im.save(ofile, 'PNG', optimize=True) obj.filedata.seek(0) ofile.seek(0) res = add_screenshot(description='Render of an image file', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=ofile, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id'))) except IOError as e: self._error("Exception while reading: %s" % str(e)) return False self._add_result('preview', res.get('id'), {'Message': res.get('message')}) return True elif data8.startswith("\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1"): obj.filedata.seek(0) self._debug("preview DOC started.") pdftoppm_path = self.config.get("pdftoppm_path", "/usr/bin/pdftoppm") antiword_path = self.config.get("antiword_path", "/usr/bin/antiword") # The _write_to_file() context manager will delete this file at the # end of the "with" block. with self._write_to_file() as tmp_file: (working_dir, filename) = os.path.split(tmp_file) pdf_fpath = os.path.join(working_dir, 'test.pdf') with open(pdf_fpath, 'wb+') as pdf_file: new_env = dict(os.environ) # Copy current environment new_env['LANG'] = 'en_US' #env=dict(os.environ, LANG="en_US") proc1 = subprocess.Popen( [antiword_path, '-r', '-s', '-a', 'letter', tmp_file], env=new_env, stdout=pdf_file, stderr=subprocess.PIPE, cwd=working_dir) pdf_file, serr = proc1.communicate() #self._warning("antiOut:%s" % pdf_file) if serr: self._warning("Antiword warning: %s" % serr) if proc1.returncode: msg = ("Antiword could not process the file.") self._error(msg) return False outy = 'page' args = [pdftoppm_path, '-png', pdf_fpath, outy] # pdftoppm does not generate a lot of output, so we should not have to # worry about this hanging because the buffer is full proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=working_dir) output, serr = proc.communicate() for filen in sorted(os.listdir(working_dir)): if filen.endswith(".png"): fileh = open(os.path.join(working_dir, filen), "rb") raw_hash = md5(fileh.read()).hexdigest() fileh.seek(0) res = add_screenshot( description='Render of a pdf document', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=fileh, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get( 'success') == True: self._warning( "res-message: %s id:%s" % (res.get('message'), res.get('id'))) self._add_result( 'preview', res.get('id'), {'Message': res.get('message')}) self._info("id:%s, file: %s" % (res.get('id'), os.path.join(working_dir, filen))) # Note that we are redirecting STDERR to STDOUT, so we can ignore # the second element of the tuple returned by communicate(). #self._warning("Out:%s" % output) if serr: self._warning("Pdftoppm warning: %s" % serr) if proc.returncode: msg = ("Pdftoppm could not process the file.") self._error(msg) return False else: return True else: obj.filedata.seek(0) self._debug("preview PDF started\n") pdftoppm_path = self.config.get("pdftoppm_path", "/usr/bin/pdftoppm") # The _write_to_file() context manager will delete this file at the # end of the "with" block. with self._write_to_file() as tmp_file: (working_dir, filename) = os.path.split(tmp_file) outy = 'page' args = [pdftoppm_path, '-png', tmp_file, outy] # pdftoppm does not generate a lot of output, so we should not have to # worry about this hanging because the buffer is full proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=working_dir) #stderr=subprocess.STDOUT, cwd=working_dir) serr, output = proc.communicate() for filen in sorted(os.listdir(working_dir)): if filen.endswith(".png"): fileh = open(os.path.join(working_dir, filen), "rb") raw_hash = md5(fileh.read()).hexdigest() fileh.seek(0) res = add_screenshot( description='Render of a pdf document', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=fileh, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id'))) self._add_result('preview', res.get('id'), {'Message': res.get('message')}) self._info( "id:%s, file: %s" % (res.get('id'), os.path.join(working_dir, filen))) # Note that we are redirecting STDERR to STDOUT, so we can ignore # the second element of the tuple returned by communicate(). if serr: self._warning("Pdftoppm warning: %s" % serr) if proc.returncode: msg = ("pdftoppm could not process the file.") self._warning(msg) return False return True
def run(self, obj, config): self.config = config self.obj = obj user = self.current_task.user tlp_value = self.config.get("tlp_value", "tlp_value") url = obj['value'] if not (obj._meta['crits_type'] == 'Indicator' and obj['ind_type'] == 'URI'): self._error('This object type cannot use service Url analysis.') return False #verify url http or https if url.startswith('https://') or url.startswith('http://'): #put url in file dcap = dict(DesiredCapabilities.PHANTOMJS) dcap["phantomjs.page.settings.userAgent"] = ( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36" ) driver = webdriver.PhantomJS(desired_capabilities=dcap, service_args=[ '--ignore-ssl-errors=true', '--ssl-protocol=any', '--web-security=false' ]) driver.set_window_size(1024, 768) driver.set_page_load_timeout(30) driver.get(url) time.sleep(3) #driver.save_screenshot('testing1.png') screen = driver.get_screenshot_as_png() ofile = io.BytesIO() im = Image.open(StringIO.StringIO(screen)) im.save(ofile, 'PNG', optimize=True) ofile.seek(0) res = add_screenshot(description='Render of a website URL', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.user.username, screenshot=ofile, screenshot_ids=None, oid=obj.id, tlp=tlp_value, otype="Indicator") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id'))) self._add_result('ScreenShot URL', res.get('id'), {'Message': res.get('message')}) #parse HAR har = driver.get_log('har') if type(har) is list and har: if type(har[0]) is dict and 'message' in har[0]: #change unicode to json try: har[0]['message'] = json.loads(har[0]['message']) except: self._warning('Har log error to parse json') if type(har[0]['message'] ) is dict and 'log' in har[0]['message'] and type( har[0]['message']['log'] ) is dict and 'pages' in har[0]['message']['log']: if type(har[0]['message']['log']['pages'] ) is list and har[0]['message']['log'][ 'pages'] and type(har[0]['message']['log'] ['pages'][0]) is dict: title = 'Result of ' if 'id' in har[0]['message']['log']['pages'][0]: title += har[0]['message']['log']['pages'][0][ 'id'] if 'title' in har[0]['message']['log']['pages'][0]: self._add_result( title, 'Title', { 'value': har[0]['message']['log']['pages'][0] ['title'] }) #parse each request and response if 'entries' in har[0]['message']['log'] and type( har[0]['message']['log']['entries'] ) is list and har[0]['message']['log']['entries']: count = 1 type_r = ['cookies', 'queryString', 'headers'] type_rs = ['content', 'timings', 'cache'] for elem_rr in har[0]['message']['log']['entries']: for k, v in elem_rr.iteritems(): if type(v) is not dict: self._add_result( title + ' -- Informations Request & Response num:' + str(count), k, {'value': v}) for k, v in elem_rr.iteritems(): if type(v) is dict: for kx, vx in v.iteritems(): self._add_result( title + ' -- Informations Request & Response num:' + str(count) + ' -- ' + str(k), kx, {'value': vx}) count += 1 #save page source in rawdata if not user.has_access_to(RawDataACL.WRITE): self._info(driver.page_source.encode('utf8')) else: #can write result = handle_raw_data_file( driver.page_source.encode('utf8'), obj.source, user=self.current_task.user, description="Code page for URL: %s" % url, title=url, data_type="Text", tool_name=self.name, tool_version=self.version, tool_details=self.description) if result['success']: obj.add_relationship( result['object'], RelationshipTypes.CONTAINED_WITHIN, analyst=self.current_task.user.username, rel_reason="Extracted from URI") obj.save() self._add_result( 'Code Page', url, { 'RawData TLO ID': result['_id'], 'md5 file': md5(driver.page_source.encode('utf8')).hexdigest(), 'simhash': str(simhash(driver.page_source.encode('utf8'))) }) driver.close() driver.service.process.terminate() time.sleep(1) #get certificat information - ref: https://stackoverflow.com/questions/30862099/how-can-i-get-certificate-issuer-information-in-python #because selenium not functionnality if url.startswith('https://'): try: host = urlparse(url).hostname port = urlparse(url).port if (port is None): port = 443 s = socks.socksocket() if settings.HTTP_PROXY: type_proxy = socks.PROXY_TYPE_SOCKS5 if settings.HTTP_PROXY.startswith('http://'): type_proxy = socks.PROXY_TYPE_HTTP s.setproxy(type_proxy, urlparse(settings.HTTP_PROXY).hostname, port=urlparse(settings.HTTP_PROXY).port) s.connect((host, port)) ss = ssl.wrap_socket(s) pem_data = ssl.DER_cert_to_PEM_cert(ss.getpeercert(True)) ss.close() s.close() cert = M2Crypto.X509.load_cert_string(pem_data) #put ssl information self._add_result( 'SSL informations', 'Subject', {'value': str(cert.get_subject().as_text())}) self._add_result( 'SSL informations', 'Issuer', {'value': str(cert.get_issuer().as_text())}) self._add_result('SSL informations', 'Version', {'value': str(cert.get_version())}) self._add_result('SSL informations', 'Date before', {'value': str(cert.get_not_before())}) self._add_result('SSL informations', 'Date after', {'value': str(cert.get_not_after())}) self._add_result('SSL informations', 'Serial Number', {'value': str(cert.get_serial_number())}) self._add_result('SSL informations', 'Verify', {'value': str(cert.verify())}) self._add_result('SSL informations', 'Fingerprint MD5', {'value': str(cert.get_fingerprint())}) for i in range(0, cert.get_ext_count()): self._add_result( 'SSL informations Extension', str(cert.get_ext_at(i).get_name()), {'value': str(cert.get_ext_at(i).get_value())}) #https://www.heikkitoivonen.net/m2crypto/api/M2Crypto.X509-module.html except: self._error('Error: get certificate informations.') self._info(str(cert)) driver.service.process.kill() driver.quit() self._info('END')
def obj_create(self, bundle, **kwargs): """ Handles creating Screenshots through the API. :param bundle: Bundle containing the information to create the Screenshot. :type bundle: Tastypie Bundle object. :returns: HttpResponse. """ user = bundle.request.user type_ = bundle.data.get('upload_type', None) content = {'return_code': 1, 'type': 'Screenshot'} if not type_: content['message'] = 'Must provide an upload type.' self.crits_response(content) if type_ not in ('ids', 'screenshot'): content['message'] = 'Not a valid upload type.' self.crits_response(content) if type_ == 'ids': screenshot_ids = bundle.data.get('screenshot_ids', None) screenshot = None elif type_ == 'screenshot': screenshot = bundle.data.get('filedata', None) screenshot_ids = None if not screenshot: content['message'] = "Upload type of 'screenshot' but no file uploaded." self.crits_response(content) description = bundle.data.get('description', None) tags = bundle.data.get('tags', None) source = bundle.data.get('source', None) method = bundle.data.get('method', None) reference = bundle.data.get('reference', None) tlp = bundle.data.get('tlp', 'amber') oid = bundle.data.get('oid', None) otype = bundle.data.get('otype', None) if not oid or not otype or not source or not (screenshot or screenshot_ids): content['message'] = "You must provide a valid set of information." self.crits_response(content) acl = get_acl_object(otype) if not user.has_access_to(acl.SCREENSHOTS_ADD): content['message'] = 'User does not have permission to create Object.' self.crits_response(content) result = add_screenshot(description, tags, source, method, reference, tlp, user.username, screenshot, screenshot_ids, oid, otype) if result.get('message'): content['message'] = result.get('message') if result.get('id'): url = reverse('api_dispatch_detail', kwargs={'resource_name': 'screenshots', 'api_name': 'v1', 'pk': result.get('id')}) content['url'] = url content['id'] = result.get('id') if result['success']: content['return_code'] = 0 self.crits_response(content)
def obj_create(self, bundle, **kwargs): """ Handles creating Screenshots through the API. :param bundle: Bundle containing the information to create the Screenshot. :type bundle: Tastypie Bundle object. :returns: HttpResponse. """ user = bundle.request.user type_ = bundle.data.get('upload_type', None) content = {'return_code': 1, 'type': 'Screenshot'} if not type_: content['message'] = 'Must provide an upload type.' self.crits_response(content) if type_ not in ('ids', 'screenshot'): content['message'] = 'Not a valid upload type.' self.crits_response(content) if type_ == 'ids': screenshot_ids = bundle.data.get('screenshot_ids', None) screenshot = None elif type_ == 'screenshot': screenshot = bundle.data.get('filedata', None) screenshot_ids = None if not screenshot: content[ 'message'] = "Upload type of 'screenshot' but no file uploaded." self.crits_response(content) description = bundle.data.get('description', None) tags = bundle.data.get('tags', None) source = bundle.data.get('source', None) method = bundle.data.get('method', None) reference = bundle.data.get('reference', None) tlp = bundle.data.get('tlp', 'amber') oid = bundle.data.get('oid', None) otype = bundle.data.get('otype', None) if not oid or not otype or not source or not (screenshot or screenshot_ids): content['message'] = "You must provide a valid set of information." self.crits_response(content) acl = get_acl_object(otype) if not user.has_access_to(acl.SCREENSHOTS_ADD): content[ 'message'] = 'User does not have permission to create Object.' self.crits_response(content) result = add_screenshot(description, tags, source, method, reference, tlp, user.username, screenshot, screenshot_ids, oid, otype) if result.get('message'): content['message'] = result.get('message') if result.get('id'): url = reverse('api_dispatch_detail', kwargs={ 'resource_name': 'screenshots', 'api_name': 'v1', 'pk': result.get('id') }) content['url'] = url content['id'] = result.get('id') if result['success']: content['return_code'] = 0 self.crits_response(content)
def run(self, obj, config): self.config = config self.obj = obj if not obj.is_pdf(): try: ofile = io.BytesIO() obj.filedata.seek(0) im = Image.open(io.BytesIO(obj.filedata.read())) # if it's a PNG, then let's convert it to something else and then back to PNG if im.format == 'PNG': tfile = io.BytesIO() im.save(tfile, 'TIFF') tfile.seek(0) Image.open(io.BytesIO(tfile.read())).save(ofile, 'PNG', optimize=True) else: im.save(ofile,'PNG', optimize=True) obj.filedata.seek(0) ofile.seek(0) res = add_screenshot(description='Render of an image file', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=ofile, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id') ) ) except IOError as e: self._error("Exception while reading: %s" % str(e)) self._add_result('preview', res.get('id'), {'Message': res.get('message')}) return else: self._debug("preview started\n") pdftoppm_path = self.config.get("pdftoppm_path", "/usr/bin/pdftoppm") # The _write_to_file() context manager will delete this file at the # end of the "with" block. with self._write_to_file() as tmp_file: (working_dir, filename) = os.path.split(tmp_file) outy = 'page' args = [pdftoppm_path, '-png', tmp_file, outy] # pdftoppm does not generate a lot of output, so we should not have to # worry about this hanging because the buffer is full proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=working_dir) output = proc.communicate()[0] for filen in sorted(os.listdir(working_dir)): if filen.endswith(".png"): fileh = open(os.path.join(working_dir,filen), "rb") raw_hash = md5(fileh.read()).hexdigest() fileh.seek(0) res = add_screenshot(description='Render of a pdf document', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.username, screenshot=fileh, screenshot_ids=None, oid=obj.id, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id') ) ) self._add_result('preview', res.get('id'), {'Message': res.get('message')}) self._warning("id:%s, file: %s" % (res.get('id'), os.path.join(working_dir,filen))) # Note that we are redirecting STDERR to STDOUT, so we can ignore # the second element of the tuple returned by communicate(). self._warning("Out:%s" % output) if proc.returncode: msg = ("pdftoppm could not process the file.") self._warning(msg) return return
def run(self, obj, config): if bool(re.search(r'^\d+$', config['import_yara_score'])): logger.error("SFA COnfig SCORE YARA dont format interger") self._error("SFA COnfig SCORE YARA dont format interger") return "" obj.filedata.seek(0) data8 = obj.filedata.read(8) obj.filedata.seek(0) user = self.current_task.user self.config = config self.obj = obj self._info("SFA started") tlp_value = self.config.get("tlp_value", "tlp_value") sfa_api = self.config.get("sfa_api", '') key_api = self.config.get("key_api", '') if not sfa_api: self._error("No URI for SFA API found") return if not key_api: self._error("No API KEY found") return response_dict = {} proxies = { "http": None, "https": None, } headers = {"x-api-key": key_api} #IF URL if (obj._meta['crits_type'] == 'Indicator' and obj['ind_type'] == 'URI'): self._info("Analyse URI on API: %s" % str(sfa_api)) url = obj['value'] try: headers['Content-Type'] = 'application/json' response = requests.post(sfa_api + 'api/sfa_check_url', json={"url": url}, verify=False, proxies=proxies, headers=headers) except Exception as e: logger.error("SFA API: network connection error (%s)" % str(e)) self._error("Network connection error checking SFA API (%s)" % str(e)) return if response.status_code == 200: try: jsonc = response.content response_dict = json.loads(jsonc) except Exception as e: logger.error("SFA API return bad format json (%s)" % str(e)) self._error("SFA API return bad format json (%s)" % str(e)) return else: logger.error("SFA API return code error (%s)" % str(response.status_code)) self._error("SFA API return code error (%s)" % str(response.status_code)) return #IF FILE else: #write out the sample stored in the db to a tmp file self._info("Analyse Sample on API: %s" % str(sfa_api)) with self._write_to_file() as tmp_file: with open(tmp_file, 'r') as tmpfo: files = {'file': tmpfo} #SFA is not on internet, local service try: response = requests.post(sfa_api + 'api/sfa_check_file', files=files, verify=False, proxies=proxies, headers=headers) except Exception as e: logger.error("SFA API: network connection error (%s)" % str(e)) self._error( "Network connection error checking SFA API (%s)" % str(e)) return #print str(r.content) # Execute GET request if response.status_code == 200: try: jsonc = response.content response_dict = json.loads(jsonc) except Exception as e: logger.error( "SFA API return bad format json (%s)" % str(e)) self._error("SFA API return bad format json (%s)" % str(e)) return else: logger.error("SFA API return code error (%s)" % str(response.status_code)) self._error("SFA API return code error (%s)" % str(response.status_code)) return #make temp file for get json result and graph self._info("Reponse request:" + str(response_dict)) if 'risk_score' in response_dict: risk = response_dict['risk_score'] if risk: self._add_result("Risk Score of Sample", str(risk), {}) if 'trace-serr.debug' in response_dict: trace_serr = download(self, response_dict['trace-serr.debug']) if trace_serr: self._info(trace_serr) if 'trace-sout.debug' in response_dict and config['debug_log']: trace_sout = download(self, response_dict['trace-sout.debug']) if trace_sout: self._info(trace_sout) if 'result.json' in response_dict: result = download(self, response_dict['result.json']) if result: try: result_json = json.loads(result) except Exception as e: logger.error("Analysis JSON result error: (%s)" % str(e)) self._error("Analysis JSON result error: (%s)" % str(e)) parse_result(self, result_json, response_dict, config, None) if 'graph.png' in response_dict: graph = download(self, response_dict['graph.png']) if graph: dirtmp = tempfile._get_default_tempdir() file_png = dirtmp + '/' + next( tempfile._get_candidate_names()) + '.png' with open(file_png, 'w+') as fpng: fpng.write(graph) fpng.seek(0) res = add_screenshot( description='Render of static analysis', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.user.username, screenshot=fpng, screenshot_ids=None, oid=obj.id, tlp=tlp_value, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id'))) self._add_result('Graph analysis', res.get('id'), {'Message': res.get('message')}) self._info("id:%s, file: %s" % (res.get('id'), file_png)) if os.path.isfile(file_png): os.remove(file_png)
def run(self, obj, config): obj.filedata.seek(0) data8 = obj.filedata.read(8) obj.filedata.seek(0) user = self.current_task.user self.config = config self.obj = obj self._debug("ExtractEmbedded started") tlp_value = self.config.get("tlp_value", "tlp_value") clamscan_path = self.config.get( "clamscan_path", os.path.dirname(os.path.realpath(__file__)) + '/static_analysis/clamav-devel/clamscan/clamscan') analysis_path = self.config.get( "analysis_path", os.path.dirname(os.path.realpath(__file__)) + '/static_analysis/analysis.py') yararules_path = self.config.get( "yararules_path", os.path.dirname(os.path.realpath(__file__)) + '/static_analysis/yara_rules/') pattern_path = self.config.get( "pattern_path", os.path.dirname(os.path.realpath(__file__)) + '/static_analysis/pattern.db') coef_path = self.config.get( "coef_path", os.path.dirname(os.path.realpath(__file__)) + '/static_analysis/coef.conf') #write out the sample stored in the db to a tmp file with self._write_to_file() as tmp_file: (working_dir, filename) = os.path.split(tmp_file) new_env = dict(os.environ) # Copy current environment args = [] obj.filedata.seek(0) #make temp file for get json result and graph dirtmp = tempfile._get_default_tempdir() file_png = dirtmp + '/' + next( tempfile._get_candidate_names()) + '.png' file_json = dirtmp + '/' + next( tempfile._get_candidate_names()) + '.json' if os.path.isfile(file_png) or os.path.isfile(file_json): self._warning('Error: File temp exist.') else: #TODO add choice: verbose mode and extracted file emmbed args = [ 'python', analysis_path, '-c', clamscan_path, '-g', '-y', yararules_path, '-p', pattern_path, '-f', tmp_file, '-m', coef_path, '-s', file_png, '-j', file_json ] if config['debug_log']: args = [ 'python', analysis_path, '-c', clamscan_path, '-g', '-y', yararules_path, '-p', pattern_path, '-f', tmp_file, '-m', coef_path, '-s', file_png, '-j', file_json, '-v' ] #verify user can write sample acl_write = user.has_access_to(SampleACL.WRITE) if not acl_write: self._info( "User does not have permission to add Sample Data to CRITs" ) # pdftotext does not generate a lot of output, so we should not have to # worry about this hanging because the buffer is full proc = subprocess.Popen(args, env=new_env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=working_dir) # Note that we are redirecting STDERR to STDOUT, so we can ignore # the second element of the tuple returned by communicate(). output, serr = proc.communicate() #print stderr without message 'empty database file' self._info(output) if serr: self._warning(serr) #run command problem if proc.returncode: msg = ("analysis could not process the file.") self._warning(msg) if os.path.isfile(file_json): os.remove(file_json) if os.path.isfile(file_png): os.remove(file_png) #run command OK else: #add json information and png file result_extract = None if os.path.isfile(file_json): with open(file_json) as data_file: try: result_extract = json.load(data_file) except Exception as e: self._warning("Error to parse json result: " + str(e)) os.remove(file_json) if os.path.isfile(file_png): #add screeshot fileh = open(file_png, "rb") fileh.seek(0) res = add_screenshot( description='Render of analysis embedded files', tags=None, method=self.name, source=obj.source, reference=None, analyst=self.current_task.user.username, screenshot=fileh, screenshot_ids=None, oid=obj.id, tlp=tlp_value, otype="Sample") if res.get('message') and res.get('success') == True: self._warning("res-message: %s id:%s" % (res.get('message'), res.get('id'))) self._add_result('Graph analysis', res.get('id'), {'Message': res.get('message')}) self._info("id:%s, file: %s" % (res.get('id'), file_png)) fileh.close() os.remove(file_png) if type(result_extract) is dict: parse_result(self, result_extract, acl_write, None) if result_extract['TempDirExtract'] and dirtmp in str( result_extract['TempDirExtract'] ) and os.path.isdir( str(result_extract['TempDirExtract'])): #remove dir tmp shutil.rmtree(result_extract['TempDirExtract'])