Exemplo n.º 1
0
 def __enter__(self):
     # init LibVMI
     self.vmi = Libvmi(self.vm_name,
                       init_flags=INIT_DOMAINNAME | INIT_EVENTS,
                       partial=True)
     self.vmi.init_paging(flags=0)
     # catch every exception to force a clean exit with __exit__
     # where vmi.destroy() must be called
     try:
         # determine debug context
         if not self.process:
             self.ctx = RawDebugContext(self.vmi)
         else:
             self.vmi.init_os()
             ostype = self.vmi.get_ostype()
             if ostype == VMIOS.WINDOWS:
                 self.ctx = WindowsDebugContext(self.vmi, self.process)
             elif ostype == VMIOS.LINUX:
                 self.ctx = LinuxDebugContext(self.vmi, self.process)
             else:
                 raise RuntimeError('unhandled ostype: {}'.format(
                     ostype.value))
         self.ctx.attach()
         self.attached = True
     except:
         logging.exception('Exception while initializing debug context')
     return self
Exemplo n.º 2
0
 def __init__(self, vm_name, process_name):
     self.log = logging.getLogger(__class__.__name__)
     self.vm_name = vm_name
     self.target_name = process_name
     self.target_pid = None
     self.target_dtb = None
     self.vmi = Libvmi(self.vm_name, INIT_DOMAINNAME | INIT_EVENTS)
     self.kernel_base = self.get_kernel_base()
     logging.info('kernel base address: %s', hex(self.kernel_base))
