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 | 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
logger/logsystem.py
0 → 100644
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 | 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
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 = [] | ... | ... |