Commit cf2de849a35617c97b5861c2afec90026b24c585

Authored by Imanol-Mikel Barba Sabariego
1 parent 6320acf4

Added logging. Added better error handling and displaying. Implemented evt module

digger.py
1 #! /usr/bin/env python3 1 #! /usr/bin/env python3
2 2
  3 +import sys
  4 +
  5 +sys.path.append('modules')
  6 +sys.path.append('vars')
  7 +sys.path.append('logger')
  8 +
3 import locale 9 import locale
4 from dialog import Dialog 10 from dialog import Dialog
5 import glob 11 import glob
6 import os 12 import os
7 -import sys  
8 import subprocess as sp 13 import subprocess as sp
9 import tomb 14 import tomb
10 import traceback 15 import traceback
11 -  
12 -sys.path.append('modules')  
13 -sys.path.append('vars') 16 +import logger
  17 +from consolelogger import ConsoleLogger
  18 +from filelogger import FileLogger
14 19
15 def getModules(): 20 def getModules():
16 choiceList = [] 21 choiceList = []
@@ -37,52 +42,80 @@ def prepareModule(moduleName): @@ -37,52 +42,80 @@ def prepareModule(moduleName):
37 module.getVars() 42 module.getVars()
38 return module 43 return module
39 except Exception as e: 44 except Exception as e:
40 - raise Exception("[" + moduleName + "] " + str(e))  
41 -  
42 -locale.setlocale(locale.LC_ALL, '')  
43 -d = Dialog(dialog="dialog",autowidgetsize=True)  
44 -d.set_background_title("Gravedigger")  
45 -  
46 -moduleList = getModules()  
47 -code,value = d.inputbox("Input computer's name")  
48 -if code == d.OK:  
49 - tomb._MACHINE_NAME= value  
50 - d.set_background_title("Gravedigger - " + value)  
51 - code, tags = d.checklist("Select modules to execute",  
52 - choices=moduleList + [("all","Execute all modules",False)],  
53 - title="Module selection") 45 + raise
  46 +
  47 +def showFinishDialog(allSuccessful):
  48 + msg = ""
  49 + if(allSuccessful):
  50 + msg = "All modules finished execution"
  51 + else:
  52 + msg = "Some or all modules failed execution. Please check the logs."
  53 +
  54 + code, tag = d.menu(msg, choices=[("Poweroff", "Shutdown the computer"),
  55 + ("Reboot", "Reboot the computer"),
  56 + ("Restart", "Run Gravedigger again")])
  57 + if (code == d.OK):
  58 + if tag == "Poweroff":
  59 + sp.call("poweroff", shell=True)
  60 + elif tag == "Reboot":
  61 + sp.call("reboot", shell=True)
  62 +
  63 + exit(0)
  64 +
  65 +def showContinueDialog(d,msg):
  66 + ans = d.yesno(msg + "\n\nDo you want to continue execution without the module?")
  67 + return ans == d.OK
  68 +
  69 +if __name__ == "__main__":
  70 + locale.setlocale(locale.LC_ALL, '')
  71 + d = Dialog(dialog="dialog",autowidgetsize=True)
  72 + d.set_background_title("Gravedigger")
  73 +
  74 + moduleList = getModules()
  75 + code,value = d.inputbox("Input computer's name")
54 if code == d.OK: 76 if code == d.OK:
55 - runlist = []  
56 - try: 77 + tomb._MACHINE_NAME= value
  78 + logger.logSystems.append(ConsoleLogger())
  79 + logger.logSystems.append(FileLogger(tomb.getPath() + "log.txt"))
  80 + d.set_background_title("Gravedigger - " + value)
  81 + code, tags = d.checklist("Select modules to execute",
  82 + choices=moduleList + [("all","Execute all modules",False)],
  83 + title="Module selection")
  84 + if code == d.OK:
  85 + runlist = []
