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 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 9 import locale
4 10 from dialog import Dialog
5 11 import glob
6 12 import os
7   -import sys
8 13 import subprocess as sp
9 14 import tomb
10 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 20 def getModules():
16 21 choiceList = []
... ... @@ -37,52 +42,80 @@ def prepareModule(moduleName):
37 42 module.getVars()
38 43 return module
39 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 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 86 if "all" in tags:
58 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 97 else:
61 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 109 sp.call('clear', shell=True)
65   -
66 110 for module in runlist:
67   - print("Running " + module.name + "...")
  111 + logger.msgLog("Running " + module.name + "...", "digger", logger.TYPE_INFO)
68 112 try:
69 113 module.run()
70 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 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 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 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 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 1 import os
5 2  
  3 +import tomb
  4 +from modules.module import Module
  5 +from runcmd import runProcess
  6 +
  7 +
6 8 def getInstance():
7 9 return INFOModule()
8 10  
... ...
modules/mft.py
1   -from module import Module
2   -from runcmd import runProcess
3   -import tomb
4 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 9 def getInstance():
7 10 return MFTModule()
8 11  
... ... @@ -18,6 +21,7 @@ class MFTModule(Module):
18 21 path = tomb.getPath() + self.name + "/"
19 22 if(not os.path.exists(path)):
20 23 os.mkdir(path)
  24 + logger.msgLog("Extracting MFT from volumes: " + repr(self.vars['ntfsvol'].value), "mft", logger.TYPE_INFO)
21 25 for vol in self.vars['ntfsvol'].value:
22 26 result,code = runProcess(["icat","/dev/" + vol,"0"])
23 27 mftbin = open(path + vol + ".bin",'wb')
... ...
module.py renamed to modules/module.py
... ... @@ -16,4 +16,7 @@ class Module(object):
16 16 for var in self.requiredVars:
17 17 modvar = __import__(var).getInstance(self.name)
18 18 modvar.query()
19   - self.vars[modvar.name] = modvar
20 19 \ No newline at end of file
  20 + self.vars[modvar.name] = modvar
  21 +
  22 + def __str__(self):
  23 + return self.name
21 24 \ No newline at end of file
... ...
modules/winreg.py
1   -from module import Module
2   -import tomb
3 1 import os
  2 +
  3 +import logger
  4 +import tomb
4 5 import winver
5   -from runcmd import runProcess
  6 +from modules.module import Module
6 7 from mount import mount,umount
  8 +from runcmd import runProcess
  9 +
7 10  
8 11 def getInstance():
9 12 return RegistryModule()
... ... @@ -20,9 +23,13 @@ class RegistryModule(Module):
20 23 path = tomb.getPath() + self.name + "/"
21 24 if(not os.path.exists(path)):
22 25 os.mkdir(path)
  26 + logger.msgLog("Extracting Windows registry from volumes: " + repr(self.vars['winvol'].value), "winreg", logger.TYPE_INFO)
23 27 for vol in self.vars['winvol'].value:
24 28 mntpoint = "/mnt/"
25   - mntid = mount("/dev/" + vol)
  29 + try:
  30 + mntid = mount("/dev/" + vol)
  31 + except:
  32 + raise
26 33 mntpoint += mntid
27 34 files = []
28 35 windir = winver.getWindowsDirectory(mntpoint)
... ... @@ -58,4 +65,7 @@ class RegistryModule(Module):
58 65 files += [profile + "/AppData/Local/Microsoft/Windows/UsrClass.dat"]
59 66  
60 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 13  
14 14 @abstractmethod
15 15 def query(self):
16   - pass
17 16 \ No newline at end of file
  17 + pass
  18 +
  19 + def __str__(self):
  20 + return self.name
18 21 \ No newline at end of file
... ...
vars/ntfsvol.py
1   -from modulevar import Modulevar
2 1 from dialog import Dialog
  2 +
3 3 from runcmd import runProcess
  4 +from vars.modulevar import Modulevar
  5 +
4 6  
5 7 def getInstance(modname):
6 8 return NTFSVol(modname)
... ... @@ -27,7 +29,7 @@ class NTFSVol(Modulevar):
27 29 d.set_background_title("[" + self.parentModule + "] Setting variable: ntfsvol")
28 30 volumes = self.getNTFSVolumes()
29 31 if(len(volumes) == 0):
30   - raise Exception("[" + self.name + "] No Windows Volumes found")
  32 + raise Exception("[" + self.name + "] No NTFS Volumes found")
31 33 volumeList = []
32 34 for vol in volumes:
33 35 volumeList.append((vol[0],vol[1], False))
... ...
vars/winvol.py
1   -from modulevar import Modulevar
2 1 from dialog import Dialog
3   -from runcmd import runProcess
  2 +
  3 +import logger
4 4 import winver
5 5 from mount import mount,umount
  6 +from runcmd import runProcess
  7 +from vars.modulevar import Modulevar
  8 +
6 9  
7 10 def getInstance(modname):
8 11 return WinVol(modname)
... ... @@ -49,6 +52,7 @@ class WinVol(Modulevar):
49 52 d = Dialog(dialog="dialog", autowidgetsize=True)
50 53 d.set_background_title("[" + self.parentModule + "] Setting variable: winvol")
51 54 volumes = self.getWindowsVolumes()
  55 + logger.msgLog("Detected Windows volumes in " + repr(volumes),"winvol",logger.TYPE_INFO)
52 56 if(len(volumes) == 0):
53 57 raise Exception("[" + self.name + "] No Windows Volumes found")
54 58 volumeList = []
... ...