Package modules :: Package processing :: Module memory
[hide private]
[frames] | no frames]

Source Code for Module modules.processing.memory

  1  # Copyright (C) 2010-2014 Cuckoo Foundation. 
  2  # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org 
  3  # See the file 'docs/LICENSE' for copying permission. 
  4   
  5  import os 
  6  import logging 
  7   
  8  from lib.cuckoo.common.abstracts import Processing 
  9  from lib.cuckoo.common.config import Config 
 10  from lib.cuckoo.common.constants import CUCKOO_ROOT 
 11   
 12  try: 
 13      import volatility.conf as conf 
 14      import volatility.registry as registry 
 15      import volatility.commands as commands 
 16      import volatility.utils as utils 
 17      import volatility.plugins.malware.devicetree as devicetree 
 18      import volatility.plugins.getsids as sidm 
 19      import volatility.plugins.privileges as privm 
 20      import volatility.plugins.taskmods as taskmods 
 21      import volatility.win32.tasks as tasks 
 22      import volatility.obj as obj 
 23      HAVE_VOLATILITY = True 
 24  except ImportError: 
 25      HAVE_VOLATILITY = False 
 26   
 27  log = logging.getLogger(__name__) 
 28   
29 -class VolatilityAPI(object):
30 """ Volatility API interface.""" 31
32 - def __init__(self, memdump, osprofile=None):
33 """@param memdump: the memdump file path 34 @param osprofile: the profile (OS type) 35 """ 36 registry.PluginImporter() 37 self.memdump = memdump 38 self.osprofile = osprofile 39 self.config = None 40 self.__config()
41
42 - def __config(self):
43 """Creates a volatility configuration.""" 44 self.config = conf.ConfObject() 45 self.config.optparser.set_conflict_handler("resolve") 46 registry.register_global_options(self.config, commands.Command) 47 base_conf = { 48 "profile": "WinXPSP2x86", 49 "use_old_as": None, 50 "kdbg": None, 51 "help": False, 52 "kpcr": None, 53 "tz": None, 54 "pid": None, 55 "output_file": None, 56 "physical_offset": None, 57 "conf_file": None, 58 "dtb": None, 59 "output": None, 60 "info": None, 61 "location": "file://" + self.memdump, 62 "plugins": None, 63 "debug": None, 64 "cache_dtb": True, 65 "filename": None, 66 "cache_directory": None, 67 "verbose": None, 68 "write": False 69 } 70 71 if self.osprofile: 72 base_conf["profile"] = self.osprofile 73 74 for key, value in base_conf.items(): 75 self.config.update(key, value) 76 77 self.addr_space = utils.load_as(self.config) 78 self.plugins = registry.get_plugin_classes(commands.Command, 79 lower=True) 80 81 return self.config
82
83 - def pslist(self):
84 """Volatility pslist plugin. 85 @see volatility/plugins/taskmods.py 86 """ 87 log.debug("Executing Volatility pslist plugin on " 88 "{0}".format(self.memdump)) 89 90 self.__config() 91 results = [] 92 93 command = taskmods.PSList(self.config) 94 for process in command.calculate(): 95 new = { 96 "process_name": str(process.ImageFileName), 97 "process_id": int(process.UniqueProcessId), 98 "parent_id": int(process.InheritedFromUniqueProcessId), 99 "num_threads": str(process.ActiveThreads), 100 "num_handles": str(process.ObjectTable.HandleCount), 101 "session_id": str(process.SessionId), 102 "create_time": str(process.CreateTime or ""), 103 "exit_time": str(process.ExitTime or ""), 104 } 105 106 results.append(new) 107 108 return dict(config={}, data=results)
109
110 - def psxview(self):
111 """Volatility psxview plugin. 112 @see volatility/plugins/malware/psxview.py 113 """ 114 log.debug("Executing Volatility psxview plugin on " 115 "{0}".format(self.memdump)) 116 117 self.__config() 118 results = [] 119 120 command = self.plugins["psxview"](self.config) 121 for offset, process, ps_sources in command.calculate(): 122 new = { 123 "process_name": str(process.ImageFileName), 124 "process_id": int(process.UniqueProcessId), 125 "pslist": str(ps_sources['pslist'].has_key(offset)), 126 "psscan": str(ps_sources['psscan'].has_key(offset)), 127 "thrdproc": str(ps_sources['thrdproc'].has_key(offset)), 128 "pspcid": str(ps_sources['pspcid'].has_key(offset)), 129 "csrss": str(ps_sources['csrss'].has_key(offset)), 130 "session": str(ps_sources['session'].has_key(offset)), 131 "deskthrd": str(ps_sources['deskthrd'].has_key(offset)) 132 } 133 134 results.append(new) 135 136 return dict(config={}, data=results)
137
138 - def callbacks(self):
139 """Volatility callbacks plugin. 140 @see volatility/plugins/malware/callbacks.py 141 """ 142 log.debug("Executing Volatility callbacks plugin on " 143 "{0}".format(self.memdump)) 144 145 self.__config() 146 results = [] 147 148 command = self.plugins["callbacks"](self.config) 149 for (sym, cb, detail), mods, mod_addrs in command.calculate(): 150 module = tasks.find_module(mods, mod_addrs, command.kern_space.address_mask(cb)) 151 152 if module: 153 module_name = module.BaseDllName or module.FullDllName 154 else: 155 module_name = "UNKNOWN" 156 157 new = { 158 "type": str(sym), 159 "callback": hex(int(cb)), 160 "module": str(module_name), 161 "details": str(detail or "-"), 162 } 163 164 results.append(new) 165 166 return dict(config={}, data=results)
167
168 - def idt(self):
169 """Volatility idt plugin. 170 @see volatility/plugins/malware/idt.py 171 """ 172 log.debug("Executing Volatility idt plugin on " 173 "{0}".format(self.memdump)) 174 175 self.__config() 176 results = [] 177 178 command = self.plugins["idt"](self.config) 179 for n, entry, addr, module in command.calculate(): 180 if module: 181 module_name = str(module.BaseDllName or '') 182 sect_name = command.get_section_name(module, addr) 183 else: 184 module_name = "UNKNOWN" 185 sect_name = '' 186 187 # The parent is IDT. The grand-parent is _KPCR. 188 cpu_number = entry.obj_parent.obj_parent.ProcessorBlock.Number 189 new = { 190 "cpu_number": int(cpu_number), 191 "index": int(n), 192 "selector": hex(int(entry.Selector)), 193 "address": hex(int(addr)), 194 "module": module_name, 195 "section": sect_name, 196 } 197 results.append(new) 198 199 return dict(config={}, data=results)
200
201 - def timers(self):
202 """Volatility timers plugin. 203 @see volatility/plugins/malware/timers.py 204 """ 205 log.debug("Executing Volatility timers plugin on " 206 "{0}".format(self.memdump)) 207 208 self.__config() 209 results = [] 210 211 command = self.plugins["timers"](self.config) 212 for timer, module in command.calculate(): 213 if timer.Header.SignalState.v(): 214 signaled = "Yes" 215 else: 216 signaled = "-" 217 218 if module: 219 module_name = str(module.BaseDllName or '') 220 else: 221 module_name = "UNKNOWN" 222 223 due_time = "{0:#010x}:{1:#010x}".format(timer.DueTime.HighPart, timer.DueTime.LowPart) 224 225 new = { 226 "offset": hex(timer.obj_offset), 227 "due_time": due_time, 228 "period": int(timer.Period), 229 "signaled": signaled, 230 "routine": hex(int(timer.Dpc.DeferredRoutine)), 231 "module": module_name, 232 } 233 results.append(new) 234 235 return dict(config={}, data=results)
236
237 - def messagehooks(self):
238 """Volatility messagehooks plugin. 239 @see volatility/plugins/malware/messagehooks.py 240 """ 241 log.debug("Executing Volatility messagehooks plugin on " 242 "{0}".format(self.memdump)) 243 244 self.__config() 245 results = [] 246 247 command = self.plugins["messagehooks"](self.config) 248 for winsta, atom_tables in command.calculate(): 249 for desk in winsta.desktops(): 250 for name, hook in desk.hooks(): 251 module = command.translate_hmod(winsta, atom_tables, hook.ihmod) 252 new = { 253 "offset": hex(int(hook.obj_offset)), 254 "session": int(winsta.dwSessionId), 255 "desktop": "{0}\\{1}".format(winsta.Name, desk.Name), 256 "thread": "<any>", 257 "filter": str(name), 258 "flags": str(hook.flags), 259 "function": hex(int(hook.offPfn)), 260 "module": str(module), 261 } 262 results.append(new) 263 264 for thrd in desk.threads(): 265 info = "{0} ({1} {2})".format( 266 thrd.pEThread.Cid.UniqueThread, 267 thrd.ppi.Process.ImageFileName, 268 thrd.ppi.Process.UniqueProcessId) 269 270 for name, hook in thrd.hooks(): 271 module = command.translate_hmod(winsta, atom_tables, hook.ihmod) 272 273 new = { 274 "offset": hex(int(hook.obj_offset)), 275 "session": int(winsta.dwSessionId), 276 "desktop": "{0}\\{1}".format(winsta.Name, desk.Name), 277 "thread": str(info), 278 "filter": str(name), 279 "flags": str(hook.flags), 280 "function": hex(int(hook.offPfn)), 281 "module": str(module), 282 } 283 results.append(new) 284 285 return dict(config={}, data=results)
286
287 - def getsids(self):
288 """Volatility getsids plugin. 289 @see volatility/plugins/malware/getsids.py 290 """ 291 292 log.debug("Executing Volatility getsids plugin on " 293 "{0}".format(self.memdump)) 294 295 self.__config() 296 results = [] 297 298 command = self.plugins["getsids"](self.config) 299 for task in command.calculate(): 300 token = task.get_token() 301 302 if not token: 303 continue 304 305 for sid_string in token.get_sids(): 306 if sid_string in sidm.well_known_sids: 307 sid_name = " {0}".format(sidm.well_known_sids[sid_string]) 308 else: 309 sid_name_re = sidm.find_sid_re(sid_string, sidm.well_known_sid_re) 310 if sid_name_re: 311 sid_name = " {0}".format(sid_name_re) 312 else: 313 sid_name = "" 314 315 new = { 316 "filename": str(task.ImageFileName), 317 "process_id": int(task.UniqueProcessId), 318 "sid_string": str(sid_string), 319 "sid_name": str(sid_name), 320 } 321 results.append(new) 322 323 return dict(config={}, data=results)
324
325 - def privs(self):
326 """Volatility privs plugin. 327 @see volatility/plugins/malware/privs.py 328 """ 329 330 log.debug("Executing Volatility privs plugin on " 331 "{0}".format(self.memdump)) 332 333 self.__config() 334 results = [] 335 336 command = self.plugins["privs"](self.config) 337 338 for task in command.calculate(): 339 for value, present, enabled, default in task.get_token().privileges(): 340 try: 341 name, desc = privm.PRIVILEGE_INFO[int(value)] 342 except KeyError: 343 continue 344 345 attributes = [] 346 if present: 347 attributes.append("Present") 348 if enabled: 349 attributes.append("Enabled") 350 if default: 351 attributes.append("Default") 352 353 new = { 354 "process_id": int(task.UniqueProcessId), 355 "filename": str(task.ImageFileName), 356 "value": int(value), 357 "privilege": str(name), 358 "attributes": ",".join(attributes), 359 "description": str(desc), 360 } 361 results.append(new) 362 363 return dict(config={}, data=results)
364
365 - def malfind(self, dump_dir=None):
366 """Volatility malfind plugin. 367 @param dump_dir: optional directory for dumps 368 @see volatility/plugins/malware/malfind.py 369 """ 370 log.debug("Executing Volatility malfind plugin on " 371 "{0}".format(self.memdump)) 372 373 self.__config() 374 results = [] 375 376 command = self.plugins["malfind"](self.config) 377 for task in command.calculate(): 378 for vad, address_space in task.get_vads(vad_filter=task._injection_filter): 379 if command._is_vad_empty(vad, address_space): 380 continue 381 382 new = { 383 "process_name": str(task.ImageFileName), 384 "process_id": int(task.UniqueProcessId), 385 "vad_start": "{0:#x}".format(vad.Start), 386 "vad_tag": str(vad.Tag), 387 } 388 results.append(new) 389 390 if dump_dir: 391 filename = os.path.join(dump_dir, "process.{0:#x}.{1:#x}.dmp".format(task.obj_offset, vad.Start)) 392 command.dump_vad(filename, vad, address_space) 393 394 return dict(config={}, data=results)
395
396 - def apihooks(self):
397 """Volatility apihooks plugin. 398 @see volatility/plugins/malware/apihooks.py 399 """ 400 log.debug("Executing Volatility apihooks plugin on {0}".format(self.memdump)) 401 402 self.__config() 403 results = [] 404 405 command = self.plugins["apihooks"](self.config) 406 for process, module, hook in command.calculate(): 407 new = { 408 "hook_mode": str(hook.Mode), 409 "hook_type": str(hook.Type), 410 "victim_module": str(module.BaseDllName or ""), 411 "victim_function": str(hook.Detail), 412 "hook_address": "{0:#x}".format(hook.hook_address), 413 "hooking_module": str(hook.HookModule) 414 } 415 416 if process: 417 new["process_id"] = int(process.UniqueProcessId) 418 new["process_name"] = str(process.ImageFileName) 419 420 results.append(new) 421 422 return dict(config={}, data=results)
423
424 - def dlllist(self):
425 """Volatility dlllist plugin. 426 @see volatility/plugins/taskmods.py 427 """ 428 log.debug("Executing Volatility dlllist plugin on {0}".format(self.memdump)) 429 430 self.__config() 431 results = [] 432 433 command = self.plugins["dlllist"](self.config) 434 for task in command.calculate(): 435 new = { 436 "process_id": int(task.UniqueProcessId), 437 "process_name": str(task.ImageFileName), 438 "commandline": str(task.Peb.ProcessParameters.CommandLine or ""), 439 "loaded_modules": [] 440 } 441 442 for module in task.get_load_modules(): 443 new["loaded_modules"].append({ 444 "dll_base": str(module.DllBase), 445 "dll_size": str(module.SizeOfImage), 446 "dll_full_name": str(module.FullDllName or ""), 447 "dll_load_count": int(module.LoadCount), 448 }) 449 450 results.append(new) 451 452 return dict(config={}, data=results)
453
454 - def handles(self):
455 """Volatility handles plugin. 456 @see volatility/plugins/handles.py 457 """ 458 log.debug("Executing Volatility handles plugin on {0}".format(self.memdump)) 459 460 self.__config() 461 results = [] 462 463 command = self.plugins["handles"](self.config) 464 for pid, handle, object_type, name in command.calculate(): 465 new = { 466 "process_id": int(pid), 467 "handle_value": str(handle.HandleValue), 468 "handle_granted_access": str(handle.GrantedAccess), 469 "handle_type": str(object_type), 470 "handle_name": str(name) 471 } 472 473 results.append(new) 474 475 return dict(config={}, data=results)
476
477 - def ldrmodules(self):
478 """Volatility ldrmodules plugin. 479 @see volatility/plugins/malware/malfind.py 480 """ 481 log.debug("Executing Volatility ldrmodules plugin on {0}".format(self.memdump)) 482 483 self.__config() 484 results = [] 485 486 command = self.plugins["ldrmodules"](self.config) 487 for task in command.calculate(): 488 # Build a dictionary for all three PEB lists where the 489 # keys are base address and module objects are the values. 490 inloadorder = dict((mod.DllBase.v(), mod) for mod in task.get_load_modules()) 491 ininitorder = dict((mod.DllBase.v(), mod) for mod in task.get_init_modules()) 492 inmemorder = dict((mod.DllBase.v(), mod) for mod in task.get_mem_modules()) 493 494 # Build a similar dictionary for the mapped files. 495 mapped_files = {} 496 for vad, address_space in task.get_vads(vad_filter=task._mapped_file_filter): 497 # Note this is a lot faster than acquiring the full 498 # vad region and then checking the first two bytes. 499 if obj.Object("_IMAGE_DOS_HEADER", offset=vad.Start, vm=address_space).e_magic != 0x5A4D: 500 continue 501 502 mapped_files[int(vad.Start)] = str(vad.FileObject.FileName or "") 503 504 # For each base address with a mapped file, print info on 505 # the other PEB lists to spot discrepancies. 506 for base in mapped_files.keys(): 507 # Does the base address exist in the PEB DLL lists? 508 load_mod = inloadorder.get(base, None) 509 init_mod = ininitorder.get(base, None) 510 mem_mod = inmemorder.get(base, None) 511 512 new = { 513 "process_id": int(task.UniqueProcessId), 514 "process_name": str(task.ImageFileName), 515 "dll_base": "{0:#x}".format(base), 516 "dll_in_load": not load_mod is None, 517 "dll_in_init": not init_mod is None, 518 "dll_in_mem": not mem_mod is None, 519 "dll_mapped_path": str(mapped_files[base]), 520 "load_full_dll_name": "", 521 "init_full_dll_name": "", 522 "mem_full_dll_name": "" 523 } 524 525 if load_mod: 526 new["load_full_dll_name"] = str(load_mod.FullDllName) 527 528 if init_mod: 529 new["init_full_dll_name"] = str(init_mod.FullDllName) 530 531 if mem_mod: 532 new["mem_full_dll_name"] = str(mem_mod.FullDllName) 533 534 results.append(new) 535 536 return dict(config={}, data=results)
537
538 - def mutantscan(self):
539 """Volatility mutantscan plugin. 540 @see volatility/plugins/filescan.py 541 """ 542 log.debug("Executing Volatility mutantscan module on {0}".format(self.memdump)) 543 544 self.__config() 545 results = [] 546 547 command = self.plugins["mutantscan"](self.config) 548 for object_obj, mutant in command.calculate(): 549 tid = 0 550 pid = 0 551 if mutant.OwnerThread > 0x80000000: 552 thread = mutant.OwnerThread.dereference_as("_ETHREAD") 553 tid = thread.Cid.UniqueThread 554 pid = thread.Cid.UniqueProcess 555 556 new = { 557 "mutant_offset": "{0:#x}".format(mutant.obj_offset), 558 "num_pointer": int(object_obj.PointerCount), 559 "num_handles": int(object_obj.HandleCount), 560 "mutant_signal_state": str(mutant.Header.SignalState), 561 "mutant_name": str(object_obj.NameInfo.Name or ""), 562 "process_id": int(pid), 563 "thread_id": int(tid) 564 } 565 566 results.append(new) 567 568 return dict(config={}, data=results)
569
570 - def devicetree(self):
571 """Volatility devicetree plugin. 572 @see volatility/plugins/malware/devicetree.py 573 """ 574 log.debug("Executing Volatility devicetree module on {0}".format(self.memdump)) 575 576 self.__config() 577 results = [] 578 579 command = self.plugins["devicetree"](self.config) 580 for _object_obj, driver_obj, _ in command.calculate(): 581 new = { 582 "driver_offset": "0x{0:08x}".format(driver_obj.obj_offset), 583 "driver_name": str(driver_obj.DriverName or ""), 584 "devices": [] 585 } 586 587 for device in driver_obj.devices(): 588 device_header = obj.Object( 589 "_OBJECT_HEADER", 590 offset=device.obj_offset - device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"), 591 vm=device.obj_vm, 592 native_vm=device.obj_native_vm 593 ) 594 595 device_name = str(device_header.NameInfo.Name or "") 596 597 new_device = { 598 "device_offset": "0x{0:08x}".format(device.obj_offset), 599 "device_name": device_name, 600 "device_type": devicetree.DEVICE_CODES.get(device.DeviceType.v(), "UNKNOWN"), 601 "devices_attached": [] 602 } 603 604 new["devices"].append(new_device) 605 606 level = 0 607 608 for att_device in device.attached_devices(): 609 device_header = obj.Object( 610 "_OBJECT_HEADER", 611 offset=att_device.obj_offset - att_device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"), 612 vm=att_device.obj_vm, 613 native_vm=att_device.obj_native_vm 614 ) 615 616 device_name = str(device_header.NameInfo.Name or "") 617 name = (device_name + " - " + str(att_device.DriverObject.DriverName or "")) 618 619 new_device["devices_attached"].append({ 620 "level": level, 621 "attached_device_offset": "0x{0:08x}".format(att_device.obj_offset), 622 "attached_device_name": name, 623 "attached_device_type": devicetree.DEVICE_CODES.get(att_device.DeviceType.v(), "UNKNOWN") 624 }) 625 626 level += 1 627 628 results.append(new) 629 630 return dict(config={}, data=results)
631
632 - def svcscan(self):
633 """Volatility svcscan plugin - scans for services. 634 @see volatility/plugins/malware/svcscan.py 635 """ 636 log.debug("Executing Volatility svcscan plugin on {0}".format(self.memdump)) 637 638 self.__config() 639 results = [] 640 641 command = self.plugins["svcscan"](self.config) 642 for rec in command.calculate(): 643 new = { 644 "service_offset": "{0:#x}".format(rec.obj_offset), 645 "service_order": int(rec.Order), 646 "process_id": int(rec.Pid), 647 "service_name": str(rec.ServiceName.dereference()), 648 "service_display_name": str(rec.DisplayName.dereference()), 649 "service_type": str(rec.Type), 650 "service_binary_path": str(rec.Binary), 651 "service_state": str(rec.State) 652 } 653 654 results.append(new) 655 656 return dict(config={}, data=results)
657
658 - def modscan(self):
659 """Volatility modscan plugin. 660 @see volatility/plugins/modscan.py 661 """ 662 log.debug("Executing Volatility modscan plugin on {0}".format(self.memdump)) 663 664 self.__config() 665 results = [] 666 667 command = self.plugins["modscan"](self.config) 668 for ldr_entry in command.calculate(): 669 new = { 670 "kernel_module_offset": "{0:#x}".format(ldr_entry.obj_offset), 671 "kernel_module_name": str(ldr_entry.BaseDllName or ""), 672 "kernel_module_file": str(ldr_entry.FullDllName or ""), 673 "kernel_module_base": "{0:#x}".format(ldr_entry.DllBase), 674 "kernel_module_size": int(ldr_entry.SizeOfImage), 675 } 676 677 results.append(new) 678 679 return dict(config={}, data=results)
680
681 - def imageinfo(self):
682 """Volatility imageinfo plugin. 683 @see volatility/plugins/imageinfo.py 684 """ 685 log.debug("Executing Volatility imageinfo plugin on {0}".format(self.memdump)) 686 687 self.__config() 688 results = [] 689 690 command = self.plugins["imageinfo"](self.config) 691 new = {} 692 for key, value in command.calculate(): 693 new[key] = value 694 695 osp = new["Suggested Profile(s)"].split(",")[0] 696 new["osprofile"] = osp 697 698 results.append(new) 699 700 return dict(config={}, data=results)
701
702 -class VolatilityManager(object):
703 """Handle several volatility results.""" 704
705 - def __init__(self, memfile, osprofile=None):
706 self.mask_pid = [] 707 self.taint_pid = set() 708 self.memfile = memfile 709 710 conf_path = os.path.join(CUCKOO_ROOT, "conf", "memory.conf") 711 if not os.path.exists(conf_path): 712 log.error("Configuration file volatility.conf not found".format(conf_path)) 713 self.voptions = False 714 return 715 716 self.voptions = Config(conf_path) 717 718 for pid in self.voptions.mask.pid_generic.split(","): 719 pid = pid.strip() 720 if pid: 721 self.mask_pid.append(int(pid)) 722 723 self.no_filter = not self.voptions.mask.enabled 724 if self.voptions.basic.guest_profile: 725 self.osprofile = self.voptions.basic.guest_profile 726 else: 727 self.osprofile = osprofile or self.get_osprofile()
728
729 - def get_osprofile(self):
730 """Get the OS profile""" 731 return VolatilityAPI(self.memfile).imageinfo()["data"][0]["osprofile"]
732
733 - def run(self):
734 results = {} 735 736 # Exit if options were not loaded. 737 if not self.voptions: 738 return 739 740 vol = VolatilityAPI(self.memfile, self.osprofile) 741 742 # TODO: improve the load of volatility functions. 743 if self.voptions.pslist.enabled: 744 results["pslist"] = vol.pslist() 745 if self.voptions.psxview.enabled: 746 results["psxview"] = vol.psxview() 747 if self.voptions.callbacks.enabled: 748 results["callbacks"] = vol.callbacks() 749 if self.voptions.idt.enabled: 750 results["idt"] = vol.idt() 751 if self.voptions.timers.enabled: 752 results["timers"] = vol.timers() 753 if self.voptions.messagehooks.enabled: 754 results["messagehooks"] = vol.messagehooks() 755 if self.voptions.getsids.enabled: 756 results["getsids"] = vol.getsids() 757 if self.voptions.privs.enabled: 758 results["privs"] = vol.privs() 759 if self.voptions.malfind.enabled: 760 results["malfind"] = vol.malfind() 761 if self.voptions.apihooks.enabled: 762 results["apihooks"] = vol.apihooks() 763 if self.voptions.dlllist.enabled: 764 results["dlllist"] = vol.dlllist() 765 if self.voptions.handles.enabled: 766 results["handles"] = vol.handles() 767 if self.voptions.ldrmodules.enabled: 768 results["ldrmodules"] = vol.ldrmodules() 769 if self.voptions.mutantscan.enabled: 770 results["mutantscan"] = vol.mutantscan() 771 if self.voptions.devicetree.enabled: 772 results["devicetree"] = vol.devicetree() 773 if self.voptions.svcscan.enabled: 774 results["svcscan"] = vol.svcscan() 775 if self.voptions.modscan.enabled: 776 results["modscan"] = vol.modscan() 777 778 self.find_taint(results) 779 self.cleanup() 780 781 return self.mask_filter(results)
782
783 - def mask_filter(self, old):
784 """Filter out masked stuff. Keep tainted stuff.""" 785 new = {} 786 787 for akey in old.keys(): 788 new[akey] = {"config": old[akey]["config"], "data": []} 789 conf = getattr(self.voptions, akey, None) 790 new[akey]["config"]["filter"] = conf.filter 791 for item in old[akey]["data"]: 792 # TODO: need to improve this logic. 793 if not conf.filter: 794 new[akey]["data"].append(item) 795 elif ("process_id" in item and item["process_id"] in self.mask_pid and not item["process_id"] in self.taint_pid): 796 pass 797 else: 798 new[akey]["data"].append(item) 799 return new
800
801 - def find_taint(self, res):
802 """Find tainted items.""" 803 if "malfind" in res: 804 for item in res["malfind"]["data"]: 805 self.taint_pid.add(item["process_id"])
806
807 - def cleanup(self):
808 """Delete the memory dump (if configured to do so).""" 809 810 if self.voptions.basic.delete_memdump: 811 try: 812 os.remove(self.memfile) 813 except OSError: 814 log.error("Unable to delete memory dump file at path \"%s\" ", self.memfile)
815
816 -class Memory(Processing):
817 """Volatility Analyzer.""" 818
819 - def run(self):
820 """Run analysis. 821 @return: volatility results dict. 822 """ 823 self.key = "memory" 824 825 results = {} 826 if HAVE_VOLATILITY: 827 if self.memory_path and os.path.exists(self.memory_path): 828 try: 829 vol = VolatilityManager(self.memory_path) 830 results = vol.run() 831 except Exception: 832 log.exception("Generic error executing volatility") 833 else: 834 log.error("Memory dump not found: to run volatility you have to enable memory_dump") 835 else: 836 log.error("Cannot run volatility module: volatility library not available") 837 838 return results
839