57 if "all" in tags: 86 if "all" in tags:
58 for module in moduleList: 87 for module in moduleList:
59 - runlist.append(prepareModule(module[0])) 88 + try:
  89 + mod = prepareModule(module[0])
  90 + runlist.append(mod)
  91 + except Exception as e:
  92 + msg = "Exception raised while preparing module \"" + module[0] + "\": " + str(e)
  93 + logger.msgLog(msg, module[0], logger.TYPE_ERROR)
  94 + #logger.msgLog(traceback.format_exc(), module[0], logger.TYPE_ERROR)
  95 + if(not showContinueDialog(d,msg)):
  96 + showFinishDialog(False)
60 else: 97 else:
61 for tag in tags: 98 for tag in tags:
62 - runlist.append(prepareModule(tag)) 99 + try:
  100 + mod = prepareModule(tag)
  101 + runlist.append(mod)
  102 + except Exception as e:
  103 + msg = "Exception raised while preparing module \"" + tag + "\": " + str(e)
  104 + logger.msgLog(msg,tag,logger.TYPE_ERROR)
  105 + #logger.msgLog(traceback.format_exc(), tag logger.TYPE_ERROR)
  106 + if(not showContinueDialog(d,msg)):
  107 + showFinishDialog(False)
63 108
64 sp.call('clear', shell=True) 109 sp.call('clear', shell=True)
65 -  
66 for module in runlist: 110 for module in runlist:
67 - print("Running " + module.name + "...") 111 + logger.msgLog("Running " + module.name + "...", "digger", logger.TYPE_INFO)
68 try: 112 try:
69 module.run() 113 module.run()
70 except Exception as e: 114 except Exception as e:
71 - print("Exception raised while running " + module.name + ": " + str(e))  
72 - traceback.print_exc() 115 + logger.msgLog("Exception raised while running \"" + module.name + "\": " + str(e), module.name, logger.TYPE_ERROR)
  116 + #logger.msgLog(traceback.format_exc(), module.name, logger.TYPE_ERROR)
73 117
74 - code, tag = d.menu("All modules finished execution",choices=[("Poweroff","Shutdown the computer"),  
75 - ("Reboot","Reboot the computer"),  
76 - ("Restart","Run Gravedigger again")])  
77 - if(code == d.OK):  
78 - if tag == "Poweroff":  
79 - sp.call("poweroff",shell=True)  
80 - elif tag == "Reboot":  
81 - sp.call("reboot", shell=True)  
82 118
83 -  
84 - except Exception as e:  
85 - print("Exception raised while preparing module: " + str(e))  
86 - traceback.print_exc() 119 + showFinishDialog(True)
87 120
88 121
logger/consolelogger.py 0 → 100644
  1 +import datetime
  2 +from logsystem import LogSystem
  3 +
  4 +BASH_YLW_TEXT = '\033[33m'
  5 +BASH_RED_TEXT = '\033[31m'
  6 +BASH_RESET_TEXT = '\033[0m'
  7 +
  8 +class ConsoleLogger(LogSystem):
  9 +
  10 + def writeLog(self,message,module,type = None):
  11 + if(type == None):
  12 + type = self.TYPE_INFO
  13 + time = str(datetime.datetime.now())
  14 +
  15 + if(type == self.TYPE_ERROR):
  16 + print(time + " [" + module + "] " + BASH_RED_TEXT + "ERROR: " + message + BASH_RESET_TEXT)
  17 +
  18 + elif(type == self.TYPE_WARNING):
  19 + print(time + " [" + module + "] " + BASH_YLW_TEXT + "WARNING: " + message + BASH_RESET_TEXT)
  20 +
  21 + elif(type == self.TYPE_INFO):
  22 + print(time + " [" + module + "] " + "INFO: " + message)
  23 +
  24 + else:
  25 + print(message)
