Commit cf2de849a35617c97b5861c2afec90026b24c585
1 parent
6320acf4
Added logging. Added better error handling and displaying. Implemented evt module
Showing
14 changed files
with
248 additions
and
55 deletions
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
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
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 = [] |