mirror of
https://github.com/wavestone-cdt/EDRSandblast.git
synced 2026-06-11 01:41:20 +00:00
Add g_CiOptions offset extract "feature"
Here is an example : ExtractOffsets.py ci -i C:\Windows\System32\ci.dll
This commit is contained in:
@@ -13,8 +13,8 @@ import threading
|
|||||||
CSVLock = threading.Lock()
|
CSVLock = threading.Lock()
|
||||||
|
|
||||||
machineType = dict(x86=332, x64=34404)
|
machineType = dict(x86=332, x64=34404)
|
||||||
knownImageVersions = dict(ntoskrnl=list(), wdigest=list())
|
knownImageVersions = dict(ntoskrnl=list(), wdigest=list(),ci=list())
|
||||||
extensions_by_mode = dict(ntoskrnl="exe", wdigest="dll")
|
extensions_by_mode = dict(ntoskrnl="exe", wdigest="dll",ci="dll")
|
||||||
|
|
||||||
def run(args, **kargs):
|
def run(args, **kargs):
|
||||||
"""Wrap subprocess.run to works on Windows and Linux"""
|
"""Wrap subprocess.run to works on Windows and Linux"""
|
||||||
@@ -41,7 +41,12 @@ def downloadSpecificFile(entry, pe_basename, pe_ext, knownPEVersions, output_fol
|
|||||||
virtual_size = entry['fileInfo']['virtualSize']
|
virtual_size = entry['fileInfo']['virtualSize']
|
||||||
file_id = hex(timestamp).replace('0x','').zfill(8).upper() + hex(virtual_size).replace('0x','')
|
file_id = hex(timestamp).replace('0x','').zfill(8).upper() + hex(virtual_size).replace('0x','')
|
||||||
url = 'https://msdl.microsoft.com/download/symbols/' + pe_name + '/' + file_id + '/' + pe_name
|
url = 'https://msdl.microsoft.com/download/symbols/' + pe_name + '/' + file_id + '/' + pe_name
|
||||||
|
# fix download error, sometimes version does not exist
|
||||||
|
try:
|
||||||
version = entry['fileInfo']['version'].split(' ')[0]
|
version = entry['fileInfo']['version'].split(' ')[0]
|
||||||
|
except KeyError:
|
||||||
|
print(f"{url} version is unknown.")
|
||||||
|
return "SKIP"
|
||||||
|
|
||||||
# Output file format: <PE>_build-revision.<exe | dll>
|
# Output file format: <PE>_build-revision.<exe | dll>
|
||||||
output_version = '-'.join(version.split('.')[-2:])
|
output_version = '-'.join(version.split('.')[-2:])
|
||||||
@@ -126,6 +131,9 @@ def extractOffsets(input_file, output_file, mode):
|
|||||||
elif "wdigest.dll" in line:
|
elif "wdigest.dll" in line:
|
||||||
imageType = "wdigest"
|
imageType = "wdigest"
|
||||||
break
|
break
|
||||||
|
elif "CI.dll" in line:
|
||||||
|
imageType = "ci"
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
print(f"[*] File {input_file} unrecognized")
|
print(f"[*] File {input_file} unrecognized")
|
||||||
return
|
return
|
||||||
@@ -170,6 +178,10 @@ def extractOffsets(input_file, output_file, mode):
|
|||||||
("g_fParameter_UseLogonCredential",get_symbol_offset),
|
("g_fParameter_UseLogonCredential",get_symbol_offset),
|
||||||
("g_IsCredGuardEnabled",get_symbol_offset)
|
("g_IsCredGuardEnabled",get_symbol_offset)
|
||||||
]
|
]
|
||||||
|
elif imageType == "ci":
|
||||||
|
symbols = [
|
||||||
|
("g_CiOptions",get_symbol_offset),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
symbols_values = list()
|
symbols_values = list()
|
||||||
@@ -219,18 +231,18 @@ def loadOffsetsFromCSV(loadedVersions, CSVPath):
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
parser.add_argument('mode', help='ntoskrnl or wdigest. Mode to download and extract offsets for either ntoskrnl or wdigest')
|
parser.add_argument('mode', help='ntoskrnl or wdigest or ci. Mode to download and extract offsets for either ntoskrnl or wdigest or ci')
|
||||||
parser.add_argument('-i', '--input', dest='input', required=True,
|
parser.add_argument('-i', '--input', dest='input', required=True,
|
||||||
help='Single file or directory containing ntoskrnl.exe / wdigest.dll to extract offsets from. If in download mode, the PE downloaded from MS symbols servers will be placed in this folder.')
|
help='Single file or directory containing ntoskrnl.exe / wdigest.dll / ci.dll to extract offsets from. If in download mode, the PE downloaded from MS symbols servers will be placed in this folder.')
|
||||||
parser.add_argument('-o', '--output', dest='output',
|
parser.add_argument('-o', '--output', dest='output',
|
||||||
help='CSV file to write offsets to. If the specified file already exists, only new ntoskrnl versions will be downloaded / analyzed. Defaults to NtoskrnlOffsets.csv / WdigestOffsets.csv in the current folder.')
|
help='CSV file to write offsets to. If the specified file already exists, only new ntoskrnl versions will be downloaded / analyzed. Defaults to NtoskrnlOffsets.csv / WdigestOffsets.csv / CiOffsets.csv in the current folder.')
|
||||||
parser.add_argument('-d', '--download', dest='download', action='store_true',
|
parser.add_argument('-d', '--download', dest='download', action='store_true',
|
||||||
help='Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.')
|
help='Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
mode = args.mode.lower()
|
mode = args.mode.lower()
|
||||||
if mode not in knownImageVersions:
|
if mode not in knownImageVersions:
|
||||||
print(f'[!] ERROR : unsupported mode "{args.mode}", supported mode are: "ntoskrnl" and "wdigest"')
|
print(f'[!] ERROR : unsupported mode "{args.mode}", supported mode are: "ntoskrnl" and "wdigest" and "ci"')
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
# check R2 version
|
# check R2 version
|
||||||
@@ -269,6 +281,8 @@ if __name__ == '__main__':
|
|||||||
output.write('ntoskrnlVersion,PspCreateProcessNotifyRoutineOffset,PspCreateThreadNotifyRoutineOffset,PspLoadImageNotifyRoutineOffset,_PS_PROTECTIONOffset,EtwThreatIntProvRegHandleOffset,EtwRegEntry_GuidEntryOffset,EtwGuidEntry_ProviderEnableInfoOffset,PsProcessType,PsThreadType,CallbackList\n')
|
output.write('ntoskrnlVersion,PspCreateProcessNotifyRoutineOffset,PspCreateThreadNotifyRoutineOffset,PspLoadImageNotifyRoutineOffset,_PS_PROTECTIONOffset,EtwThreatIntProvRegHandleOffset,EtwRegEntry_GuidEntryOffset,EtwGuidEntry_ProviderEnableInfoOffset,PsProcessType,PsThreadType,CallbackList\n')
|
||||||
elif mode == "wdigest":
|
elif mode == "wdigest":
|
||||||
output.write('wdigestVersion,g_fParameter_UseLogonCredentialOffset,g_IsCredGuardEnabledOffset\n')
|
output.write('wdigestVersion,g_fParameter_UseLogonCredentialOffset,g_IsCredGuardEnabledOffset\n')
|
||||||
|
elif mode == "ci":
|
||||||
|
output.write('g_CiOptionsOffset\n')
|
||||||
else:
|
else:
|
||||||
assert False
|
assert False
|
||||||
# In download mode, an updated list of image versions published will be retrieved from https://winbindex.m417z.com.
|
# In download mode, an updated list of image versions published will be retrieved from https://winbindex.m417z.com.
|
||||||
|
|||||||
Reference in New Issue
Block a user