0 \ No newline at end of file 26 \ No newline at end of file
logger/filelogger.py 0 → 100644
  1 +import datetime
  2 +from logsystem import LogSystem
  3 +
  4 +class FileLogger(LogSystem):
  5 +
  6 + def __init__(self,filename):
  7 + self.file = filename
  8 + f = open(filename,"w+")
  9 + f.close()
  10 +
  11 + def writeLog(self,message,module,type = None):
  12 + if(type == None):
  13 + type = self.TYPE_INFO
  14 + time = str(datetime.datetime.now())
  15 +
  16 + if(type == self.TYPE_ERROR):
  17 + f = open(self.file,"a+")
  18 + f.write(time + " [" + module + "] " + "ERROR: " + message + "\n")
  19 + f.close()
  20 +
  21 + elif(type == self.TYPE_WARNING):
  22 + f = open(self.file,"a+")
  23 + f.write(time + " [" + module + "] " + "WARNING: " + message + "\n")
  24 + f.close()
  25 +
  26 + elif(type == self.TYPE_INFO):
  27 + f = open(self.file,"a+")
  28 + f.write(time + " [" + module + "] " + "INFO: " + message + "\n")
  29 + f.close()
  30 +
  31 + else:
  32 + f = open(self.file,"a+")
  33 + f.write(message + "\n")
  34 + f.close()
0 \ No newline at end of file 35 \ No newline at end of file
logger/logger.py 0 → 100644
  1 +logSystems = []
  2 +TYPE_INFO = 0
  3 +TYPE_WARNING = 1
  4 +TYPE_ERROR = 2
  5 +
  6 +def msgLog(message,module,type=None):
  7 + for system in logSystems:
  8 + system.writeLog(message,module,type)
0 \ No newline at end of file 9 \ No newline at end of file
logger/logsystem.py 0 → 100644
  1 +from abc import ABCMeta, abstractmethod
  2 +
  3 +class LogSystem(object):
  4 + __metaclass__ = ABCMeta
  5 +
  6 + TYPE_INFO = 0
  7 + TYPE_WARNING = 1
  8 + TYPE_ERROR = 2
  9 +
  10 + @abstractmethod
  11 + def writeLog(self,message,module,type):
  12 + pass
0 \ No newline at end of file 13 \ No newline at end of file
modules/evt.py 0 → 100644
  1 +import os
  2 +
  3 +import logger
  4 +import tomb
  5 +import winver
  6 +from modules.module import Module
  7 +from mount import mount,umount
  8 +from runcmd import runProcess
  9 +
  10 +
  11 +def getInstance():
  12 + return RegistryModule()
  13 +
  14 +class RegistryModule(Module):
  15 +
  16 + def __init__(self):
  17 + self.name = "evt"
  18 + self.description = "Extracts Windows Event Viewer files"
  19 + self.requiredVars = ["winvol"]
  20 + self.vars = {}
  21 +
  22 + def run(self):
  23 + path = tomb.getPath() + self.name + "/"
  24 + if(not os.path.exists(path)):
  25 + os.mkdir(path)
  26 + logger.msgLog("Extracting Windows Event Logs from volumes: " + repr(self.vars['winvol'].value), "winreg", logger.TYPE_INFO)
  27 + for vol in self.vars['winvol'].value:
  28 + mntpoint = "/mnt/"
  29 + try:
  30 + mntid = mount("/dev/" + vol)
  31 + except:
  32 + raise
  33 + mntpoint += mntid
  34 + files = []
  35 + windir = winver.getWindowsDirectory(mntpoint)
  36 + if windir == None:
  37 + raise Exception("No Windows installation present")
  38 + version = winver.getWindowsVersion(mntpoint)
  39 +
  40 + if version < winver._WIN_2k:
  41 + raise Exception("No EVT files in Windows versions prior to Windows 2000")
  42 + elif version < winver._WIN_VISTA:
  43 + files += [windir + "/System32/config/*.evt"]
  44 + files += [windir + "/System32/config/*.Evt"]
  45 + files += [windir + "/System32/config/*.EVT"]
  46 + else:
  47 + files += [windir + "/System32/winevt/Logs" ]
  48 +
  49 + runProcess(["tar","-czvf",path + "evt_" + vol + ".tar.gz"] + files)
  50 + try:
  51 + umount(mntid)
  52 + except:
  53 + raise
