Commit 00dcf762f2e5a53b6a03f524ae77addd1689ea07
1 parent
956444dd
fixed windows path storing (per volume). Added globeimposter2 module. Added func…
…tionality for registry and file lookup.
Showing
5 changed files
with
143 additions
and
9 deletions
findfile.py
0 → 100644
1 | +import os | |
2 | +import fnmatch | |
3 | + | |
4 | +def find_pattern_all(pattern, path, casesensitive): | |
5 | + result = [] | |
6 | + for root, dirs, files in os.walk(path): | |
7 | + for name in files: | |
8 | + if sensitive: | |
9 | + if fnmatch.fnmatchcase(name,pattern): | |
10 | + result.append(os.path.join(root, name)) | |
11 | + else: | |
12 | + if fnmatch.fnmatch(name.lower(), pattern.lower()): | |
13 | + result.append(os.path.join(root, name)) | |
14 | + return result | |
15 | + | |
16 | +def find_pattern(pattern, path, casesensitive): | |
17 | + for root, dirs, files in os.walk(path): | |
18 | + for name in files: | |
19 | + if sensitive: | |
20 | + if fnmatch.fnmatchcase(name,pattern): | |
21 | + return os.path.join(root, name) | |
22 | + else: | |
23 | + if fnmatch.fnmatch(name.lower(), pattern.lower()): | |
24 | + return os.path.join(root, name) | |
25 | + return None | |
26 | + | |
27 | +def find_all(name, path): | |
28 | + result = [] | |
29 | + for root, dirs, files in os.walk(path): | |
30 | + if name in files: | |
31 | + result.append(os.path.join(root, name)) | |
32 | + return result | |
33 | + | |
34 | +def find(name, path): | |
35 | + for root, dirs, files in os.walk(path): | |
36 | + if name in files: | |
37 | + return os.path.join(root, name) | |
38 | + return None | ... | ... |
modules/edb.py
... | ... | @@ -43,7 +43,7 @@ class RegistryModule(Module): |
43 | 43 | else: |
44 | 44 | files += [mntpoint + "/ProgramData/Microsoft/Search/Data/Applications/Windows/Windows.edb"] |
45 | 45 | |
46 | - runProcess(["tar","-czvf",path + "evt_" + vol + "_" + str(int(time.time())) + ".tar.gz"] + files) | |
46 | + runProcess(["tar","-czvf",path + "edb_" + vol + "_" + str(int(time.time())) + ".tar.gz"] + files) | |
47 | 47 | try: |
48 | 48 | umount(mntid) |
49 | 49 | except: | ... | ... |
modules/globeimposter2.py
0 → 100644
1 | +import os | |
2 | + | |
3 | +import regquery | |
4 | +import logger | |
5 | +import tomb | |
6 | +import winver | |
7 | +from modules.module import Module | |
8 | +from mount import mount,umount | |
9 | +from runcmd import runProcess | |
10 | +import time | |
11 | +import findfile | |
12 | + | |
13 | +def getInstance(): | |
14 | + return RegistryModule() | |
15 | + | |
16 | +class RegistryModule(Module): | |
17 | + | |
18 | + def __init__(self): | |
19 | + self.name = "globeimposter2" | |
20 | + self.description = "Detects a Globeimposter 2.0 infection" | |
21 | + self.requiredVars = ["ntfsvol","winvol"] | |
22 | + self.vars = {} | |
23 | + | |
24 | + def execute(self): | |
25 | + path = tomb.getPath() + self.name + "/" | |
26 | + if(not os.path.exists(path)): | |
27 | + os.mkdir(path) | |
28 | + logger.msgLog("Scanning volumes " + repr(self.vars['winvol'].value) + " " + repr(self.vars['ntfsvol'].value) + " for Globeimposter 2.0 infection","globeimposter2", logger.TYPE_INFO) | |
29 | + for vol in self.vars['winvol'].value: | |
30 | + mntpoint = "/mnt/" | |
31 | + try: | |
32 | + mntid = mount("/dev/" + vol) | |
33 | + except: | |
34 | + raise | |
35 | + mntpoint += mntid | |
36 | + profiles = winver.getUserProfiles(mntpoint) | |
37 | + for profile in profiles: | |
38 | + hkcu = profile + "/NTUSER.DAT" | |
39 | + value = regquery.queryValue(hkcu,"""Software\Microsoft\Windows\CurrentVersion\RunOnce""","CertificatesCheck") | |
40 | + if(value != None): | |
41 | + logger.msgLog("FOUND Globeimposter 2.0 value in RunOnce: " + value,"globeimposter2",logger.TYPE_WARNING) | |
42 | + #VSS | |
43 | + | |
44 | + for vol in self.vars['ntfsvol'].value: | |
45 | + mntpoint = "/mnt/" | |
46 | + try: | |
47 | + mntid = mount("/dev/" + vol) | |
48 | + except: | |
49 | + raise | |
50 | + mntpoint += mntid | |
51 | + result = find_pattern("*.725",mntpoint,False) | |
52 | + if(result != None): | |
53 | + logger.msgLog("FOUND at least one file with 725 extension: " + result,"globeimposter2",logger.TYPE_WARNING) | |
54 | + result = find("RECOVER-FILES.html",mntpoint) | |
55 | + if(result != None): | |
56 | + logger.msgLog("FOUND ransom letter: " + result,"globeimposter2",logger.TYPE_WARNING) | ... | ... |
regquery.py
0 → 100644
1 | +from Registry import Registry | |
2 | + | |
3 | +def queryValue(hive,keyPath,valueName): | |
4 | + reg = Registry.Registry(hive) | |
5 | + key = reg.open(keyPath) | |
6 | + try: | |
7 | + value = str(key.value(valueName).value) | |
8 | + except Registry.RegistryValueNotFoundException: | |
9 | + value = None | |
10 | + return value | |
11 | + | |
12 | +def getValues(hive,key): | |
13 | + valueList = [] | |
14 | + reg = Registry.Registry(hive) | |
15 | + key = reg.open(keyPath) | |
16 | + for value in key.values(): | |
17 | + valueList.append(value.value_name) | |
18 | + return valueList | |
19 | + | |
20 | +def getSubkeys(hive,key): | |
21 | + subkeyList = [] | |
22 | + reg = Registry.Registry(hive) | |
23 | + key = reg.open(keyPath) | |
24 | + for subkey in key.subkeys(): | |
25 | + subkeyList.append(subkey.name) | |
26 | + return subkeyList | |
27 | + | |
28 | +def keyExists(hive,key): | |
29 | + reg = Registry.Registry(hive) | |
30 | + try: | |
31 | + key = reg.open(key) | |
32 | + return True | |
33 | + except Registry.RegistryKeyNotFoundException: | |
34 | + return False | ... | ... |
winver.py
... | ... | @@ -2,6 +2,7 @@ import os |
2 | 2 | from runcmd import runProcess |
3 | 3 | import re |
4 | 4 | import pefile |
5 | +import findfile | |
5 | 6 | |
6 | 7 | _WIN_9x = 0 |
7 | 8 | _WIN_ME = 1 |
... | ... | @@ -19,7 +20,7 @@ _WIN_81 = 9 |
19 | 20 | _WIN_2k12R2 = 9 |
20 | 21 | _WIN_10 = 10 |
21 | 22 | |
22 | - | |
23 | +DETECTED_WINDOWS_PATH = {} | |
23 | 24 | |
24 | 25 | def getWindowsVersion(path): |
25 | 26 | if(os.path.isfile(getWindowsDirectory(path) + "/System32/ntdll.dll")): |
... | ... | @@ -51,13 +52,18 @@ def getWindowsVersion(path): |
51 | 52 | return _WIN_9x |
52 | 53 | |
53 | 54 | def getWindowsDirectory(path): |
54 | - result,code = runProcess(["find",path,"-xdev","-iname","explorer.exe","-print","-quit"]) | |
55 | - if(result.decode("utf-8") == ""): | |
56 | - return None | |
57 | - matches = result.decode("utf-8").splitlines() | |
58 | - #WARNING: ONLY CONSIDERING FIRST MATCH | |
59 | - #TODO: Improve | |
60 | - return os.path.dirname(os.path.realpath(matches[0])) | |
55 | + if DETECTED_WINDOWS_PATH[path] is None: | |
56 | + result = find_pattern("explorer.exe",path,False) | |
57 | + #result,code = runProcess(["find",path,"-xdev","-iname","explorer.exe","-print","-quit"]) | |
58 | + #if(result.decode("utf-8") == ""): | |
59 | + if(len(result) == 0): | |
60 | + return None | |
61 | + #matches = result.decode("utf-8").splitlines() | |
62 | + #WARNING: ONLY CONSIDERING FIRST MATCH | |
63 | + #TODO: Improve | |
64 | + #return os.path.dirname(os.path.realpath(matches[0])) | |
65 | + DETECTED_WINDOWS_PATH[path] = os.path.dirname(os.path.realpath(result)) | |
66 | + return DETECTED_WINDOWS_PATH[path] | |
61 | 67 | |
62 | 68 | def getUserProfiles(path): |
63 | 69 | version = getWindowsVersion(path) | ... | ... |