def wrapper(self: Karton, *args, **kwargs): handler = LocalLogBuffer() try: # Register new log handler self.log.addHandler(handler) method(self, *args, **kwargs) except Exception: self.log.exception("Analysis failed") finally: # Unregister local handler self.log.removeHandler(handler) try: buffer = StringIO() for idx, entry in enumerate(handler.buffer): if idx > 0: buffer.write("\n") buffer.write(json.dumps(entry)) res = LocalResource(object_name, buffer.getvalue(), bucket="drakrun") task_uid = (self.current_task.payload.get("analysis_uid") or self.current_task.uid) res._uid = f"{task_uid}/{res.name}" # Karton rejects empty resources # Ensure that we upload it only when some data was actually generated if buffer.tell() > 0: res.upload(self.backend) except Exception: self.log.exception("Failed to upload analysis logs")
def wrapper(self: Karton, *args, **kwargs): handler = LocalLogBuffer() try: # Register new log handler self.log.addHandler(handler) method(self, *args, **kwargs) except Exception: self.log.exception("Analysis failed") finally: # Unregister local handler self.log.removeHandler(handler) try: buffer = StringIO() for idx, entry in enumerate(handler.buffer): if idx > 0: buffer.write("\n") buffer.write(json.dumps(entry)) res = LocalResource(object_name, buffer.getvalue(), bucket="drakrun") task_uid = self.current_task.payload.get( 'override_uid') or self.current_task.uid res._uid = f"{task_uid}/{res.name}" res.upload(self.backend) except Exception: self.log.exception("Failed to upload analysis logs")
def process(self, task: Task): dumps = task.get_resource("dumps.zip") sample = task.get_resource("sample") with dumps.extract_temporary() as temp: family = self.analyze_dumps(sample, temp) testcase = TestCase.from_json(task.payload["testcase"]) expected_family = testcase.ripped if family is None or expected_family != family: self.log.error( f"Failed to rip {sample.sha256}. Expected {expected_family}, ripped {family}" ) result = 'FAIL' else: self.log.info(f"Ripping {sample.sha256} OK: {family}") result = 'OK' out_res = json.dumps({ "sample": sample.sha256, "family": { "expected": expected_family, "ripped": family }, "result": result }) task = Task({"type": "analysis-test-result", "kind": "drakrun"}) res = LocalResource(name=self.current_task.root_uid, bucket='draktestd', content=out_res) res._uid = res.name task.add_payload("result", res) self.send_task(task)
def upload_artifacts(self, analysis_uid, outdir, subdir=''): for fn in os.listdir(os.path.join(outdir, subdir)): file_path = os.path.join(outdir, subdir, fn) if os.path.isfile(file_path): object_name = os.path.join(analysis_uid, subdir, fn) res_name = os.path.join(subdir, fn) if self.test_run: # If it's a test run upload artifacts to karton-managed bucket # They'll be cleaned up by karton-system resource = LocalResource(name=res_name, path=file_path) else: # If it's not a test run, put them into drakrun bucket resource = LocalResource(name=res_name, bucket='drakrun', path=file_path) resource._uid = object_name yield resource elif os.path.isdir(file_path): yield from self.upload_artifacts(analysis_uid, outdir, os.path.join(subdir, fn))
def upload_artifacts(self, analysis_uid, outdir, subdir=''): for fn in os.listdir(os.path.join(outdir, subdir)): file_path = os.path.join(outdir, subdir, fn) if os.path.isfile(file_path): object_name = os.path.join(analysis_uid, subdir, fn) res_name = os.path.join(subdir, fn) resource = LocalResource(name=res_name, bucket='drakrun', path=file_path) resource._uid = object_name yield resource elif os.path.isdir(file_path): yield from self.upload_artifacts(analysis_uid, outdir, os.path.join(subdir, fn))
def send_raw_analysis(self, sample, outdir, metadata, dumps_metadata, quality): """ Offload drakrun-prod by sending raw analysis output to be processed by drakrun.processor. """ if self.test_run: headers = dict(self.test_headers) else: headers = dict(self.headers) headers["quality"] = quality task = Task(headers, payload=metadata) task.add_payload("sample", sample) task.add_payload("dumps_metadata", dumps_metadata) if self.test_run: task.add_payload("testcase", self.current_task.payload["testcase"]) if self.config.config.getboolean("drakrun", "attach_profiles", fallback=False): self.log.info("Uploading profiles...") task.add_payload("profiles", self.build_profile_payload()) if self.config.config.getboolean( "drakrun", "attach_apiscout_profile", fallback=False ): self.log.info("Uploading static ApiScout profile...") task.add_payload( "static_apiscout_profile.json", LocalResource( name="static_apiscout_profile.json", path=Path(APISCOUT_PROFILE_DIR) / "static_apiscout_profile.json", ), ) self.log.info("Uploading artifacts...") for resource in self.upload_artifacts(self.analysis_uid, outdir): task.add_payload(resource.name, resource) self.send_task(task)