Exemplo n.º 3
0
    def __init__(self, base, config, layered=False, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        addrspace.BaseAddressSpace.__init__(self, base, config, **kwargs)
        self.as_assert(base is None or layered, 'Must be first Address Space')
        self.as_assert(config.LOCATION.startswith("vmi://"),
                       "Location doesn't start with vmi://")

        domain = config.LOCATION[len("vmi://"):]
        self.vmi = Libvmi(domain, partial=True)
        self.dtb = self.vmi.get_vcpu_reg(CR3, 0)
Exemplo n.º 4
0
def get_backend(domain, listener, syscall_filtering):
    """Return backend based on libvmi configuration.
    If analyze if False, returns a dummy backend
    that does not analyze system calls.
    Returns None if the backend is missing
    """
    libvmi = Libvmi(domain.name())
    os_type = libvmi.get_ostype()
    try:
        return BACKENDS[os_type](domain, libvmi, listener, syscall_filtering)
    except KeyError:
        raise BackendNotFoundError('Unable to find an appropritate backend for'
                                   'this OS: {}'.format(os_type))
Exemplo n.º 5
0
    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(url, "Filename must be specified in session (e.g. "
                       "session.SetParameter('filename', 'vmi://domain').")
        self.as_assert(url.startswith(URL_PREFIX),
                       "The domain must be passed with the URL prefix {}".format(URL_PREFIX))
        domain = url[len(URL_PREFIX):]
        self.as_assert(domain, "domain name missing after {}".format(URL_PREFIX))

        super(VMIAddressSpace, self).__init__(base=base, session=session, **kwargs)
        self.vmi = Libvmi(domain, partial=True)
Exemplo n.º 6
0
 def __init__(self, vm_name, process_name):
     self.log = logging.getLogger(__class__.__name__)
     self.vm_name = vm_name
     self.full_system_mode = False
     self.target_name = process_name
     self.target_pid = None
     if process_name is None:
         self.full_system_mode = True
         self.target_name = 'kernel'
         # kernel space is represented by PID 0 in LibVMI
         self.target_pid = 0
     self.target_dtb = None
     self.vmi = Libvmi(self.vm_name, INIT_DOMAINNAME | INIT_EVENTS)
     self.kernel_base = self.get_kernel_base()
     if self.kernel_base:
         logging.info('kernel base address: %s', hex(self.kernel_base))
Exemplo n.º 7
0
def main(args):
    vm_name = args['<vm_name>']
    symbol = args['<symbol>']

    # register SIGINT
    signal.signal(signal.SIGINT, signal_handler)

    with Libvmi(vm_name, INIT_DOMAINNAME | INIT_EVENTS) as vmi:
        vaddr = vmi.translate_ksym2v(symbol)

        debug_event = DebugEvent(debug_callback)

        num_vcpus = vmi.get_num_vcpus()
        sstep_event = SingleStepEvent(range(num_vcpus), enable=False,
                                      callback=sstep_callback)
        with pause(vmi):
            vmi.register_event(debug_event)
            vmi.register_event(sstep_event)
            # set dr0 to our address
            vmi.set_vcpureg(vaddr, X86Reg.DR0.value, 0)
            toggle_dr0(vmi, True)

        # listen
        while not interrupted:
            print("Waiting for events")
            vmi.listen(1000)
        print("Stop listening")

        with pause(vmi):
            vmi.clear_event(debug_event)
            vmi.clear_event(sstep_event)
Exemplo n.º 8
0
def get_backend(domain, listener, syscall_filtering):
    """
    Return a suitable backend based on guest operating system.

    :param domain: libvirt domain
    :returns: new backend instance
    :rtype: Backend
    :raises: BackendNotFoundError
    """
    libvmi = Libvmi(domain.name())
    os_type = libvmi.get_ostype()
    try:
        return BACKENDS[os_type](domain, libvmi, listener, syscall_filtering)
    except KeyError:
        raise BackendNotFoundError('Unable to find an appropritate backend for'
                                   'this OS: {}'.format(os_type))
Exemplo n.º 9
0
def main(args):
    logging.basicConfig(level=logging.INFO)
    vm_name = args['<vm_name>']

    # register SIGINT
    signal.signal(signal.SIGINT, signal_handler)

    kvm_socket = {VMIInitData.KVMI_SOCKET: args['--kvmi-socket']} if args['--kvmi-socket'] else None
    with Libvmi(vm_name, INIT_DOMAINNAME | INIT_EVENTS, init_data=kvm_socket, partial=True) as vmi:
        # init paging to translate virtual addresses
        vmi.init_paging(0)
        with pause(vmi):
            # get current RIP on VCPU 0
            rip = vmi.get_vcpureg(X86Reg.RIP.value, 0)
            # get DTB
            cr3 = vmi.get_vcpureg(X86Reg.CR3.value, 0)
            dtb = cr3 & ~0xfff
            # get gpa
            paddr = vmi.pagetable_lookup(dtb, rip)
            gfn = paddr >> 12

            # define callback
            def cb_mem_event(vmi, event):
                logging.info("Mem event at RIP: %s, frame: %s, offset: %s, permissions: %s",
                             hex(event.x86_regs.rip), hex(event.gla), hex(event.offset), event.out_access.name)

            mem_event = MemEvent(MemAccess.X, cb_mem_event, gfn=gfn)
            vmi.register_event(mem_event)
        # listen
        while not interrupted:
            vmi.listen(3000)
        logging.info("stop listening")
Exemplo n.º 10
0
def main(args):
    logging.basicConfig(level=logging.INFO)
    vm_name = args['<vm_name>']

    # register SIGINT
    signal.signal(signal.SIGINT, signal_handler)

    # 1 - init LibVMI
    kvm_socket = {
        VMIInitData.KVMI_SOCKET: args['--kvmi-socket']
    } if args['--kvmi-socket'] else None
    with Libvmi(vm_name,
                INIT_DOMAINNAME | INIT_EVENTS,
                init_data=kvm_socket,
                partial=True) as vmi:
        counter = Counter()

        # 2 - define CR3 callback
        def cr3_callback(vmi, event):
            cr3_value = event.value
            logging.info("CR3 change: %s", hex(cr3_value))
            counter[hex(cr3_value)] += 1

        # 3 - define and register CR3-write event
        with pause(vmi):
            # register CR3-write event
            reg_event = RegEvent(X86Reg.CR3, RegAccess.W, cr3_callback)
            vmi.register_event(reg_event)

        # 4 - listen for events
        for i in range(0, 100):
            vmi.listen(500)
        logging.info(counter)
Exemplo n.º 11
0
def vmiev(domain):
    vm_config = DOMAIN_CONFIGS[domain.name()]
    with Libvmi(domain.name(),
                INIT_DOMAINNAME | INIT_EVENTS,
                config_mode=VMIConfig.DICT,
                config=vm_config) as vmi:
        yield vmi
Exemplo n.º 12
0
def main(args):

    if len(args) != 3:
        print("./mem_vmi.py <process_name> <string_addr>")
        return 1

    vm_name = "ubuntu16.04"
    process_name = args[1]
    string_addr = args[2]

    with Libvmi(
            vm_name
    ) as vmi:  #class Libvmi,the default parameters calls vmi_init_complete
        #init offsets values, init libvmi library
        tasks_offset = vmi.get_offset("linux_tasks")
        name_offset = vmi.get_offset("linux_name")
        pid_offset = vmi.get_offset("linux_pid")

        #pause vm for consistent memory access
        with pause(vmi):
            pids = get_pid_by_name(vmi, process_name)
            if not pids:
                print("Cannot find process %s" % process_name)
            pid = pids[0]
            print("process %s:%d" % (process_name, pid))

            #get output string of exp
            string = vmi.read_str_va(int(string_addr, 16), pid)
            print("output:%s" % string)

            #alter output string of exp
            vmi.write_8_va(int(string_addr, 16), pid, 0x77)
            return 0
Exemplo n.º 13
0
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """
    This address space can be used in conjunction with LibVMI
    and the Python bindings for LibVMI.  The end result is that
    you can connect Volatility to view the memory of a running
    virtual machine from any virtualization platform that
    LibVMI supports.

    For this AS to be instantiated, we need the VM name to
    connect to.
    """

    order = 90

    def __init__(self, base, config, layered=False, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        addrspace.BaseAddressSpace.__init__(self, base, config, **kwargs)
        self.as_assert(base is None or layered, 'Must be first Address Space')
        self.as_assert(config.LOCATION.startswith("vmi://"),
                       "Location doesn't start with vmi://")

        domain = config.LOCATION[len("vmi://"):]
        self.vmi = Libvmi(domain, partial=True)
        self.dtb = self.vmi.get_vcpu_reg(CR3, 0)

    def close(self):
        self.vmi.destroy()

    def read(self, addr, length):
        buffer, bytes_read = self.vmi.read_pa(addr, length)
        if bytes_read != length:
            raise RuntimeError('Error while reading physical memory at '
                               '{}'.format(hex(addr)))
        return buffer

    def zread(self, addr, length):
        buffer, bytes_read = self.vmi.read_pa(addr, length)
        if bytes_read != length:
            # fill with zeroes
            buffer += bytes(length - bytes_read).decode()
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return 4096 < addr < self.vmi.get_memsize() - 1

    def get_available_addresses(self):
        yield (0, self.vmi.get_memsize())
Exemplo n.º 14
0
def main(args):
    if len(args) != 2:
        print('./process-list.py <vm_name>')
        return 1

    vm_name = args[1]

    with Libvmi(vm_name) as vmi:
        # get ostype
        os = vmi.get_ostype()
        # init offsets values
        tasks_offset = None
        name_offset = None
        pid_offset = None
        if os == VMIOS.LINUX:
            tasks_offset = vmi.get_offset("linux_tasks")
            name_offset = vmi.get_offset("linux_name")
            pid_offset = vmi.get_offset("linux_pid")
        elif os == VMIOS.WINDOWS:
            tasks_offset = vmi.get_offset("win_tasks")
            name_offset = vmi.get_offset("win_pname")
            pid_offset = vmi.get_offset("win_pid")
        else:
            logging.info("Unknown OS")
            return 1

        # pause vm
        with pause(vmi):
            # demonstrate name and id accessors
            name = vmi.get_name()
            id = vmi.get_vmid()

            logging.info("Process listing for VM %s (id: %s)", name, id)
            if os == VMIOS.LINUX:
                list_head = vmi.translate_ksym2v("init_task")
                list_head += tasks_offset
            elif os == VMIOS.WINDOWS:
                list_head = vmi.read_addr_ksym("PsActiveProcessHead")
            else:
                return 1
            cur_list_entry = list_head
            next_list_entry = vmi.read_addr_va(cur_list_entry, 0)

            while True:
                current_process = cur_list_entry - tasks_offset
                pid = vmi.read_32_va(current_process + pid_offset, 0)
                procname = vmi.read_str_va(current_process + name_offset, 0)

                logging.info("[%s] %s (struct addr:%s)", pid, procname,
                             hex(current_process))
                cur_list_entry = next_list_entry
                next_list_entry = vmi.read_addr_va(cur_list_entry, 0)

                if os == VMIOS.WINDOWS and next_list_entry == list_head:
                    break
                elif os == VMIOS.LINUX and cur_list_entry == list_head:
                    break
Exemplo n.º 15
0
def main(args):
    if len(args) != 2:
        print('./module-list.py <vm_name>')
        return 1

    vm_name = args[1]

    with Libvmi(vm_name) as vmi:
        # pause vm for consistent memory access
        with pause(vmi):
            next_module = None
            # get ostype
            os = vmi.get_ostype()
            if os == VMIOS.LINUX:
                next_module = vmi.read_addr_ksym("modules")
            elif os == VMIOS.WINDOWS:
                next_module = vmi.read_addr_ksym("PsLoadedModuleList")
            else:
                logging.info("Unknown OS")

            list_head = next_module

            # walk the module list
            while True:
                # follow the next pointer
                tmp_next = vmi.read_addr_va(next_module, 0)

                # if we are back at the list head, we are done
                if list_head == tmp_next:
                    break

                modname = None
                # print out the module name
                if os == VMIOS.LINUX:
                    if page_mode == PageMode.IA32E:
                        modname = vmi.read_str_va(next_module + 16, 0)
                    else:
                        modname = vmi.read_str_va(next_module + 8, 0)

                elif os == VMIOS.WINDOWS:
                    page_mode = vmi.get_page_mode(0)
                    if page_mode == PageMode.IA32E:
                        modname = vmi.read_unicode_str_va(
                            next_module + 0x58, 0)
                    else:
                        modname = vmi.read_unicode_str_va(
                            next_module + 0x2c, 0)

                else:
                    logging.info("Unkown OS")

                if modname is not None:
                    logging.info(modname)

                next_module = tmp_next
Exemplo n.º 16
0
 def __enter__(self):
     # init LibVMI
     self.vmi = Libvmi(self.vm_name,
                       init_flags=INIT_DOMAINNAME | INIT_EVENTS,
                       partial=True)
     self.vmi.init_paging(flags=0)
     # catch every exception to force a clean exit with __exit__
     # where vmi.destroy() must be called
     try:
         # determine debug context
         if not self.process:
             self.ctx = RawDebugContext(self.vmi)
         else:
             self.vmi.init_os()
             ostype = self.vmi.get_ostype()
             if ostype == VMIOS.WINDOWS:
                 self.ctx = WindowsDebugContext(self.vmi, self.process)
             elif ostype == VMIOS.LINUX:
                 self.ctx = LinuxDebugContext(self.vmi, self.process)
             else:
                 raise RuntimeError('unhandled ostype: {}'.format(
                     ostype.value))
         # register some events
         # register interrupt event
         self.int_event = IntEvent(self.cb_on_int3)
         self.vmi.register_event(self.int_event)
         # single step event to handle wrong hits by sw breakpoints
         # enabled via EventResponse.TOGGLE_SINGLESTEP
         num_vcpus = self.vmi.get_num_vcpus()
         self.ss_event_recoil = SingleStepEvent(range(num_vcpus),
                                                self.cb_on_sstep_recoil,
                                                enable=False)
         self.vmi.register_event(self.ss_event_recoil)
         self.ctx.attach()
         self.attached = True
     except:
         logging.exception('Exception while initializing debug context')
     return self
Exemplo n.º 17
0
    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(
            url, "Filename must be specified in session (e.g. "
            "session.SetParameter('filename', 'vmi:///domain').")
        vmi_url = urlparse(url)
        self.as_assert(vmi_url.scheme == SCHEME, "URL scheme must be vmi://")
        self.as_assert(vmi_url.path, "No domain name specified")
        domain = vmi_url.path[1:]
        # hypervisor specified ?
        self.mode = None
        hypervisor = vmi_url.netloc
        if hypervisor:
            self.mode = VMIMode[hypervisor.upper()]
        # query parameters ?
        self.volatile = True
        if vmi_url.query:
            params = parse_qs(vmi_url.query, strict_parsing=True)
            try:
                self.volatile = strtobool((params['volatile'][0]))
            except KeyError:
                raise RuntimeError('Invalid query parameters in vmi:// URI')
        # build Libvmi instance
        super(VMIAddressSpace, self).__init__(base=base,
                                              session=session,
                                              **kwargs)
        self.vmi = Libvmi(domain, mode=self.mode, partial=True)
        self.min_addr = 0
        self.max_addr = self.vmi.get_memsize() - 1
        # pause in case volatile has been disabled
        if not self.volatile:
            self.vmi.pause_vm()
        # register flush hook to destroy vmi instance when session.Flush() is called
        session.register_flush_hook(self, self.close)
Exemplo n.º 18
0
    def _init_vmi(self):
        """ Initialize LibVMI """
        self._vmi = Libvmi(self._vm.name)

        # get ostype
        self._os = self._vmi.get_ostype()

        # init offsets values
        self._tasks_offset = None
        self._name_offset = None
        self._pid_offset = None
        if self._os == VMIOS.LINUX:
            self._tasks_offset = self._vmi.get_offset("linux_tasks")
            self._name_offset = self._vmi.get_offset("linux_name")
            self._pid_offset = self._vmi.get_offset("linux_pid")
        elif self._os == VMIOS.WINDOWS:
            self._tasks_offset = self._vmi.get_offset("win_tasks")
            self._name_offset = self._vmi.get_offset("win_pname")
            self._pid_offset = self._vmi.get_offset("win_pid")
        else:
            self.logger.error("Unknown OS")
            return 0
        return 1
Exemplo n.º 19
0
def main(args):
    if len(args) != 3:
        print('Incorrect number of args', args)
        print('arg 2', args[1])
        return
    init_config()
    vm_name = args[1]
    p_id = args[2]
    print('Received : vm_name = ' + vm_name + ' , p_id = ' + p_id)
    vmi = Libvmi(vm_name)
    result = change_uid_process(vmi, p_id)
    if result:
        print("uid changed successfully!")
    else:
        print("something went wrong!")
Exemplo n.º 20
0
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """An address space which operates on top of Libvmi's interface."""

    __abstract = False
    __name = "vmi"
    order = 90
    __image = True

    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(url, "Filename must be specified in session (e.g. "
                       "session.SetParameter('filename', 'vmi://domain').")
        self.as_assert(url.startswith(URL_PREFIX),
                       "The domain must be passed with the URL prefix {}".format(URL_PREFIX))
        domain = url[len(URL_PREFIX):]
        self.as_assert(domain, "domain name missing after {}".format(URL_PREFIX))

        super(VMIAddressSpace, self).__init__(base=base, session=session, **kwargs)
        self.vmi = Libvmi(domain, partial=True)

    def close(self):
        self.vmi.destroy()

    def read(self, addr, size):
        buffer, bytes_read = self.vmi.read_pa(addr, size)
        if bytes_read != size:
            raise RuntimeError('Error while reading physical memory at {}'.format(hex(addr)))
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return 4096 < addr < self.vmi.get_memsize() - 1

    def get_available_addresses(self):
        yield (4096, self.vmi.get_memsize() - 4096)

    def get_mappings(self, start=0, end=2 ** 64):
        yield addrspace.Run(start=0, end=self.vmi.get_memsize(), file_offset=0, address_space=self)
Exemplo n.º 21
0
def main(args):
    if len(args) != 2:
        print('./memaccess-event.py <vm_name>')
        return 1

    vm_name = args[1]

    # register SIGINT
    signal.signal(signal.SIGINT, signal_handler)

    with Libvmi(vm_name, INIT_DOMAINNAME | INIT_EVENTS) as vmi:
        reg_event = RegEvent(X86Reg.CR3, RegAccess.W, callback)
        vmi.register_event(reg_event)
        # listen
        while not interrupted:
            print("Waiting for events")
            vmi.listen(3000)
        print("Stop listening")
Exemplo n.º 22
0
def main(args):
    vm_name = args['<vm_name>']
    symbol = args['<symbol>']
    sstep_enabled = args['--sstep']

    # register SIGINT
    signal.signal(signal.SIGINT, signal_handler)

    with Libvmi(vm_name, INIT_DOMAINNAME | INIT_EVENTS) as vmi:
        vaddr = vmi.translate_ksym2v(symbol)
        paddr = vmi.translate_kv2p(vaddr)
        frame = paddr >> 12
        print("symbol: {} vaddr: {} paddr: {} frame: {}".format(
            symbol, hex(vaddr), hex(paddr), hex(frame)))

        user_data = {
            'symbol': symbol,
            'target_vaddr': vaddr,
            'target_gfn': frame,
            'mem_event': None,
            'sstep': sstep_enabled
        }
        num_vcpus = vmi.get_num_vcpus()
        ss_event = SingleStepEvent(range(num_vcpus),
                                   cb_ss_event,
                                   data=user_data,
                                   enable=False)
        mem_event = MemEvent(MemAccess.X,
                             cb_mem_event,
                             gfn=frame,
                             data=user_data)
        user_data['mem_event'] = mem_event
        with pause(vmi):
            vmi.register_event(ss_event)
            vmi.register_event(mem_event)
        # listen
        while not interrupted:
            print("Waiting for events ({})".format(vmi.are_events_pending()))
            vmi.listen(3000)
        print("Stop listening")
        with pause(vmi):
            vmi.clear_event(mem_event)
Exemplo n.º 23
0
def main(args):
    if len(args) != 2:
        print('./singlestep-event.py <vm_name>')
        return 1

    vm_name = args[1]

    # register SIGINT
    signal.signal(signal.SIGINT, signal_handler)

    counter = 0
    with Libvmi(vm_name, INIT_DOMAINNAME | INIT_EVENTS) as vmi:
        num_vcpus = vmi.get_num_vcpus()
        ss_event = SingleStepEvent(range(num_vcpus), callback, data=counter)
        vmi.register_event(ss_event)
        # listen
        while not interrupted:
            print("Waiting for events")
            vmi.listen(500)
        print("Stop listening")
        counter = ss_event.data
    print("Singlestepped {} instructions".format(counter))
Exemplo n.º 24
0
def main(args):
    logging.basicConfig(level=logging.INFO)

    vm_name = args['<vm_name>']

    # register SIGINT
    signal.signal(signal.SIGINT, signal_handler)

    kvm_socket = {
        VMIInitData.KVMI_SOCKET: args['--kvmi-socket']
    } if args['--kvmi-socket'] else None
    with Libvmi(vm_name,
                INIT_DOMAINNAME | INIT_EVENTS,
                init_data=kvm_socket,
                partial=True) as vmi:
        msr_counter = Counter()

        def msr_callback(vmi, event):
            try:
                name = MSR_NAME[event.msr]
            except KeyError:
                name = 'MSR'

            logging.info("%s %s = %s", name, hex(event.msr), hex(event.value))
            msr_counter[event.msr] += 1
            # EternalBlue exploitation ?
            if msr_counter[0x176] > 1:
                logging.warn('MSR 0x176 modified %s times !',
                             msr_counter[0x176])

        with pause(vmi):
            # register MSR event
            reg_event = RegEvent(MSR.ALL, RegAccess.W, msr_callback)
            vmi.register_event(reg_event)
        logging.info("listening")
        while not interrupted:
            vmi.listen(500)
Exemplo n.º 25
0
Arquivo: vmi.py Projeto: google/rekall
    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(url, "Filename must be specified in session (e.g. "
                       "session.SetParameter('filename', 'vmi:///domain').")
        vmi_url = urlparse(url)
        self.as_assert(vmi_url.scheme == SCHEME, "URL scheme must be vmi://")
        self.as_assert(vmi_url.path, "No domain name specified")
        domain = vmi_url.path[1:]
        # hypervisor specified ?
        self.mode = None
        hypervisor = vmi_url.netloc
        if hypervisor:
            self.mode = VMIMode[hypervisor.upper()]
        # query parameters ?
        self.volatile = True
        if vmi_url.query:
            params = parse_qs(vmi_url.query, strict_parsing=True)
            try:
                self.volatile = strtobool((params['volatile'][0]))
            except KeyError:
                raise RuntimeError('Invalid query parameters in vmi:// URI')
        # build Libvmi instance
        super(VMIAddressSpace, self).__init__(base=base, session=session,
                                              **kwargs)
        self.vmi = Libvmi(domain, mode=self.mode, partial=True)
        self.min_addr = 0
        self.max_addr = self.vmi.get_memsize() - 1
        # pause in case volatile has been disabled
        if not self.volatile:
            self.vmi.pause_vm()
        # register flush hook to destroy vmi instance when session.Flush() is called
        session.register_flush_hook(self, self.close)
Exemplo n.º 26
0
        "python /usr/src/volatility/vol.py --profile=LinuxDebian8x64 -f /mnt/mem linux_hidden_modules"
    ).read()
    loaded_mods = os.popen(
        "python /usr/src/volatility/vol.py --profile=LinuxDebian8x64 -f /mnt/mem linux_lsmod"
    ).read()
    sp_network = os.popen(
        "python /usr/src/volatility/vol.py --profile=LinuxDebian8x64 -f /mnt/mem linux_netstat -U | grep -o '[a-z0-9A-Z]*/[0-9]*' | awk -F'/' '{print $2}' | sort | uniq"
    ).read()
    sp_lsmod = os.popen(
        "python /usr/src/volatility/vol.py --profile=LinuxDebian8x64 -f /mnt/mem linux_lsmod | awk '{print $2"
        "$3}'").read()
    return (network, hidden_mods, loaded_mods, sp_network, sp_lsmod)


if (len(sys.argv) == 4):
    vmi = Libvmi(sys.argv[1])
    f = open(sys.argv[3], 'w')
    f1 = open("net_be", 'w')
    f2 = open("lsmod_be", "w")
    f3 = open("pslist_be", "w")

    for pid, procname in list_processes(vmi):
        f.write("%s %s\n" % (pid, procname))
        f3.write("%s %s\n" % (pid, procname))
    (network, hidden_mods, loaded_mods, sp_network, sp_lsmod) = list_other()
    f.write("\n%s\n" % network)
    f.write("%s\n" % hidden_mods)
    f.write("%s" % loaded_mods)
    f1.write("%s" % sp_network)
    f2.write("%s" % sp_lsmod)
Exemplo n.º 27
0
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """An address space which operates on top of Libvmi's interface."""

    __abstract = False
    __name = "vmi"
    order = 90
    volatile = True
    __image = True

    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(
            url, "Filename must be specified in session (e.g. "
            "session.SetParameter('filename', 'vmi:///domain').")
        vmi_url = urlparse(url)
        self.as_assert(vmi_url.scheme == SCHEME, "URL scheme must be vmi://")
        self.as_assert(vmi_url.path, "No domain name specified")
        domain = vmi_url.path[1:]
        # hypervisor specified ?
        self.mode = None
        hypervisor = vmi_url.netloc
        if hypervisor:
            self.mode = VMIMode[hypervisor.upper()]
        # query parameters ?
        self.volatile = True
        if vmi_url.query:
            params = parse_qs(vmi_url.query, strict_parsing=True)
            try:
                self.volatile = strtobool((params['volatile'][0]))
            except KeyError:
                raise RuntimeError('Invalid query parameters in vmi:// URI')
        # build Libvmi instance
        super(VMIAddressSpace, self).__init__(base=base,
                                              session=session,
                                              **kwargs)
        self.vmi = Libvmi(domain, mode=self.mode, partial=True)
        self.min_addr = 0
        self.max_addr = self.vmi.get_memsize() - 1
        # pause in case volatile has been disabled
        if not self.volatile:
            self.vmi.pause_vm()
        # register flush hook to destroy vmi instance when session.Flush() is called
        session.register_flush_hook(self, self.close)

    def close(self):
        if not self.volatile:
            self.vmi.resume_vm()
        self.vmi.destroy()

    def read(self, addr, size):
        buffer, _ = self.vmi.read_pa(addr, size, padding=True)
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return self.min_addr <= addr <= self.max_addr

    def get_available_addresses(self):
        yield (self.min_addr, self.max_addr)

    def get_mappings(self, start=0, end=2**64):
        yield addrspace.Run(start=self.min_addr,
                            end=self.max_addr,
                            file_offset=0,
                            address_space=self)
Exemplo n.º 28
0
Arquivo: vmi.py Projeto: google/rekall
class VMIAddressSpace(addrspace.BaseAddressSpace):
    """An address space which operates on top of Libvmi's interface."""

    __abstract = False
    __name = "vmi"
    order = 90
    volatile = True
    __image = True

    def __init__(self, base=None, filename=None, session=None, **kwargs):
        self.as_assert(libvmi, "The LibVMI python bindings must be installed")
        self.as_assert(base is None, "must be first Address Space")
        self.session = session

        url = filename or (session and session.GetParameter("filename"))
        self.as_assert(url, "Filename must be specified in session (e.g. "
                       "session.SetParameter('filename', 'vmi:///domain').")
        vmi_url = urlparse(url)
        self.as_assert(vmi_url.scheme == SCHEME, "URL scheme must be vmi://")
        self.as_assert(vmi_url.path, "No domain name specified")
        domain = vmi_url.path[1:]
        # hypervisor specified ?
        self.mode = None
        hypervisor = vmi_url.netloc
        if hypervisor:
            self.mode = VMIMode[hypervisor.upper()]
        # query parameters ?
        self.volatile = True
        if vmi_url.query:
            params = parse_qs(vmi_url.query, strict_parsing=True)
            try:
                self.volatile = strtobool((params['volatile'][0]))
            except KeyError:
                raise RuntimeError('Invalid query parameters in vmi:// URI')
        # build Libvmi instance
        super(VMIAddressSpace, self).__init__(base=base, session=session,
                                              **kwargs)
        self.vmi = Libvmi(domain, mode=self.mode, partial=True)
        self.min_addr = 0
        self.max_addr = self.vmi.get_memsize() - 1
        # pause in case volatile has been disabled
        if not self.volatile:
            self.vmi.pause_vm()
        # register flush hook to destroy vmi instance when session.Flush() is called
        session.register_flush_hook(self, self.close)

    def close(self):
        if not self.volatile:
            self.vmi.resume_vm()
        self.vmi.destroy()

    def read(self, addr, size):
        buffer, _ = self.vmi.read_pa(addr, size, padding=True)
        return buffer

    def write(self, addr, data):
        bytes_written = self.vmi.write_pa(addr, data)
        if bytes_written != len(data):
            return False
        return True

    def is_valid_address(self, addr):
        if addr is None:
            return False
        return self.min_addr <= addr <= self.max_addr

    def get_available_addresses(self):
        yield (self.min_addr, self.max_addr)

    def get_mappings(self, start=0, end=2 ** 64):
        yield addrspace.Run(start=self.min_addr, end=self.max_addr,
                            file_offset=0, address_space=self)
Exemplo n.º 29
0
def vmi(domain):
    vm_config = DOMAIN_CONFIGS[domain.name()]
    with Libvmi(domain.name(), config_mode=VMIConfig.DICT,
                config=vm_config) as vmi:
        yield vmi
Exemplo n.º 30
0
class LibVMIStub(GDBStub):
    def __init__(self, conn, addr, vm_name, process):
        super().__init__(conn, addr)
        self.vm_name = vm_name
        self.process = process
        self.cmd_to_handler = {
            GDBCmd.GEN_QUERY_GET: self.gen_query_get,
            GDBCmd.GEN_QUERY_SET: self.gen_query_set,
            GDBCmd.SET_THREAD_ID: self.set_thread_id,
            GDBCmd.TARGET_STATUS: self.target_status,
            GDBCmd.READ_REGISTERS: self.read_registers,
            GDBCmd.WRITE_REGISTERS: self.write_registers,
            GDBCmd.DETACH: self.detach,
            GDBCmd.READ_MEMORY: self.read_memory,
            GDBCmd.WRITE_MEMORY: self.write_memory,
            GDBCmd.WRITE_DATA_MEMORY: self.write_data_memory,
            GDBCmd.CONTINUE: self.cont_execution,
            GDBCmd.SINGLESTEP: self.singlestep,
            GDBCmd.IS_THREAD_ALIVE: self.is_thread_alive,
            GDBCmd.REMOVE_XPOINT: self.remove_xpoint,
            GDBCmd.INSERT_XPOINT: self.insert_xpoint,
            GDBCmd.BREAKIN: self.breakin,
            GDBCmd.V_FEATURES: self.v_features,
            GDBCmd.KILL_REQUEST: self.kill_request,
        }
        self.features = {
            b'multiprocess': False,
            b'swbreak': True,
            b'hwbreak': False,
            b'qRelocInsn': False,
            b'fork-events': False,
            b'vfork-events': False,
            b'exec-events': False,
            b'vContSupported': True,
            b'QThreadEvents': False,
            b'QStartNoAckMode': True,
            b'no-resumed': False,
            b'xmlRegisters': False,
            b'qXfer:memory-map:read': True
        }

    def __enter__(self):
        # init LibVMI
        self.vmi = Libvmi(self.vm_name,
                          init_flags=INIT_DOMAINNAME | INIT_EVENTS,
                          partial=True)
        self.vmi.init_paging(flags=0)
        # catch every exception to force a clean exit with __exit__
        # where vmi.destroy() must be called
        try:
            # determine debug context
            if not self.process:
                self.ctx = RawDebugContext(self.vmi)
            else:
                self.vmi.init_os()
                ostype = self.vmi.get_ostype()
                if ostype == VMIOS.WINDOWS:
                    self.ctx = WindowsDebugContext(self.vmi, self.process)
                elif ostype == VMIOS.LINUX:
                    self.ctx = LinuxDebugContext(self.vmi, self.process)
                else:
                    raise RuntimeError('unhandled ostype: {}'.format(
                        ostype.value))
            self.ctx.attach()
            self.attached = True
        except:
            logging.exception('Exception while initializing debug context')
        return self

    def __exit__(self, type, value, traceback):
        try:
            self.ctx.detach()
            self.attached = False
            self.ctx.bpm.restore_opcodes()
        except:
            logging.exception('Exception while detaching from debug context')
        finally:
            self.vmi.destroy()

    @lru_cache(maxsize=None)
    def get_memory_map_xml(self):
        # retrieve list of maps
        root = etree.Element('memory-map')
        for page_info in self.vmi.get_va_pages(self.ctx.get_dtb()):
            # <memory type="ram" start="addr" length="length"/>
            addr = str(hex(page_info.vaddr))
            size = str(hex(page_info.size))
            region = etree.Element('memory',
                                   type='ram',
                                   start=addr,
                                   length=size)
            root.append(region)
        doctype = '<!DOCTYPE memory-map ' \
                  'PUBLIC "+//IDN gnu.org//DTD GDB Memory Map V1.0//EN"' \
                  ' "http://sourceware.org/gdb/gdb-memory-map.dtd">'
        xml = etree.tostring(root,
                             xml_declaration=True,
                             doctype=doctype,
                             encoding='UTF-8')
        return xml

# commands

    def gen_query_get(self, packet_data):
        if re.match(b'Supported', packet_data):
            reply = self.set_supported_features(packet_data)
            pkt = GDBPacket(reply)
            self.send_packet(pkt)
            return True
        if re.match(b'TStatus', packet_data):
            # Ask the stub if there is a trace experiment running right now
            # reply: No trace has been run yet
            self.send_packet(GDBPacket(b'T0;tnotrun:0'))
            return True
        if re.match(b'TfV', packet_data):
            # TODO
            return False
        if re.match(b'fThreadInfo', packet_data):
            reply = b'm'
            for thread in self.ctx.list_threads():
                if reply != b'm':
                    reply += b','
                reply += b'%x' % thread.id
            self.send_packet(GDBPacket(reply))
            return True
        if re.match(b'sThreadInfo', packet_data):
            # send end of thread list
            self.send_packet(GDBPacket(b'l'))
            return True
        m = re.match(b'ThreadExtraInfo,(?P<thread_id>.+)', packet_data)
        if m:
            tid = int(m.group('thread_id'), 16)
            thread = self.ctx.get_thread(tid)
            if not thread:
                return False
            self.send_packet(GDBPacket(thread.name.encode()))
            return True
        if re.match(b'Attached', packet_data):
            # attach existing process: 0
            # attach new process: 1
            self.send_packet(GDBPacket(b'0'))
            return True
        if re.match(b'C', packet_data):
            # return current thread id
            self.send_packet(GDBPacket(b'QC%x' % self.ctx.cur_tid))
            return True
        m = re.match(b'Xfer:memory-map:read::(?P<offset>.*),(?P<length>.*)',
                     packet_data)
        if m:
            offset = int(m.group('offset'), 16)
            length = int(m.group('length'), 16)
            xml = self.get_memory_map_xml()
            chunk = xml[offset:offset + length]
            msg = b'm%s' % chunk
            if len(chunk) < length or offset + length >= len(xml):
                # last chunk
                msg = b'l%s' % chunk
            self.send_packet(GDBPacket(msg))
            return True
        return False

    def gen_query_set(self, packet_data):
        if re.match(b'StartNoAckMode', packet_data):
            self.no_ack = True
            self.send_packet(GDBPacket(b'OK'))
            # read last ack
            c = self.sock.recv(1)
            if c == b'+':
                return True
            else:
                return False
        return False

    def set_thread_id(self, packet_data):
        m = re.match(b'(?P<op>[cg])(?P<tid>([0-9a-f])+|-1)', packet_data)
        if m:
            op = m.group('op')
            tid = int(m.group('tid'), 16)
            self.log.debug('Current thread: %s', tid)
            self.ctx.cur_tid = tid
            # TODO op, Enn
            self.send_packet(GDBPacket(b'OK'))
            return True
        return False

    def target_status(self, packet_data):
        msg = b'S%.2x' % GDBSignal.TRAP.value
        self.send_packet(GDBPacket(msg))
        return True

    def kill_request(self, packet_data):
        self.attached = False
        return True

    def read_registers(self, packet_data):
        addr_width = self.vmi.get_address_width()
        if addr_width == 4:
            pack_fmt = '@I'
        else:
            pack_fmt = '@Q'

        cur_thread = self.ctx.get_thread()
        regs = cur_thread.read_registers()

        gen_regs_32 = [
            X86Reg.RAX, X86Reg.RCX, X86Reg.RDX, X86Reg.RBX, X86Reg.RSP,
            X86Reg.RBP, X86Reg.RSI, X86Reg.RDI, X86Reg.RIP
        ]

        gen_regs_64 = [
            X86Reg.R9, X86Reg.R10, X86Reg.R11, X86Reg.R12, X86Reg.R13,
            X86Reg.R14, X86Reg.R15
        ]
        # not available through libvmi
        seg_regs = [x + 1 for x in range(0, 6)]
        # write general registers
        msg = b''.join(
            [hexlify(struct.pack(pack_fmt, regs[r])) for r in gen_regs_32])
        if addr_width == 8:
            msg += b''.join(
                [hexlify(struct.pack(pack_fmt, regs[r])) for r in gen_regs_64])
        # write eflags
        msg += hexlify(struct.pack(pack_fmt, regs[X86Reg.RFLAGS]))
        # write segment registers
        msg += b''.join([hexlify(struct.pack(pack_fmt, r)) for r in seg_regs])
        self.send_packet(GDBPacket(msg))
        return True

    def write_registers(self, packet_data):
        addr_width = self.vmi.get_address_width()
        if addr_width == 4:
            pack_fmt = '@I'
        else:
            pack_fmt = '@Q'
        gen_regs_32 = [
            X86Reg.RAX, X86Reg.RCX, X86Reg.RDX, X86Reg.RBX, X86Reg.RSP,
            X86Reg.RBP, X86Reg.RSI, X86Reg.RDI, X86Reg.RIP
        ]

        gen_regs_64 = [
            X86Reg.R9, X86Reg.R10, X86Reg.R11, X86Reg.R12, X86Reg.R13,
            X86Reg.R14, X86Reg.R15
        ]

        # TODO parse the entire buffer
        # regs = Registers()
        regs = self.vmi.get_vcpuregs(0)
        iter = struct.iter_unpack(pack_fmt, unhexlify(packet_data))
        for r in gen_regs_32:
            value, *rest = next(iter)
            logging.debug('%s: %x', r.name, value)
            regs[r] = value
        # 64 bits ?
        if addr_width == 8:
            for r in gen_regs_64:
                value, *rest = next(iter)
                logging.debug('%s: %x', r.name, value)
                regs[r] = value
        # eflags
        value, *rest = next(iter)
        regs[X86Reg.RFLAGS] = value
        # TODO segment registers
        try:
            self.vmi.set_vcpuregs(regs, 0)
        except LibvmiError:
            return False
        else:
            self.send_packet(GDBPacket(b'OK'))
            return True

    def detach(self, packet_data):
        # detach
        self.attached = False
        try:
            self.vmi.resume_vm()
        except LibvmiError:
            pass
        self.send_packet(GDBPacket(b'OK'))
        return True

    def read_memory(self, packet_data):
        m = re.match(b'(?P<addr>.*),(?P<length>.*)', packet_data)
        if m:
            addr = int(m.group('addr'), 16)
            length = int(m.group('length'), 16)
            # TODO partial read
            try:
                buffer, bytes_read = self.vmi.read(
                    self.ctx.get_access_context(addr), length)
            except LibvmiError:
                return False
            else:
                self.send_packet(GDBPacket(hexlify(buffer)))
                return True
        return False

    def write_memory(self, packet_data):
        m = re.match(b'(?P<addr>.+),(?P<length>.+):(?P<data>.+)', packet_data)
        if m:
            addr = int(m.group('addr'), 16)
            length = int(m.group('length'), 16)
            data = unhexlify(m.group('data'))
            # TODO partial write
            try:
                bytes_written = self.vmi.write(
                    self.ctx.get_access_context(addr), data)
            except LibvmiError:
                return False
            else:
                self.send_packet(GDBPacket(b'OK'))
                return True
        return False

    def write_data_memory(self, packet_data):
        # ‘X addr,length:XX…’
        m = re.match(b'(?P<addr>.+),(?P<length>.+):(?P<data>.*)', packet_data)
        if m:
            addr = int(m.group('addr'), 16)
            length = int(m.group('length'), 16)
            data = m.group('data')
            # TODO partial write
            try:
                bytes_written = self.vmi.write(
                    self.ctx.get_access_context(addr), data)
            except LibvmiError:
                return False
            else:
                self.send_packet(GDBPacket(b'OK'))
                return True
        return False

    def cont_execution(self, packet_data):
        # TODO resume execution at addr
        addr = None
        m = re.match(b'(?P<addr>.+)', packet_data)
        if m:
            addr = int(m.group('addr'), 16)
            return False
        self.action_continue()
        self.send_packet(GDBPacket(b'OK'))
        # TODO race condition if listen thread started by action_continue
        # sends a packet before our 'OK' reply
        return True

    def singlestep(self, packet_data):
        # TODO resume execution at addr
        addr = None
        m = re.match(b'(?P<addr>.+)', packet_data)
        if m:
            addr = int(m.group('addr'), 16)
            return False

        self.ctx.bpm.wait_process_scheduled()
        self.ctx.bpm.singlestep_once()

        msg = b'S%.2x' % GDBSignal.TRAP.value
        self.send_packet(GDBPacket(msg))
        return True

    def is_thread_alive(self, packet_data):
        m = re.match(b'(?P<tid>.+)', packet_data)
        if m:
            tid = int(m.group('tid'), 16)
            thread = self.ctx.get_thread(tid)
            if not thread:
                # TODO Err XX
                return False
            reply = None
            if thread.is_alive():
                reply = b'OK'
            else:
                # TODO thread is dead
                reply = b'EXX'
            self.send_packet(GDBPacket(reply))
            return True
        return False

    def remove_xpoint(self, packet_data):
        # ‘z type,addr,kind’
        m = re.match(b'(?P<type>[0-9]),(?P<addr>.+),(?P<kind>.+)', packet_data)
        if not m:
            return False
        btype = int(m.group('type'))
        addr = int(m.group('addr'), 16)
        # kind -> size of breakpoint
        kind = int(m.group('kind'), 16)
        if btype == 0:
            # software breakpoint
            self.ctx.bpm.del_swbp(addr)
            self.send_packet(GDBPacket(b'OK'))
            return True
        return False

    def insert_xpoint(self, packet_data):
        # ‘Z type,addr,kind’
        m = re.match(b'(?P<type>[0-9]),(?P<addr>.+),(?P<kind>.+)', packet_data)
        if not m:
            return False
        btype = int(m.group('type'))
        addr = int(m.group('addr'), 16)
        # kind -> size of breakpoint
        kind = int(m.group('kind'), 16)
        if btype == 0:
            # software breakpoint
            cb_data = {
                'stub': self,
                'stop_listen': self.ctx.bpm.stop_listen,
            }
            self.ctx.bpm.add_swbp(addr, kind, self.ctx.cb_on_swbreak, cb_data)
            self.send_packet(GDBPacket(b'OK'))
            return True
        return False

    def breakin(self, packet_data):
        # stop event thread
        self.ctx.bpm.stop_listening()
        self.ctx.attach()
        msg = b'S%.2x' % GDBSignal.TRAP.value
        self.send_packet(GDBPacket(msg))
        return True

    def v_features(self, packet_data):
        if re.match(b'MustReplyEmpty', packet_data):
            # reply empty string
            # TODO refactoring, this should be treated as an unknown packet
            self.send_packet(GDBPacket(b''))
            return True
        if re.match(b'Cont\?', packet_data):
            # query the list of supported actions for vCont
            # reply: vCont[;action…]
            # we do not support continue or singlestep with a signal
            # but we have to advertise this to GDB, otherwise it won't use vCont
            self.send_packet(GDBPacket(b'vCont;c;C;s;S'))
            return True
        m = re.match(b'Cont(;(?P<action>[sc])(:(?P<tid>.*?))?).*', packet_data)
        if m:
            # vCont[;action[:thread-id]]…
            # we don't support threads
            action = m.group('action')
            if action == b's':
                self.ctx.bpm.wait_process_scheduled()
                self.ctx.bpm.singlestep_once()
                self.send_packet_noack(
                    GDBPacket(b'T%.2x' % GDBSignal.TRAP.value))
                return True
            if action == b'c':
                self.action_continue()
                return True
        if re.match(b'Kill;(?P<pid>[a-fA-F0-9]).+', packet_data):
            # vKill;pid
            # ignore pid, and don't kill the process anyway
            # just detach from the target
            # sent when GDB client has a ^D
            self.attached = False
            self.send_packet(GDBPacket(b'OK'))
            return True
        return False

# helpers

    def action_continue(self):
        self.vmi.resume_vm()
        # start listening on VMI events, asynchronously
        self.ctx.bpm.listen(block=False)

    def set_supported_features(self, packet_data):
        # split string and get features in a list
        # trash 'Supported
        req_features = re.split(b'[:|;]', packet_data)[1:]
        for f in req_features:
            if f[-1:] in [b'+', b'-']:
                name = f[:-1]
                value = True if f[-1:] == b'+' else False
            else:
                groups = f.split(b'=')
                name = groups[0]
                value = groups[1]
            # TODO check supported features
        reply_msg = b'PacketSize=%x' % PACKET_SIZE
        for name, value in self.features.items():
            if isinstance(value, bool):
                reply_msg += b';%s%s' % (name, b'+' if value else b'-')
            else:
                reply_msg += b';%s=%s' % (name, value)
        return reply_msg
Exemplo n.º 31
0
class ProcessChecker:

    whlte_list = ['sshd', 'insmod', 'kworker/0:2', 'kworker/u2:2']

    def __init__(self, vm, callback=None, interval=10):
        self._vm = vm
        self._callback = callback
        self._init_vmi()

        self.logger = setup_logger(
            self._vm.name, self._vm.name + '/' + self._vm.name + '.log',
            logging.INFO)
        self._ori_ps_list = self._get_process_list()
        self._ori_ps_set = set(self._ori_ps_list.keys())
        self._timer = RepeatableTimer(interval, self.check_process)

        self._dump_enabled = False

    def _init_vmi(self):
        """ Initialize LibVMI """
        self._vmi = Libvmi(self._vm.name)

        # get ostype
        self._os = self._vmi.get_ostype()

        # init offsets values
        self._tasks_offset = None
        self._name_offset = None
        self._pid_offset = None
        if self._os == VMIOS.LINUX:
            self._tasks_offset = self._vmi.get_offset("linux_tasks")
            self._name_offset = self._vmi.get_offset("linux_name")
            self._pid_offset = self._vmi.get_offset("linux_pid")
        elif self._os == VMIOS.WINDOWS:
            self._tasks_offset = self._vmi.get_offset("win_tasks")
            self._name_offset = self._vmi.get_offset("win_pname")
            self._pid_offset = self._vmi.get_offset("win_pid")
        else:
            self.logger.error("Unknown OS")
            return 0
        return 1

    def _get_process_list(self):
        """
        Get the process list inside the VM
        :return: process list of getting the page successfully or None.
        """
        # pause vm
        with pause(self._vmi):
            # demonstrate name and id accessors
            name = self._vmi.get_name()
            id = self._vmi.get_vmid()

            self.logger.debug("Process listing for VM %s (id: %s)", name, id)
            if self._os == VMIOS.LINUX:
                list_head = self._vmi.translate_ksym2v("init_task")
                list_head += self._tasks_offset
            elif self._os == VMIOS.WINDOWS:
                list_head = self._vmi.read_addr_ksym("PsActiveProcessHead")
            else:
                self.logger.error("Unknown OS")
                return None

            process_list = dict()
            cur_list_entry = list_head
            next_list_entry = self._vmi.read_addr_va(cur_list_entry, 0)

            while True:
                current_process = cur_list_entry - self._tasks_offset
                pid = self._vmi.read_32_va(current_process + self._pid_offset,
                                           0)
                procname = self._vmi.read_str_va(
                    current_process + self._name_offset, 0)
                process_list[pid] = (procname, hex(current_process))

                self.logger.debug("[%s] %s (struct addr:%s)", pid, procname,
                                  hex(current_process))
                cur_list_entry = next_list_entry
                next_list_entry = self._vmi.read_addr_va(cur_list_entry, 0)

                if self._os == VMIOS.WINDOWS and next_list_entry == list_head:
                    break
                elif self._os == VMIOS.LINUX and cur_list_entry == list_head:
                    break

            return process_list

    def check_process(self):
        self._timer.start()

        ps_list = self._get_process_list()
        #ps_list = self._filter_white_list(ps_list)

        ps_set = set(ps_list.keys())

        new_ps = ps_set - self._ori_ps_set
        reduce_ps = self._ori_ps_set - ps_set

        if new_ps:
            for pid in new_ps:
                if ps_list[pid][0] not in self.whlte_list:

                    if not self._vm.dump_enabled:
                        self._vm.dump_enabled = True
                        self._callback()

                    self.logger.warning(
                        "detected new process. [%s] %s (struct addr:%s)", pid,
                        ps_list[pid][0], ps_list[pid][1])

        if reduce_ps:
            for pid in reduce_ps:
                if self._ori_ps_list[pid][0] not in self.whlte_list:
                    self.logger.warning(
                        "detected process leave. [%s] %s (struct addr:%s)",
                        pid, self._ori_ps_list[pid][0],
                        self._ori_ps_list[pid][1])

        self._ori_ps_list = ps_list
        self._ori_ps_set = ps_set

    def start(self):
        """Start a thread that compares both of origin process list and a new one"""
        self._timer.start()

    def stop(self):
        """stop process checker"""
        self._timer.cancel()
        self._vmi.destroy()
Exemplo n.º 32
0
                                                                                       
import volatility.obj as obj                                                           
import volatility.addrspace as addrspace                                               
import volatility.registry as registry                                                 
                                                                                       
registry.PluginImporter()                                                              
registry.register_global_options(config, addrspace.BaseAddressSpace)                   
                                                                                       
## Main program starts here:                                                           
# Initialize address space (same as a=addrspace() in linux_volshell)                   
a=utils.load_as(config)                                                                
p=a.profile                                                                            
# Lookup kernel symbol pointing to first task                                        
task_addr = p.get_symbol("init_task")                                                     
# Create python object for this task                                                 
# Note that the "init_task" symbol does not point to the start of the                    
# task_struct data structure "list" element of the data structures.                        
init_task = obj.Object("task_struct", vm=a, offset=task_addr)
l = list(init_task.tasks)

from libvmi import Libvmi
vmi = Libvmi(sys.argv[5])

t_cred_init = l[0].real_cred

for t in l:
	if (t.pid == int(sys.argv[6])):
		t_cred_pa = a.vtop(t.real_cred.obj_offset)
		vmi.write_64_pa(t_cred_pa, t_cred_init)