modules/info.py
1 -from module import Module  
2 -from runcmd import runProcess  
3 -import tomb  
4 import os 1 import os
5 2
  3 +import tomb
  4 +from modules.module import Module
  5 +from runcmd import runProcess
  6 +
  7 +
6 def getInstance(): 8 def getInstance():
7 return INFOModule() 9 return INFOModule()
8 10
modules/mft.py
1 -from module import Module  
2 -from runcmd import runProcess  
3 -import tomb  
4 import os 1 import os
5 2
  3 +import logger
  4 +import tomb
  5 +from modules.module import Module
  6 +from runcmd import runProcess
  7 +
  8 +
6 def getInstance(): 9 def getInstance():
7 return MFTModule() 10 return MFTModule()
8 11
@@ -18,6 +21,7 @@ class MFTModule(Module): @@ -18,6 +21,7 @@ class MFTModule(Module):
18 path = tomb.getPath() + self.name + "/" 21 path = tomb.getPath() + self.name + "/"
19 if(not os.path.exists(path)): 22 if(not os.path.exists(path)):
20 os.mkdir(path) 23 os.mkdir(path)
  24 + logger.msgLog("Extracting MFT from volumes: " + repr(self.vars['ntfsvol'].value), "mft", logger.TYPE_INFO)
21 for vol in self.vars['ntfsvol'].value: 25 for vol in self.vars['ntfsvol'].value:
22 result,code = runProcess(["icat","/dev/" + vol,"0"]) 26 result,code = runProcess(["icat","/dev/" + vol,"0"])
23 mftbin = open(path + vol + ".bin",'wb') 27 mftbin = open(path + vol + ".bin",'wb')
module.py renamed to modules/module.py
@@ -16,4 +16,7 @@ class Module(object): @@ -16,4 +16,7 @@ class Module(object):
16 for var in self.requiredVars: 16 for var in self.requiredVars:
17 modvar = __import__(var).getInstance(self.name) 17 modvar = __import__(var).getInstance(self.name)
18 modvar.query() 18 modvar.query()
19 - self.vars[modvar.name] = modvar  
20 \ No newline at end of file 19 \ No newline at end of file
  20 + self.vars[modvar.name] = modvar
  21 +
  22 + def __str__(self):
  23 + return self.name
21 \ No newline at end of file 24 \ No newline at end of file
modules/winreg.py
1 -from module import Module  
2 -import tomb  
3 import os 1 import os
  2 +
  3 +import logger
  4 +import tomb
4 import winver 5 import winver
5 -from runcmd import runProcess 6 +from modules.module import Module
6 from mount import mount,umount 7 from mount import mount,umount
  8 +from runcmd import runProcess
  9 +
7 10
8 def getInstance(): 11 def getInstance():
9 return RegistryModule() 12 return RegistryModule()
@@ -20,9 +23,13 @@ class RegistryModule(Module): @@ -20,9 +23,13 @@ class RegistryModule(Module):
20 path = tomb.getPath() + self.name + "/" 23 path = tomb.getPath() + self.name + "/"
21 if(not os.path.exists(path)): 24 if(not os.path.exists(path)):
22 os.mkdir(path) 25 os.mkdir(path)
  26 + logger.msgLog("Extracting Windows registry from volumes: " + repr(self.vars['winvol'].value), "winreg", logger.TYPE_INFO)
23 for vol in self.vars['winvol'].value: 27 for vol in self.vars['winvol'].value:
24 mntpoint = "/mnt/" 28 mntpoint = "/mnt/"
25 - mntid = mount("/dev/" + vol) 29 + try:
  30 + mntid = mount("/dev/" + vol)
  31 + except:
  32 + raise
