Ejemplo n.º 1
0
 def finalize_iteration(self):
     try:
         self.control.send('F')
         self.control.recv(1)
     except:
         log_exception()
         log_qemu("finalize_iteration failed...", self.qemu_id)
Ejemplo n.º 2
0
    def start(self, verbose=False, serout=None):
        if verbose:
            self.process = subprocess.Popen(filter(None, self.cmd.split(" ")),
                                            stdin=None,
                                            stdout=serout, #None,
                                            stderr=None)
        else:
            if serout is None :
                serout = subprocess.PIPE
            self.process = subprocess.Popen(filter(None, self.cmd.split(" ")),
                                            stdin=subprocess.PIPE,
                                            stdout=serout, #subprocess.PIPE,
                                            stderr=subprocess.PIPE)

        log_qemu("process pid %d" % self.process.pid, self.qemu_id)
        self.stat_fd = open("/proc/" + str(self.process.pid) + "/stat")
        self.init()
        try:
            self.set_init_state()
        except:
            log_exception()
            return False
        self.initial_mem_usage = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
        #time.sleep(1)
        self.kafl_shm.seek(0x0)
        self.kafl_shm.write(self.virgin_bitmap)
        self.kafl_shm.flush()
        return True
Ejemplo n.º 3
0
 def __restart_vm(self):
     if self.comm.slave_termination.value:
         return False
     self.comm.reload_semaphore.acquire()
     try:
         #raise Exception("!")
         # QEMU is full of memory leaks...fixing it that way...
         if self.soft_reload_counter >= 32:
             self.soft_reload_counter = 0
             raise Exception("...")
         self.q.soft_reload()
         self.soft_reload_counter += 1
     except:
         log_exception()
         while True:
             self.q.__del__()
             self.q = qemu(self.slave_id, self.config)
             if self.q.start():
                 break
             else:
                 time.sleep(0.5)
                 log_slave("Fail Reload", self.slave_id)
     self.comm.reload_semaphore.release()
     self.q.set_tick_timeout_treshold(self.stage_tick_treshold *
                                      self.timeout_tick_factor)
     if self.comm.slave_termination.value:
         return False
     return True
Ejemplo n.º 4
0
    def verifiy_input(self, payload, bitmap, payload_size, runs=3):
    	crashed = self.crashed
    	timeout = self.timeout
    	kasan = self.kasan
        failed = False
        try:
            self.enable_sampling_mode()
            init = True
            tmp_bitmap1 = bitmap
            for i in range(runs):
                if not init:
                    self.fs_shm.seek(0)
                    self.fs_shm.write(payload)
                    self.fs_shm.write(''.join(chr(0x00) for x in range((64 << 10)-payload_size)))
                    self.fs_shm.flush()
                    tmp_bitmap1 = self.send_payload(timeout_detection=False)
                    if (self.crashed or self.kasan or self.timeout):
                        break
                    else:
                        self.submit_sampling_run()

                self.fs_shm.seek(0)
                self.fs_shm.write(payload)
                self.fs_shm.write(''.join(chr(0x00) for x in range((64 << 10)-payload_size)))
                self.fs_shm.flush()
                tmp_bitmap2 = self.send_payload(timeout_detection=False)
                if (self.crashed or self.kasan or self.timeout):
                    break
                else:
                    self.submit_sampling_run()
                if tmp_bitmap1 == tmp_bitmap2:
                    break
                init = False
                
        except:
            log_exception()
            failed = True

        self.crashed = crashed or self.crashed
        self.timeout = timeout or self.timeout
        self.kasan = kasan or self.kasan

        try:
            if not self.timeout:
                self.submit_sampling_run()
            self.disable_sampling_mode()
            if not failed:
                return tmp_bitmap2
            else:
                return bitmap            
        except:
            log_exception()
            self.timeout = True
            return bitmap
Ejemplo n.º 5
0
 def check_recv(self, timeout_detection=True):
     log_qemu("check recv", self.qemu_id)
     if timeout_detection:
         self.control.settimeout(1.25)
     try:
         result = self.control.recv(1)
     #except socket_error, e:
     except socket.timeout, e:
         log_exception()
         #raise Exception("XXX DEBUG TIMEOUT")
         return "TIMEOUT"
Ejemplo n.º 6
0
 def __respond_bitmap_req(self, response):
     self.q.set_payload(response.data)
     while True:
         try:
             bitmap = self.q.send_payload()
             break
         except:
             log_exception()
             log_slave("__respond_bitmap_req failed...", self.slave_id)
             self.__restart_vm()
     send_msg(KAFL_TAG_REQ_BITMAP,
              bitmap,
              self.comm.to_master_from_slave_queue,
              source=self.slave_id)
