1
2
3
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.malware.apihooks as apihooks
19 import volatility.plugins.getsids as sidm
20 import volatility.plugins.privileges as privm
21 import volatility.plugins.taskmods as taskmods
22 import volatility.win32.tasks as tasks
23 import volatility.obj as obj
24 import volatility.exceptions as exc
25 import volatility.plugins.filescan as filescan
26
27 HAVE_VOLATILITY = True
28 rootlogger = logging.getLogger()
29
30 logging.getLogger("volatility.obj").setLevel(rootlogger.level)
31 logging.getLogger("volatility.utils").setLevel(rootlogger.level)
32 except ImportError:
33 HAVE_VOLATILITY = False
34
35 log = logging.getLogger(__name__)
36
38 """ Volatility API interface."""
39
40 - def __init__(self, memdump, osprofile=None):
41 """@param memdump: the memdump file path
42 @param osprofile: the profile (OS type)
43 """
44 registry.PluginImporter()
45 self.memdump = memdump
46 self.osprofile = osprofile
47 self.config = None
48 self.addr_space = None
49 self.__config()
50
52 """Use psscan to get system dtb and apply it."""
53 ps = filescan.PSScan(self.config)
54 for ep in ps.calculate():
55 if str(ep.ImageFileName) == "System":
56 self.config.update("dtb",ep.Pcb.DirectoryTableBase)
57 return True
58 return False
59
60
62 """Creates a volatility configuration."""
63 if self.config != None and self.addr_space != None:
64 return self.config
65
66 self.config = conf.ConfObject()
67 self.config.optparser.set_conflict_handler("resolve")
68 registry.register_global_options(self.config, commands.Command)
69 base_conf = {
70 "profile": "WinXPSP2x86",
71 "use_old_as": None,
72 "kdbg": None,
73 "help": False,
74 "kpcr": None,
75 "tz": None,
76 "pid": None,
77 "output_file": None,
78 "physical_offset": None,
79 "conf_file": None,
80 "dtb": None,
81 "output": None,
82 "info": None,
83 "location": "file://" + self.memdump,
84 "plugins": None,
85 "debug": None,
86 "cache_dtb": True,
87 "filename": None,
88 "cache_directory": None,
89 "verbose": None,
90 "write": False
91 }
92
93 if self.osprofile:
94 base_conf["profile"] = self.osprofile
95
96 for key, value in base_conf.items():
97 self.config.update(key, value)
98
99
100
101 try:
102 self.addr_space = utils.load_as(self.config)
103 except exc.AddrSpaceError as e:
104 if self._get_dtb():
105 self.addr_space = utils.load_as(self.config)
106 else:
107 raise
108
109 self.plugins = registry.get_plugin_classes(commands.Command,
110 lower=True)
111
112 return self.config
113
115 """Volatility pslist plugin.
116 @see volatility/plugins/taskmods.py
117 """
118 log.debug("Executing Volatility pslist plugin on "
119 "{0}".format(self.memdump))
120
121 self.__config()
122 results = []
123
124 command = taskmods.PSList(self.config)
125 for process in command.calculate():
126 new = {
127 "process_name": str(process.ImageFileName),
128 "process_id": int(process.UniqueProcessId),
129 "parent_id": int(process.InheritedFromUniqueProcessId),
130 "num_threads": str(process.ActiveThreads),
131 "num_handles": str(process.ObjectTable.HandleCount),
132 "session_id": str(process.SessionId),
133 "create_time": str(process.CreateTime or ""),
134 "exit_time": str(process.ExitTime or ""),
135 }
136
137 results.append(new)
138
139 return dict(config={}, data=results)
140
142 """Volatility psxview plugin.
143 @see volatility/plugins/malware/psxview.py
144 """
145 log.debug("Executing Volatility psxview plugin on "
146 "{0}".format(self.memdump))
147
148 self.__config()
149 results = []
150
151 command = self.plugins["psxview"](self.config)
152 for offset, process, ps_sources in command.calculate():
153 new = {
154 "process_name": str(process.ImageFileName),
155 "process_id": int(process.UniqueProcessId),
156 "pslist": str(ps_sources['pslist'].has_key(offset)),
157 "psscan": str(ps_sources['psscan'].has_key(offset)),
158 "thrdproc": str(ps_sources['thrdproc'].has_key(offset)),
159 "pspcid": str(ps_sources['pspcid'].has_key(offset)),
160 "csrss": str(ps_sources['csrss'].has_key(offset)),
161 "session": str(ps_sources['session'].has_key(offset)),
162 "deskthrd": str(ps_sources['deskthrd'].has_key(offset))
163 }
164
165 results.append(new)
166
167 return dict(config={}, data=results)
168
170 """Volatility callbacks plugin.
171 @see volatility/plugins/malware/callbacks.py
172 """
173 log.debug("Executing Volatility callbacks plugin on "
174 "{0}".format(self.memdump))
175
176 self.__config()
177 results = []
178
179 command = self.plugins["callbacks"](self.config)
180 for (sym, cb, detail), mods, mod_addrs in command.calculate():
181 module = tasks.find_module(mods, mod_addrs, self.addr_space.address_mask(cb))
182
183 if module:
184 module_name = module.BaseDllName or module.FullDllName
185 else:
186 module_name = "UNKNOWN"
187
188 new = {
189 "type": str(sym),
190 "callback": hex(int(cb)),
191 "module": str(module_name),
192 "details": str(detail or "-"),
193 }
194
195 results.append(new)
196
197 return dict(config={}, data=results)
198
200 """Volatility idt plugin.
201 @see volatility/plugins/malware/idt.py
202 """
203 log.debug("Executing Volatility idt plugin on "
204 "{0}".format(self.memdump))
205
206 self.__config()
207 results = []
208
209 command = self.plugins["idt"](self.config)
210 for n, entry, addr, module in command.calculate():
211 if module:
212 module_name = str(module.BaseDllName or "")
213 sect_name = command.get_section_name(module, addr)
214 else:
215 module_name = "UNKNOWN"
216 sect_name = ''
217
218
219 cpu_number = entry.obj_parent.obj_parent.ProcessorBlock.Number
220 new = {
221 "cpu_number": int(cpu_number),
222 "index": int(n),
223 "selector": hex(int(entry.Selector)),
224 "address": hex(int(addr)),
225 "module": module_name,
226 "section": sect_name,
227 }
228 results.append(new)
229
230 return dict(config={}, data=results)
231
233 """Volatility gdt plugin.
234 @see volatility/plugins/malware/idt.py
235 """
236 log.debug("Executing Volatility gdt plugin on "
237 "{0}".format(self.memdump))
238
239 self.__config()
240 results = []
241
242 command = self.plugins["gdt"](self.config)
243
244 for n, entry in command.calculate():
245 selector = n * 8
246
247
248 if entry.Present:
249 present = "P"
250 else:
251 present = "Np"
252
253
254
255 if entry.Type == "CallGate32":
256 base = entry.CallGate
257 limit = 0
258 granularity = "-"
259 else:
260 base = entry.Base
261 limit = entry.Limit
262 if entry.Granularity:
263 granularity = "Pg"
264 else:
265 granularity = "By"
266
267
268 cpu_number = entry.obj_parent.obj_parent.ProcessorBlock.Number
269
270 new = {
271 "cpu_number": int(cpu_number),
272 "selector": hex(selector),
273 "base": hex(int(base)),
274 "limit": hex(int(limit)),
275 "type": str(entry.Type),
276 "dpl": str(entry.Dpl),
277 "granularity": granularity,
278 "present": present,
279 }
280 results.append(new)
281
282 return dict(config={}, data=results)
283
285 """Volatility ssdt plugin.
286 @see volatility/plugins/malware/ssdt.py
287 """
288 log.debug("Executing Volatility ssdt plugin on "
289 "{0}".format(self.memdump))
290
291 self.__config()
292 results = []
293
294 command = self.plugins["ssdt"](self.config)
295
296
297 addr_space = self.addr_space
298 syscalls = addr_space.profile.syscalls
299 bits32 = addr_space.profile.metadata.get("memory_model", "32bit") == "32bit"
300
301 for idx, table, n, vm, mods, mod_addrs in command.calculate():
302 for i in range(n):
303 if bits32:
304
305 syscall_addr = obj.Object("address", table + (i * 4), vm).v()
306 else:
307
308
309 offset = obj.Object("long", table + (i * 4), vm).v()
310
311 syscall_addr = table + (offset >> 4)
312
313 try:
314 syscall_name = syscalls[idx][i]
315 except IndexError:
316 syscall_name = "UNKNOWN"
317
318 syscall_mod = tasks.find_module(mods, mod_addrs, addr_space.address_mask(syscall_addr))
319 if syscall_mod:
320 syscall_modname = "{0}".format(syscall_mod.BaseDllName)
321 else:
322 syscall_modname = "UNKNOWN"
323
324 new = {
325 "index": int(idx),
326 "table": hex(int(table)),
327 "entry": "{0:#06x}".format(idx * 0x1000 + i),
328 "syscall_name": syscall_name,
329 "syscall_addr": syscall_addr,
330 "syscall_modname": syscall_modname,
331 }
332
333 if bits32 and syscall_mod is not None:
334 ret = apihooks.ApiHooks.check_inline(
335 va=syscall_addr, addr_space=vm,
336 mem_start=syscall_mod.DllBase,
337 mem_end=syscall_mod.DllBase + syscall_mod.SizeOfImage)
338
339
340 if ret is not None:
341 hooked, data, dest_addr = ret
342 if hooked:
343
344
345
346 hook_mod = tasks.find_module(mods, mod_addrs,
347 dest_addr)
348 if hook_mod:
349 hook_name = "{0}".format(hook_mod.BaseDllName)
350 else:
351 hook_name = "UNKNOWN"
352
353
354 new.update({
355 "hook_dest_addr": "{0:#x}".format(dest_addr),
356 "hook_name": hook_name,
357 })
358
359 results.append(new)
360
361 return dict(config={}, data=results)
362
364 """Volatility timers plugin.
365 @see volatility/plugins/malware/timers.py
366 """
367 log.debug("Executing Volatility timers plugin on "
368 "{0}".format(self.memdump))
369
370 self.__config()
371 results = []
372
373 command = self.plugins["timers"](self.config)
374 for timer, module in command.calculate():
375 if timer.Header.SignalState.v():
376 signaled = "Yes"
377 else:
378 signaled = "-"
379
380 if module:
381 module_name = str(module.BaseDllName or "")
382 else:
383 module_name = "UNKNOWN"
384
385 due_time = "{0:#010x}:{1:#010x}".format(timer.DueTime.HighPart, timer.DueTime.LowPart)
386
387 new = {
388 "offset": hex(timer.obj_offset),
389 "due_time": due_time,
390 "period": int(timer.Period),
391 "signaled": signaled,
392 "routine": hex(int(timer.Dpc.DeferredRoutine)),
393 "module": module_name,
394 }
395 results.append(new)
396
397 return dict(config={}, data=results)
398
400 """Volatility messagehooks plugin.
401 @see volatility/plugins/malware/messagehooks.py
402 """
403 log.debug("Executing Volatility messagehooks plugin on "
404 "{0}".format(self.memdump))
405
406 self.__config()
407 results = []
408
409 command = self.plugins["messagehooks"](self.config)
410 for winsta, atom_tables in command.calculate():
411 for desk in winsta.desktops():
412 for name, hook in desk.hooks():
413 module = command.translate_hmod(winsta, atom_tables, hook.ihmod)
414 new = {
415 "offset": hex(int(hook.obj_offset)),
416 "session": int(winsta.dwSessionId),
417 "desktop": "{0}\\{1}".format(winsta.Name, desk.Name),
418 "thread": "<any>",
419 "filter": str(name),
420 "flags": str(hook.flags),
421 "function": hex(int(hook.offPfn)),
422 "module": str(module),
423 }
424 results.append(new)
425
426 for thrd in desk.threads():
427 info = "{0} ({1} {2})".format(
428 thrd.pEThread.Cid.UniqueThread,
429 thrd.ppi.Process.ImageFileName,
430 thrd.ppi.Process.UniqueProcessId)
431
432 for name, hook in thrd.hooks():
433 module = command.translate_hmod(winsta, atom_tables, hook.ihmod)
434
435 new = {
436 "offset": hex(int(hook.obj_offset)),
437 "session": int(winsta.dwSessionId),
438 "desktop": "{0}\\{1}".format(winsta.Name, desk.Name),
439 "thread": str(info),
440 "filter": str(name),
441 "flags": str(hook.flags),
442 "function": hex(int(hook.offPfn)),
443 "module": str(module),
444 }
445 results.append(new)
446
447 return dict(config={}, data=results)
448
450 """Volatility getsids plugin.
451 @see volatility/plugins/malware/getsids.py
452 """
453
454 log.debug("Executing Volatility getsids plugin on "
455 "{0}".format(self.memdump))
456
457 self.__config()
458 results = []
459
460 command = self.plugins["getsids"](self.config)
461 for task in command.calculate():
462 token = task.get_token()
463
464 if not token:
465 continue
466
467 for sid_string in token.get_sids():
468 if sid_string in sidm.well_known_sids:
469 sid_name = " {0}".format(sidm.well_known_sids[sid_string])
470 else:
471 sid_name_re = sidm.find_sid_re(sid_string, sidm.well_known_sid_re)
472 if sid_name_re:
473 sid_name = " {0}".format(sid_name_re)
474 else:
475 sid_name = ""
476
477 new = {
478 "filename": str(task.ImageFileName),
479 "process_id": int(task.UniqueProcessId),
480 "sid_string": str(sid_string),
481 "sid_name": str(sid_name),
482 }
483 results.append(new)
484
485 return dict(config={}, data=results)
486
488 """Volatility privs plugin.
489 @see volatility/plugins/malware/privs.py
490 """
491
492 log.debug("Executing Volatility privs plugin on "
493 "{0}".format(self.memdump))
494
495 self.__config()
496 results = []
497
498 command = self.plugins["privs"](self.config)
499
500 for task in command.calculate():
501 for value, present, enabled, default in task.get_token().privileges():
502 try:
503 name, desc = privm.PRIVILEGE_INFO[int(value)]
504 except KeyError:
505 continue
506
507 attributes = []
508 if present:
509 attributes.append("Present")
510 if enabled:
511 attributes.append("Enabled")
512 if default:
513 attributes.append("Default")
514
515 new = {
516 "process_id": int(task.UniqueProcessId),
517 "filename": str(task.ImageFileName),
518 "value": int(value),
519 "privilege": str(name),
520 "attributes": ",".join(attributes),
521 "description": str(desc),
522 }
523 results.append(new)
524
525 return dict(config={}, data=results)
526
528 """Volatility malfind plugin.
529 @param dump_dir: optional directory for dumps
530 @see volatility/plugins/malware/malfind.py
531 """
532 log.debug("Executing Volatility malfind plugin on "
533 "{0}".format(self.memdump))
534
535 self.__config()
536 results = []
537
538 command = self.plugins["malfind"](self.config)
539 for task in command.calculate():
540 for vad, address_space in task.get_vads(vad_filter=task._injection_filter):
541 if command._is_vad_empty(vad, address_space):
542 continue
543
544 new = {
545 "process_name": str(task.ImageFileName),
546 "process_id": int(task.UniqueProcessId),
547 "vad_start": "{0:#x}".format(vad.Start),
548 "vad_tag": str(vad.Tag),
549 }
550 results.append(new)
551
552 if dump_dir:
553 filename = os.path.join(dump_dir, "process.{0:#x}.{1:#x}.dmp".format(task.obj_offset, vad.Start))
554 command.dump_vad(filename, vad, address_space)
555
556 return dict(config={}, data=results)
557
559 """Volatility yarascan plugin.
560 @see volatility/plugins/malware/yarascan.py
561 """
562 log.debug("Executing Volatility yarascan plugin on "
563 "{0}".format(self.memdump))
564
565 self.__config()
566 results = []
567
568 ypath = os.path.join(CUCKOO_ROOT, "data", "yara", "index_memory.yar")
569 if not os.path.exists(ypath):
570 return dict(config={}, data=[])
571
572 self.config.update("YARA_FILE", ypath)
573
574 command = self.plugins["yarascan"](self.config)
575 for o, addr, hit, content in command.calculate():
576
577
578 if o is None:
579 owner = "Unknown Kernel Memory"
580 elif o.obj_name == "_EPROCESS":
581 owner = "Process {0} Pid {1}".format(o.ImageFileName, o.UniqueProcessId)
582 else:
583 owner = "{0}".format(o.BaseDllName)
584
585 hexdump = "".join(
586 "{0:#010x} {1:<48} {2}\n".format(addr + o, h, ''.join(c))
587 for o, h, c in utils.Hexdump(content[0:64]))
588
589 new = {
590 "rule": hit.rule,
591 "owner": owner,
592 "hexdump": hexdump,
593 }
594 results.append(new)
595
596 return dict(config={}, data=results)
597
599 """Volatility apihooks plugin.
600 @see volatility/plugins/malware/apihooks.py
601 """
602 log.debug("Executing Volatility apihooks plugin on {0}".format(self.memdump))
603
604 self.__config()
605 results = []
606
607 command = self.plugins["apihooks"](self.config)
608 for process, module, hook in command.calculate():
609 proc_name = str(process.ImageFileName) if process else ''
610 if command.whitelist(hook.hook_mode | hook.hook_type,
611 proc_name, hook.VictimModule,
612 hook.HookModule, hook.Function):
613 continue
614
615 new = {
616 "hook_mode": str(hook.Mode),
617 "hook_type": str(hook.Type),
618 "victim_module": str(module.BaseDllName or ""),
619 "victim_function": str(hook.Detail),
620 "hook_address": "{0:#x}".format(hook.hook_address),
621 "hooking_module": str(hook.HookModule)
622 }
623
624 if process:
625 new["process_id"] = int(process.UniqueProcessId)
626 new["process_name"] = str(process.ImageFileName)
627
628 results.append(new)
629
630 return dict(config={}, data=results)
631
633 """Volatility dlllist plugin.
634 @see volatility/plugins/taskmods.py
635 """
636 log.debug("Executing Volatility dlllist plugin on {0}".format(self.memdump))
637
638 self.__config()
639 results = []
640
641 command = self.plugins["dlllist"](self.config)
642 for task in command.calculate():
643 new = {
644 "process_id": int(task.UniqueProcessId),
645 "process_name": str(task.ImageFileName),
646 "commandline": str(task.Peb.ProcessParameters.CommandLine or ""),
647 "loaded_modules": []
648 }
649
650 for module in task.get_load_modules():
651 new["loaded_modules"].append({
652 "dll_base": str(module.DllBase),
653 "dll_size": str(module.SizeOfImage),
654 "dll_full_name": str(module.FullDllName or ""),
655 "dll_load_count": int(module.LoadCount),
656 })
657
658 results.append(new)
659
660 return dict(config={}, data=results)
661
663 """Volatility handles plugin.
664 @see volatility/plugins/handles.py
665 """
666 log.debug("Executing Volatility handles plugin on {0}".format(self.memdump))
667
668 self.__config()
669 results = []
670
671 command = self.plugins["handles"](self.config)
672 for pid, handle, object_type, name in command.calculate():
673 new = {
674 "process_id": int(pid),
675 "handle_value": str(handle.HandleValue),
676 "handle_granted_access": str(handle.GrantedAccess),
677 "handle_type": str(object_type),
678 "handle_name": str(name)
679 }
680
681 results.append(new)
682
683 return dict(config={}, data=results)
684
686 """Volatility ldrmodules plugin.
687 @see volatility/plugins/malware/malfind.py
688 """
689 log.debug("Executing Volatility ldrmodules plugin on {0}".format(self.memdump))
690
691 self.__config()
692 results = []
693
694 command = self.plugins["ldrmodules"](self.config)
695 for task in command.calculate():
696
697
698 inloadorder = dict((mod.DllBase.v(), mod) for mod in task.get_load_modules())
699 ininitorder = dict((mod.DllBase.v(), mod) for mod in task.get_init_modules())
700 inmemorder = dict((mod.DllBase.v(), mod) for mod in task.get_mem_modules())
701
702
703 mapped_files = {}
704 for vad, address_space in task.get_vads(vad_filter=task._mapped_file_filter):
705
706
707 if obj.Object("_IMAGE_DOS_HEADER", offset=vad.Start, vm=address_space).e_magic != 0x5A4D:
708 continue
709
710 mapped_files[int(vad.Start)] = str(vad.FileObject.FileName or "")
711
712
713
714 for base in mapped_files.keys():
715
716 load_mod = inloadorder.get(base, None)
717 init_mod = ininitorder.get(base, None)
718 mem_mod = inmemorder.get(base, None)
719
720 new = {
721 "process_id": int(task.UniqueProcessId),
722 "process_name": str(task.ImageFileName),
723 "dll_base": "{0:#x}".format(base),
724 "dll_in_load": load_mod is not None,
725 "dll_in_init": init_mod is not None,
726 "dll_in_mem": mem_mod is not None,
727 "dll_mapped_path": str(mapped_files[base]),
728 "load_full_dll_name": "",
729 "init_full_dll_name": "",
730 "mem_full_dll_name": ""
731 }
732
733 if load_mod:
734 new["load_full_dll_name"] = str(load_mod.FullDllName)
735
736 if init_mod:
737 new["init_full_dll_name"] = str(init_mod.FullDllName)
738
739 if mem_mod:
740 new["mem_full_dll_name"] = str(mem_mod.FullDllName)
741
742 results.append(new)
743
744 return dict(config={}, data=results)
745
747 """Volatility mutantscan plugin.
748 @see volatility/plugins/filescan.py
749 """
750 log.debug("Executing Volatility mutantscan module on {0}".format(self.memdump))
751
752 self.__config()
753 results = []
754
755 command = self.plugins["mutantscan"](self.config)
756 for mutant in command.calculate():
757 header = mutant.get_object_header()
758 tid = 0
759 pid = 0
760 if mutant.OwnerThread > 0x80000000:
761 thread = mutant.OwnerThread.dereference_as("_ETHREAD")
762 tid = thread.Cid.UniqueThread
763 pid = thread.Cid.UniqueProcess
764
765 new = {
766 "mutant_offset": "{0:#x}".format(mutant.obj_offset),
767 "num_pointer": int(header.PointerCount),
768 "num_handles": int(header.HandleCount),
769 "mutant_signal_state": str(mutant.Header.SignalState),
770 "mutant_name": str(header.NameInfo.Name or ""),
771 "process_id": int(pid),
772 "thread_id": int(tid)
773 }
774
775 results.append(new)
776
777 return dict(config={}, data=results)
778
780 """Volatility devicetree plugin.
781 @see volatility/plugins/malware/devicetree.py
782 """
783 log.debug("Executing Volatility devicetree module on {0}".format(self.memdump))
784
785 self.__config()
786 results = []
787
788 command = self.plugins["devicetree"](self.config)
789 for driver_obj in command.calculate():
790 new = {
791 "driver_offset": "0x{0:08x}".format(driver_obj.obj_offset),
792 "driver_name": str(driver_obj.DriverName or ""),
793 "devices": []
794 }
795
796 for device in driver_obj.devices():
797 device_header = obj.Object(
798 "_OBJECT_HEADER",
799 offset=device.obj_offset - device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"),
800 vm=device.obj_vm,
801 native_vm=device.obj_native_vm
802 )
803
804 device_name = str(device_header.NameInfo.Name or "")
805
806 new_device = {
807 "device_offset": "0x{0:08x}".format(device.obj_offset),
808 "device_name": device_name,
809 "device_type": devicetree.DEVICE_CODES.get(device.DeviceType.v(), "UNKNOWN"),
810 "devices_attached": []
811 }
812
813 new["devices"].append(new_device)
814
815 level = 0
816
817 for att_device in device.attached_devices():
818 device_header = obj.Object(
819 "_OBJECT_HEADER",
820 offset=att_device.obj_offset - att_device.obj_vm.profile.get_obj_offset("_OBJECT_HEADER", "Body"),
821 vm=att_device.obj_vm,
822 native_vm=att_device.obj_native_vm
823 )
824
825 device_name = str(device_header.NameInfo.Name or "")
826 name = (device_name + " - " + str(att_device.DriverObject.DriverName or ""))
827
828 new_device["devices_attached"].append({
829 "level": level,
830 "attached_device_offset": "0x{0:08x}".format(att_device.obj_offset),
831 "attached_device_name": name,
832 "attached_device_type": devicetree.DEVICE_CODES.get(att_device.DeviceType.v(), "UNKNOWN")
833 })
834
835 level += 1
836
837 results.append(new)
838
839 return dict(config={}, data=results)
840
842 """Volatility svcscan plugin - scans for services.
843 @see volatility/plugins/malware/svcscan.py
844 """
845 log.debug("Executing Volatility svcscan plugin on {0}".format(self.memdump))
846
847 self.__config()
848 results = []
849
850 command = self.plugins["svcscan"](self.config)
851 for rec in command.calculate():
852 new = {
853 "service_offset": "{0:#x}".format(rec.obj_offset),
854 "service_order": int(rec.Order),
855 "process_id": int(rec.Pid),
856 "service_name": str(rec.ServiceName.dereference()),
857 "service_display_name": str(rec.DisplayName.dereference()),
858 "service_type": str(rec.Type),
859 "service_binary_path": str(rec.Binary),
860 "service_state": str(rec.State)
861 }
862
863 results.append(new)
864
865 return dict(config={}, data=results)
866
868 """Volatility modscan plugin.
869 @see volatility/plugins/modscan.py
870 """
871 log.debug("Executing Volatility modscan plugin on {0}".format(self.memdump))
872
873 self.__config()
874 results = []
875
876 command = self.plugins["modscan"](self.config)
877 for ldr_entry in command.calculate():
878 new = {
879 "kernel_module_offset": "{0:#x}".format(ldr_entry.obj_offset),
880 "kernel_module_name": str(ldr_entry.BaseDllName or ""),
881 "kernel_module_file": str(ldr_entry.FullDllName or ""),
882 "kernel_module_base": "{0:#x}".format(ldr_entry.DllBase),
883 "kernel_module_size": int(ldr_entry.SizeOfImage),
884 }
885
886 results.append(new)
887
888 return dict(config={}, data=results)
889
891 """Volatility imageinfo plugin.
892 @see volatility/plugins/imageinfo.py
893 """
894 log.debug("Executing Volatility imageinfo plugin on {0}".format(self.memdump))
895
896 self.__config()
897 results = []
898
899 command = self.plugins["imageinfo"](self.config)
900 new = {}
901 for key, value in command.calculate():
902 new[key] = value
903
904 osp = new["Suggested Profile(s)"].split(",")[0]
905 new["osprofile"] = osp
906
907 results.append(new)
908
909 return dict(config={}, data=results)
910
912 """Handle several volatility results."""
913
914 - def __init__(self, memfile, osprofile=None):
915 self.mask_pid = []
916 self.taint_pid = set()
917 self.memfile = memfile
918
919 conf_path = os.path.join(CUCKOO_ROOT, "conf", "memory.conf")
920 if not os.path.exists(conf_path):
921 log.error("Configuration file volatility.conf not found".format(conf_path))
922 self.voptions = False
923 return
924
925 self.voptions = Config("memory")
926
927 for pid in self.voptions.mask.pid_generic.split(","):
928 pid = pid.strip()
929 if pid:
930 self.mask_pid.append(int(pid))
931
932 self.no_filter = not self.voptions.mask.enabled
933 if self.voptions.basic.guest_profile:
934 self.osprofile = self.voptions.basic.guest_profile
935 else:
936 self.osprofile = osprofile or self.get_osprofile()
937
941
997
999 """Filter out masked stuff. Keep tainted stuff."""
1000 new = {}
1001
1002 for akey in old.keys():
1003 new[akey] = {"config": old[akey]["config"], "data": []}
1004 conf = getattr(self.voptions, akey, None)
1005 new[akey]["config"]["filter"] = conf.filter
1006 for item in old[akey]["data"]:
1007
1008 if not conf.filter:
1009 new[akey]["data"].append(item)
1010 elif "process_id" in item and \
1011 item["process_id"] in self.mask_pid and \
1012 item["process_id"] not in self.taint_pid:
1013 pass
1014 else:
1015 new[akey]["data"].append(item)
1016 return new
1017
1019 """Find tainted items."""
1020 if "malfind" in res:
1021 for item in res["malfind"]["data"]:
1022 self.taint_pid.add(item["process_id"])
1023
1025 """Delete the memory dump (if configured to do so)."""
1026
1027 if self.voptions.basic.delete_memdump:
1028 try:
1029 os.remove(self.memfile)
1030 except OSError:
1031 log.error("Unable to delete memory dump file at path \"%s\" ", self.memfile)
1032
1034 """Volatility Analyzer."""
1035
1037 """Run analysis.
1038 @return: volatility results dict.
1039 """
1040 self.key = "memory"
1041
1042 results = {}
1043 if HAVE_VOLATILITY:
1044 if self.memory_path and os.path.exists(self.memory_path):
1045 try:
1046 vol = VolatilityManager(self.memory_path)
1047 results = vol.run()
1048 except Exception:
1049 log.exception("Generic error executing volatility")
1050 else:
1051 log.error("Memory dump not found: to run volatility you have to enable memory_dump")
1052 else:
1053 log.error("Cannot run volatility module: volatility library not available")
1054
1055 return results
1056