def activate_detection(detection, data, pass_condition): with open(detection, 'r') as fh: parsed_detection = yaml.safe_load(fh) # Returns pipeline only for SSA detections if parsed_detection['type'] == "SSA": pipeline = extract_pipeline(parsed_detection['search'], data, pass_condition) return pipeline else: log(logging.WARN, "Not a SSA. It will be skipped.", parsed_detection['name']) return None
def assert_results(pass_condition, events): if len(pass_condition) == 0: log(logging.ERROR, "Empty pass_condition") return False try: lexer = assertions_parser.AssertionLexer() parser = assertions_parser.AssertionParser(events) return parser.parse(lexer.tokenize(pass_condition)) except SyntaxError: log( logging.ERROR, "pass_condition not in a language that assert_result can understand", pass_condition) return False
def _exit(code, passed, skipped, failed): total_passed = len(passed) total_failed = len(failed) log(logging.DEBUG, "Skipped tests %d" % len(skipped), "\n".join(skipped)) log(logging.INFO, "Passed tests (%d/%d)" % (total_passed, total_passed + total_failed), "\n".join(passed)) log(logging.INFO, "Failed tests (%d/%d)" % (total_failed, total_passed + total_failed), "\n".join(failed)) exit(code)
def build_humvee(path): if not os.path.exists(path): os.mkdir(path) latest_humvee_object = get_latest_humvee_object() humvee_path = "%s/humvee.jar" % path humvee_sha256 = "" if os.path.exists(humvee_path): with open(humvee_path, 'rb') as jar_fh: humvee_sha256 = hashlib.sha256(jar_fh.read()).hexdigest() log(logging.DEBUG, "Current local checksum of Humvee", detail=humvee_sha256) if humvee_sha256 != latest_humvee_object['checksums']['sha256']: log(logging.INFO, "Downloading Latest Humvee") log(logging.DEBUG, "Humvee details", detail=latest_humvee_object) #urllib.request.urlretrieve(latest_humvee_object['downloadUri'], humvee_path) with open(humvee_path, 'wb') as f: f.write(get(latest_humvee_object['downloadUri']).content) else: log(logging.DEBUG, "Already latest checksum %s" % humvee_sha256, detail=latest_humvee_object)
def test_detection(test, args): with open(test, 'r') as fh: test_desc = yaml.safe_load(fh) if (test_desc is not None) and ('name' in test_desc) and ('tests' in test_desc): name = test_desc['name'] # Download data to temporal folder for unit in test_desc['tests']: detection = get_detection(unit) if detection['type'] == 'streaming': log(logging.INFO, "Testing %s" % name) # Prepare data data_dir = tempfile.TemporaryDirectory( prefix="data", dir=get_path("%s" % SSML_CWD)) detection_file = get_path("../detections/%s" % unit['file']) if unit['attack_data'] is None or len( unit['attack_data']) == 0: log(logging.ERROR, "No dataset in testing file in %s" % test) return FAILED test_data = pull_data(unit, data_dir.name) # Extract pipeline and remove SSA decorations input_data = test_data[list(test_data.keys())[0]] spl2 = extract_pipeline(detection['search'], input_data, unit['pass_condition']) if args.debug: log(logging.DEBUG, "Test SPL2 query", detail=spl2) # will use always the same data file. Still we can't handle multiple datasets in desc file with open(input_data, 'r') as test_data_fh: log(logging.DEBUG, "Sample testing data", detail="\n".join( test_data_fh.readlines()[:10])) if spl2 is not None: # Preparing Execution spl2_file = os.path.join(data_dir.name, "test.spl2") test_out = "%s.out" % spl2_file test_status = "%s.status" % test_out with open(spl2_file, 'w') as spl2_fh: spl2_fh.write(spl2) # Execute SPL2 log(logging.INFO, "Humvee test %s" % unit['name']) try: subprocess.run([ "/usr/bin/java", "-jar", get_path("%s/humvee.jar" % SSML_CWD), 'cli', '-i', spl2_file, '-o', test_out ], stderr=subprocess.DEVNULL, timeout=TEST_TIMEOUT) except TimeoutError: log(logging.ERROR, "%s test timeout" % unit['name']) return FAILED # Validate that it can run with open(test_status, "r") as test_status_fh: status = '\n'.join(test_status_fh.readlines()) if status == "OK\n": log(logging.INFO, "%s executed without issues" % unit['name']) else: log(logging.ERROR, "Detection %s can not be executed" % detection_file, detail=status) log(logging.ERROR, "Faulty SPL2 with errors", detail=spl2) return FAILED # Validate the results with open(test_out, 'r') as test_out_fh: res = test_out_fh.readlines() log(logging.DEBUG, "Output events sample (%d/%d)" % (len(res[:10]), len(res)), detail="\n".join(res[:10])) if assert_results(unit['pass_condition'], res): log(logging.DEBUG, "Passed test %s" % unit['name']) else: log(logging.ERROR, "Did not pass condition:", unit['pass_condition']) return FAILED else: log(logging.DEBUG, "Not an SSA test, skipping testing file", unit['name']) return SKIPPED else: log(logging.WARN, "Not a testing file", test) return SKIPPED return PASSED