def init(self): self.control = safe_socket(socket.AF_UNIX) self.control.settimeout(None) self.control.setblocking(1) while True: try: self.control.connect(self.control_filename) # self.control.connect(self.control_filename) break except socket_error: pass # time.sleep(0.01) self.kafl_shm_f = os.open(self.bitmap_filename, os.O_RDWR | os.O_SYNC | os.O_CREAT) self.fs_shm_f = os.open(self.payload_filename, os.O_RDWR | os.O_SYNC | os.O_CREAT) open(self.tracedump_filename, "wb").close() os.symlink(self.tracedump_filename, self.config.argument_values['work_dir'] + "/pt_trace_dump_" + self.qemu_id) os.symlink(self.payload_filename, self.config.argument_values['work_dir'] + "/payload_" + self.qemu_id) os.symlink(self.bitmap_filename, self.config.argument_values['work_dir'] + "/bitmap_" + self.qemu_id) # argv_fd = os.open(self.argv_filename, os.O_RDWR | os.O_SYNC | os.O_CREAT) os.ftruncate(self.kafl_shm_f, self.bitmap_size) os.ftruncate(self.fs_shm_f, (128 << 10)) # os.ftruncate(argv_fd, (4 << 10)) self.kafl_shm = mmap.mmap(self.kafl_shm_f, self.bitmap_size, mmap.MAP_SHARED, mmap.PROT_WRITE | mmap.PROT_READ) self.c_bitmap = (ctypes.c_uint8 * self.bitmap_size).from_buffer(self.kafl_shm) self.last_bitmap_wrapper = ExecutionResult(None, None, None, None) self.fs_shm = mmap.mmap(self.fs_shm_f, (128 << 10), mmap.MAP_SHARED, mmap.PROT_WRITE | mmap.PROT_READ) return True
def debug_execution(config, execs, qemu_verbose=False, notifiers=True): log_debug("Starting debug execution...(%d rounds)" % execs) payload_file = config.argument_values["input"] null_hash = ExecutionResult.get_null_hash( config.config_values['BITMAP_SHM_SIZE']) q = qemu(1337, config, debug_mode=True, notifiers=notifiers) assert q.start(), "Failed to start Qemu?" start = time.time() for i in range(execs): log_debug("Launching payload %d/%d.." % (i + 1, execs)) if i % 3 == 0: q.set_payload(read_binary_file(payload_file)) # time.sleep(0.01 * rand.int(0, 9)) # a = str(q.send_payload()) # hexdump(a) result = q.send_payload() current_hash = result.hash() if null_hash == current_hash: log_debug("Feedback Hash: " + str(current_hash) + common.color.WARNING + " (WARNING: Zero hash found!)" + common.color.ENDC) else: log_debug("Feedback Hash: " + str(current_hash)) #log_debug("Full hexdump:\n" + hexdump(result.copy_to_array())) if result.is_crash(): q.reload() q.shutdown() end = time.time() print("Performance: " + str(execs / (end - start)) + "t/s") return 0
def main(): global null_hash KAFL_ROOT = os.path.dirname(os.path.realpath(__file__)) + "/" KAFL_CONFIG = KAFL_ROOT + "kafl.ini" print("<< " + common.color.BOLD + common.color.OKGREEN + " kAFL Coverage Analyzer " + common.color.ENDC + ">>\n") if not self_check(KAFL_ROOT): return -1 config = DebugConfiguration(KAFL_CONFIG) if not post_self_check(config): return -1 verbose = config.argument_values['v'] if verbose: enable_logging(config.argument_values["work_dir"]) data_dir = config.argument_values["input"] null_hash = ExecutionResult.get_null_hash( config.config_values['BITMAP_SHM_SIZE']) print(" Scanning target data_dir »%s«..." % data_dir) input_list = get_inputs_by_time(data_dir) trace_dir = generate_traces(config, input_list) if not trace_dir: return -1 trace_parser = TraceParser(trace_dir) trace_parser.parse_trace_list(input_list) trace_parser.gen_reports()
def maybe_insert_program(self, program, exec_res): bitmap_array = exec_res.copy_to_array() bitmap = ExecutionResult.bitmap_from_bytearray(bitmap_array, exec_res.exit_reason, exec_res.performance) bitmap.lut_applied = True # since we received the bitmap from the should_send_to_master, the lut was already applied should_store, new_bytes, new_bits = self.bitmap_storage.should_store_in_queue(bitmap) if should_store and not exec_res.is_crash(): program.set_new_bits(new_bits) program.set_new_bytes(new_bytes) self.optimizer.add(program, bitmap, new_bytes, new_bits)
def send_payload(self, apply_patches=True, timeout_detection=True, max_iterations=10): start_time = time.time() if apply_patches: self.send_enable_patches() else: self.send_disable_patches() self.__debug_send(qemu_protocol.RELEASE) self.crashed = False self.timeout = False self.kasan = False repeat = False value = self.check_recv(timeout_detection=timeout_detection) if value == 1: self.crashed = True self.__debug_recv_expect(qemu_protocol.ACQUIRE) elif value == 2: self.timeout = True self.__debug_print_timeout() cmd = self.__debug_recv() self.__debug_recv_expect(qemu_protocol.ACQUIRE) elif value == 3: self.kasan = True self.__debug_recv_expect(qemu_protocol.ACQUIRE) elif value == 4: repeat = True elif value == 5: repeat = True self.soft_reload() elif value == 6: repeat = True self.soft_reload() elif value == 7: self.timeout= True self.needs_execution_for_patches = False if repeat: if max_iterations != 0: self.send_payload(apply_patches=apply_patches, timeout_detection=timeout_detection, max_iterations=0) res = self.send_payload(apply_patches=apply_patches, timeout_detection=timeout_detection, max_iterations=max_iterations - 1) res.performance = time.time() - start_time() return res self.last_bitmap_wrapper = ExecutionResult(self.c_bitmap, self.bitmap_size, self.exit_reason(), time.time() - start_time) return self.last_bitmap_wrapper
def maybe_insert_node(self, payload, bitmap_array, node_struct): bitmap = ExecutionResult.bitmap_from_bytearray(bitmap_array, node_struct["info"]["exit_reason"], node_struct["info"]["performance"]) bitmap.lut_applied = True # since we received the bitmap from the slave, the lut was already applied backup_data = bitmap.copy_to_array() should_store, new_bytes, new_bits = self.bitmap_storage.should_store_in_queue(bitmap) new_data = bitmap.copy_to_array() if should_store: node = QueueNode(payload, bitmap_array, node_struct, write=False) node.set_new_bytes(new_bytes, write=False) node.set_new_bits(new_bits, write=False) self.queue.insert_input(node, bitmap) elif self.debug_mode: if node_struct["info"]["exit_reason"] != "regular": log_master("Payload found to be boring, not saved (exit=%s)" % node_struct["info"]["exit_reason"]) for i in range(len(bitmap_array)): if backup_data[i] != new_data[i]: assert(False), "Bitmap mangled at {} {} {}".format(i, repr(backup_data[i]), repr(new_data[i]))
def maybe_insert_node(self, payload, bitmap_array, node_struct): bitmap = ExecutionResult.bitmap_from_bytearray( bitmap_array, node_struct["info"]["exit_reason"], node_struct["info"]["performance"]) bitmap.lut_applied = True # since we received the bitmap from the slave, the lut was already applied backup_data = bitmap.copy_to_array() should_store, new_bytes, new_bits = self.bitmap_storage.should_store_in_queue( bitmap) new_data = bitmap.copy_to_array() if should_store: self.insert_input( self.construct_node(payload, bitmap_array, new_bytes, new_bits, node_struct), bitmap) else: for i in xrange(len(bitmap_array)): if backup_data[i] != new_data[i]: print("diffing at {} {} {}".format(i, repr(backup_data[i]), repr(new_data[i]))) safe_print("RECIEVED BORING INPUT, NOT SAVING..")
def send_payload(self, apply_patches=True, timeout_detection=True, max_iterations=10): if self.exiting: sys.exit(0) self.persistent_runs += 1 start_time = time.time() # TODO: added in redqueen - verify what this is doing if self.in_requeen: if apply_patches: self.send_enable_patches() else: self.send_disable_patches() self.__debug_send(qemu_protocol.RELEASE) self.crashed = False self.timeout = False self.kasan = False repeat = False value = self.check_recv(timeout_detection=timeout_detection) if value == 0: pass # all good elif value == 1: log_qemu("Crash detected!", self.qemu_id) self.crashed = True elif value == 2: log_qemu("Timeout detected!", self.qemu_id) self.timeout = True elif value == 3: log_qemu("Kasan detected!", self.qemu_id) self.kasan = True elif value == 4: repeat = True elif value == 5: repeat = True self.soft_reload() elif value == 6: repeat = True self.soft_reload() elif value == 7: log_qemu("Timeout detected!", self.qemu_id) self.timeout = True else: # TODO: detect+log errors without affecting fuzz campaigns #raise ValueError("Unhandled return code %s" % str(value)) pass self.needs_execution_for_patches = False ## repeat logic - enable starting with RQ release.. if repeat: log_qemu("Repeating iteration...", self.qemu_id) if max_iterations != 0: self.send_payload(apply_patches=apply_patches, timeout_detection=timeout_detection, max_iterations=0) res = self.send_payload(apply_patches=apply_patches, timeout_detection=timeout_detection, max_iterations=max_iterations - 1) res.performance = time.time() - start_time return res return ExecutionResult(self.c_bitmap, self.bitmap_size, self.exit_reason(), time.time() - start_time)
def send_payload( self, timeout_detection=True, max_iterations=10, ): if (self.debug_mode): log_qemu("Send payload..", self.qemu_id) if self.exiting: sys.exit(0) self.persistent_runs += 1 start_time = time.time() self.__debug_send(qemu_protocol.RELEASE) self.crashed = False self.timeout = False self.kasan = False repeat = False value = self.check_recv(timeout_detection=timeout_detection) if value == 0: pass # all good elif value == 1: log_qemu("Crash detected!", self.qemu_id) self.crashed = True elif value == 2: log_qemu("Timeout detected!", self.qemu_id) self.timeout = True elif value == 3: log_qemu("Kasan detected!", self.qemu_id) self.kasan = True elif value == 4: repeat = True elif value == 5: repeat = True self.soft_reload() elif value == 6: repeat = True self.soft_reload() elif value == 7: log_qemu("Timeout detected!", self.qemu_id) self.timeout = True else: # TODO: detect+log errors without affecting fuzz campaigns #raise ValueError("Unhandled return code %s" % str(value)) pass ## repeat logic - enable starting with RQ release.. if repeat: log_qemu("Repeating iteration...", self.qemu_id) if max_iterations != 0: self.send_payload(timeout_detection=timeout_detection, max_iterations=0) res = self.send_payload(timeout_detection=timeout_detection, max_iterations=max_iterations - 1) res.performance = time.time() - start_time return res return ExecutionResult(self.c_bitmap, self.c_coverage_map, self.bitmap_size, self.exit_reason(), time.time() - start_time)