Ejemplo n.º 7
0
    def __del__(self):
        log_qemu("kill qemu pid %d" % self.process.pid, self.qemu_id)
        os.system("kill -9 " + str(self.process.pid))

        try:
            if self.process:
                try:
                    self.process.kill()
                except:
                    log_exception()

            if self.e:
                if self.control_fileno:
                    self.e.unregister(self.control_fileno)

            if self.intervm_tty_write:
                self.intervm_tty_write.close()
            if self.control:
                self.control.close()
        except OSError:
            log_exception()
            pass

        try:
            self.kafl_shm.close()
        except:
            log_exception()
            pass

        try:
            self.fs_shm.close() 
        except:
            log_exception()
            pass

        try:
            if self.stat_fd:
                self.stat_fd.close()
        except:
            log_exception()
            pass

        if self.global_bitmap is not None :
            self.global_bitmap.close()
            self.global_bitmap = None

        if self.global_bitmap_fd is not None :
            os.close(self.global_bitmap_fd)
            self.global_bitmap_fd = None
Ejemplo n.º 8
0
    def send_payload(self, timeout_detection=True):
        """Send a test case to qemu, wait for a response, and read back the coverage map"""
        log_qemu("send payload", self.qemu_id)
        self.start_ticks = self.__get_pid_guest_ticks()
        try:
            # vm was waiting for next payload, unlock them now that its been provided
            self.control.send("R")
        except OSError:
            log_exception()
            log_qemu("Failed to send payload...", self.qemu_id)
            return None

        self.crashed = False
        self.timeout = False
        self.kasan = False

        if timeout_detection:
            counter = 0
            while True:
                value = self.check_recv()
                if value == "TIMEOUT":
                    self.end_ticks = self.__get_pid_guest_ticks()
                    if (self.end_ticks-self.start_ticks) >= self.tick_timeout_treshold:
                        break
                    if counter >= 10:
                    	break
                    counter += 1
                else:
                    break
            self.end_ticks = self.__get_pid_guest_ticks()
        else:
            value = self.check_recv(timeout_detection=False)
        log_qemu("check_recv val %s" % value, self.qemu_id)
        if value == "CRASH":
            self.crashed = True
            self.finalize_iteration()
        elif value == "TIMEOUT":
            self.timeout = True
            self.finalize_iteration()
        elif value == "KASAN":
            self.kasan = True
            self.finalize_iteration()
        elif value == "EOF":
            log_qemu("QEMU control channel unexpectedly shut down!", self.qemu_id)
            self.timeout = True # XXX was really qemu shutting down!
            self.finalize_iteration()
        self.kafl_shm.seek(0x0)
        return self.kafl_shm.read(self.bitmap_size)
Ejemplo n.º 9
0
    def __respond_job_req(self, response):
        results = []
        performance = 0.0
        counter = 0
        self.comm.slave_locks_A[self.slave_id].acquire()
        for i in range(len(response.data)):
            if not self.comm.stage_abortion_notifier.value:
                new_bits = True
                vm_reloaded = False
                self.reloaded = False
                bitmap = ""
                payload = ""
                payload_size = 0
                if self.comm.slave_termination.value:
                    self.comm.slave_locks_B[self.slave_id].release()
                    send_msg(KAFL_TAG_RESULT,
                             results,
                             self.comm.to_mapserver_queue,
                             source=self.slave_id)
                    return
                while True:
                    while True:
                        try:
                            payload, payload_size = self.q.copy_master_payload(
                                self.comm.get_master_payload_shm(
                                    self.slave_id), i,
                                self.comm.get_master_payload_shm_size())
                            start_time = time.time()
                            bitmap = self.q.send_payload()
                            performance = time.time() - start_time
                            break
                        except:
                            log_exception()
                            if not self.__restart_vm():
                                return
                            self.reloaded = True
                    if not bitmap:
                        log_slave("SHM ERROR....", self.slave_id)
                        if not self.__restart_vm():
                            self.comm.slave_locks_B[self.slave_id].release()
                            send_msg(KAFL_TAG_RESULT,
                                     results,
                                     self.comm.to_mapserver_queue,
                                     source=self.slave_id)
                            return
                    else:
                        break
                self.q.finalize_iteration()
                new_bits = self.q.copy_bitmap(
                    self.comm.get_bitmap_shm(self.slave_id),
                    i,
                    self.comm.get_bitmap_shm_size(),
                    bitmap,
                    payload,
                    payload_size,
                    effector_mode=self.comm.effector_mode.value)
                if new_bits:
                    self.q.copy_mapserver_payload(
                        self.comm.get_mapserver_payload_shm(self.slave_id), i,
                        self.comm.get_mapserver_payload_shm_size())

                if self.comm.slave_termination.value:
                    self.comm.slave_locks_B[self.slave_id].release()
                    send_msg(KAFL_TAG_RESULT,
                             results,
                             self.comm.to_mapserver_queue,
                             source=self.slave_id)
                    return

                if self.q.timeout and not (self.q.crashed or self.q.kasan):
                    vm_reloaded = True
                    if mmh3.hash64(bitmap) not in self.false_positiv_map:
                        while True:
                            try:
                                if not self.__restart_vm():
                                    return
                                start_time = time.time()
                                bitmap = self.q.send_payload()
                                performance = time.time() - start_time
                                break
                            except:
                                log_exception()
                                pass
                    if not self.q.timeout:
                        #false positiv timeout
                        self.false_positiv_map.add(mmh3.hash64(bitmap))
                        self.reloaded = False
                    else:
                        #false positiv timeout (already seen)
                        self.reloaded = False
                        counter += 1

                if self.q.crashed or self.q.timeout or self.q.kasan or self.reloaded:
                    vm_reloaded = True
                    results.append(
                        FuzzingResult(i,
                                      self.q.crashed,
                                      (self.q.timeout or self.reloaded),
                                      self.q.kasan,
                                      response.data[i],
                                      self.slave_id,
                                      performance,
                                      reloaded=vm_reloaded,
                                      qid=self.slave_id))
                    if not self.__restart_vm():
                        self.comm.slave_locks_B[self.slave_id].release()
                        send_msg(KAFL_TAG_RESULT,
                                 results,
                                 self.comm.to_mapserver_queue,
                                 source=self.slave_id)
                        return
                    self.reloaded = True
                else:
                    results.append(
                        FuzzingResult(i,
                                      self.q.crashed,
                                      (self.q.timeout or self.reloaded),
                                      self.q.kasan,
                                      response.data[i],
                                      self.slave_id,
                                      performance,
                                      reloaded=vm_reloaded,
                                      new_bits=new_bits,
                                      qid=self.slave_id))
                    if new_bits and self.auto_reload:
                        self.__restart_vm()
                    self.reloaded = False

            else:
                results.append(
                    FuzzingResult(i,
                                  False,
                                  False,
                                  False,
                                  response.data[i],
                                  self.slave_id,
                                  0.0,
                                  reloaded=False,
                                  new_bits=False,
                                  qid=self.slave_id))

        if self.comm.slave_termination.value:
            self.comm.slave_locks_B[self.slave_id].release()
            send_msg(KAFL_TAG_RESULT,
                     results,
                     self.comm.to_mapserver_queue,
                     source=self.slave_id)
            return

        self.comm.slave_locks_B[self.slave_id].release()
        send_msg(KAFL_TAG_RESULT,
                 results,
                 self.comm.to_mapserver_queue,
                 source=self.slave_id)