26 mntpoint += mntid 33 mntpoint += mntid
27 files = [] 34 files = []
28 windir = winver.getWindowsDirectory(mntpoint) 35 windir = winver.getWindowsDirectory(mntpoint)
@@ -58,4 +65,7 @@ class RegistryModule(Module): @@ -58,4 +65,7 @@ class RegistryModule(Module):
58 files += [profile + "/AppData/Local/Microsoft/Windows/UsrClass.dat"] 65 files += [profile + "/AppData/Local/Microsoft/Windows/UsrClass.dat"]
59 66
60 runProcess(["tar","-czvf",path + "winreg_" + vol + ".tar.gz"] + files) 67 runProcess(["tar","-czvf",path + "winreg_" + vol + ".tar.gz"] + files)
61 - umount(mntid) 68 + try:
  69 + umount(mntid)
  70 + except:
  71 + raise
vars/__init__.py 0 → 100644
modulevar.py renamed to vars/modulevar.py
@@ -13,4 +13,7 @@ class Modulevar(object): @@ -13,4 +13,7 @@ class Modulevar(object):
13 13
14 @abstractmethod 14 @abstractmethod
15 def query(self): 15 def query(self):
16 - pass  
17 \ No newline at end of file 16 \ No newline at end of file
  17 + pass
  18 +
  19 + def __str__(self):
  20 + return self.name
18 \ No newline at end of file 21 \ No newline at end of file
vars/ntfsvol.py
1 -from modulevar import Modulevar  
2 from dialog import Dialog 1 from dialog import Dialog
  2 +
3 from runcmd import runProcess 3 from runcmd import runProcess
  4 +from vars.modulevar import Modulevar
  5 +
4 6
5 def getInstance(modname): 7 def getInstance(modname):
6 return NTFSVol(modname) 8 return NTFSVol(modname)
@@ -27,7 +29,7 @@ class NTFSVol(Modulevar): @@ -27,7 +29,7 @@ class NTFSVol(Modulevar):
27 d.set_background_title("[" + self.parentModule + "] Setting variable: ntfsvol") 29 d.set_background_title("[" + self.parentModule + "] Setting variable: ntfsvol")
28 volumes = self.getNTFSVolumes() 30 volumes = self.getNTFSVolumes()
29 if(len(volumes) == 0): 31 if(len(volumes) == 0):
30 - raise Exception("[" + self.name + "] No Windows Volumes found") 32 + raise Exception("[" + self.name + "] No NTFS Volumes found")
31 volumeList = [] 33 volumeList = []
32 for vol in volumes: 34 for vol in volumes:
33 volumeList.append((vol[0],vol[1], False)) 35 volumeList.append((vol[0],vol[1], False))
vars/winvol.py
1 -from modulevar import Modulevar  
2 from dialog import Dialog 1 from dialog import Dialog
3 -from runcmd import runProcess 2 +
  3 +import logger
4 import winver 4 import winver
5 from mount import mount,umount 5 from mount import mount,umount
  6 +from runcmd import runProcess
  7 +from vars.modulevar import Modulevar
  8 +
6 9
7 def getInstance(modname): 10 def getInstance(modname):
8 return WinVol(modname) 11 return WinVol(modname)
@@ -49,6 +52,7 @@ class WinVol(Modulevar): @@ -49,6 +52,7 @@ class WinVol(Modulevar):
49 d = Dialog(dialog="dialog", autowidgetsize=True) 52 d = Dialog(dialog="dialog", autowidgetsize=True)
50 d.set_background_title("[" + self.parentModule + "] Setting variable: winvol") 53 d.set_background_title("[" + self.parentModule + "] Setting variable: winvol")
51 volumes = self.getWindowsVolumes() 54 volumes = self.getWindowsVolumes()
  55 + logger.msgLog("Detected Windows volumes in " + repr(volumes),"winvol",logger.TYPE_INFO)
52 if(len(volumes) == 0): 56 if(len(volumes) == 0):
53 raise Exception("[" + self.name + "] No Windows Volumes found") 57 raise Exception("[" + self.name + "] No Windows Volumes found")
54 volumeList = [] 58 volumeList = []