Ejemplo n.º 10
0
    def __respond_sampling_req(self, response):
        payload = response.data[0]
        sampling_rate = response.data[1]

        self.stage_tick_treshold = 0
        sampling_counter = 0
        sampling_ticks = 0
        error_counter = 0

        round_checker = 0
        self.__restart_vm()
        self.q.set_payload(payload)

        filter_hash = self.__check_filter_bitmaps()

        while True:
            error = False
            while True:
                try:
                    self.q.enable_sampling_mode()
                    bitmap = self.q.send_payload()
                    break
                except:
                    log_exception()
                    log_slave("Sampling fail...", self.slave_id)
                    if not self.__restart_vm():
                        return

            for i in range(5):
                try:

                    if error_counter >= 2:
                        log_slave("Abort sampling...", self.slave_id)
                        error = False
                        break

                    new_bitmap = self.q.send_payload()
                    if self.q.crashed or self.q.timeout or self.q.kasan:
                        log_slave("Sampling timeout...", self.slave_id)
                        error_counter += 1
                        if not self.__restart_vm():
                            error = False
                            break
                    else:
                        self.q.submit_sampling_run()
                        sampling_counter += 1
                        sampling_ticks = self.q.end_ticks - self.q.start_ticks

                except:
                    log_exception()
                    log_slave("Sampling wtf??!", self.slave_id)
                    if not self.__restart_vm():
                        return

            while True:
                try:
                    self.q.disable_sampling_mode()
                    break
                except:
                    log_exception()
                    if not self.__restart_vm():
                        return

            tmp_hash = self.__check_filter_bitmaps()
            if tmp_hash == filter_hash:
                round_checker += 1
            else:
                round_checker = 0

            filter_hash = tmp_hash
            if round_checker == 5:
                break

        log_slave("Sampling findished!", self.slave_id)

        if sampling_counter == 0:
            sampling_counter = 1
        self.stage_tick_treshold = sampling_ticks / sampling_counter
        log_slave("sampling_ticks: " + str(sampling_ticks), self.slave_id)
        log_slave("sampling_counter: " + str(sampling_counter), self.slave_id)
        log_slave("STAGE_TICK_TRESHOLD: " + str(self.stage_tick_treshold),
                  self.slave_id)

        if self.stage_tick_treshold == 0.0:
            self.stage_tick_treshold = 1.0
        self.q.set_tick_timeout_treshold(3 * self.stage_tick_treshold *
                                         self.timeout_tick_factor)

        send_msg(KAFL_TAG_REQ_SAMPLING,
                 bitmap,
                 self.comm.to_master_from_slave_queue,
                 source=self.slave_id)