def get_hive_type(folder_path, outfile, temp_time, key): #make directory in /tmp so path name isn't so long temp_folder = "/tmp/hives_to_rename_"+temp_time print("The temp unallocated folder is: " + temp_folder) check_for_folder(temp_folder, outfile) for file_name in os.listdir(folder_path): abs_file_path = os.path.join(folder_path, file_name) if re.search(str(key) + "_Unallocated", file_name) and (os.path.getsize(abs_file_path) and not(re.search(".txt", file_name))): #copy file to temp folder print("Copying file: " + abs_file_path + " to /tmp/hives_to_rename_" + temp_time) #outfile("Copying file: " + abs_file_path + " to /tmp/hives_to_rename_" + str(temp_time) +"\n") shutil.copy(abs_file_path, "/tmp/hives_to_rename_"+temp_time+"/"+file_name) #call get_hive_user_name get_hive_type_and_username(temp_time, file_name, outfile, abs_file_path, folder_path) elif re.search(str(key) + "_ORPHAN", file_name) and (os.path.getsize(abs_file_path) and not(re.search(".txt", file_name))): #copy file to temp folder print("Copying file: " + abs_file_path + " to /tmp/hives_to_rename_" + temp_time) #outfile("Copying file: " + abs_file_path + " to /tmp/hives_to_rename_" + str(temp_time) +"\n") shutil.copy(abs_file_path, "/tmp/hives_to_rename_"+temp_time+"/"+file_name) #call get_hive_user_name get_hive_type_and_username(temp_time, file_name, outfile, abs_file_path, folder_path) #delete temp folder if (os.path.exists("/tmp/hives_to_rename_" + temp_time)): shutil.rmtree("/tmp/hives_to_rename_" + temp_time)
def process_folder(folder_to_process, folder_path, evidence_no_quotes, outfile): for root,dirs,files in os.walk(folder_to_process): for file_name in files: print("The current file is: " + file_name) abs_file_path = os.path.join(root,file_name) quoted_abs_file_path = '"'+abs_file_path+'"' file_name_print = file_name.encode('utf-8') abs_file_path_print = abs_file_path.encode('utf-8') #make output folder for this file check_for_folder(folder_path + "/" + file_name, "NONE") #clean up printable variables file_name_print = re.sub('b\'','',str(file_name_print)) file_name_print = re.sub("'",'',file_name_print) abs_file_path_print = re.sub('b\'','',str(abs_file_path_print)) abs_file_path_print = re.sub("'",'', abs_file_path_print) print("The file to process is: " + abs_file_path_print) filename = os.path.basename(abs_file_path) run_mastiff("'"+ abs_file_path_print + "'", filename, folder_path, abs_file_path_print, outfile) run_pescanner("'"+ abs_file_path_print + "'", filename, folder_path, abs_file_path_print, outfile) run_pestr("'"+ abs_file_path_print + "'", filename, folder_path, abs_file_path_print, outfile) run_readpe("'"+ abs_file_path_print + "'", filename, folder_path, abs_file_path_print, outfile) run_pedump("'"+ abs_file_path_print + "'", filename, folder_path, abs_file_path_print, outfile) run_peframe("'"+ abs_file_path_print + "'", filename, folder_path, abs_file_path_print, outfile) run_signsrch("'"+ abs_file_path_print + "'", filename, folder_path, abs_file_path_print, outfile)
def run_mastiff(evidence, file_to_process, folder_path, evidence_no_quotes, outfile): print("Getting ready to run Mastiff.....") print("The file to process is: " + file_to_process) #make output folder for this file check_for_folder(folder_path + "/" + file_to_process + "/MASTIFF", "NONE") #get md5 hash of file we are processing md5_hash = calculate_md5(evidence_no_quotes) print("The md5 hash of this file is: " + md5_hash) #set up mastiff command mastiff_command = "mas.py " + evidence print("The mastiff command is: " + mastiff_command) outfile.write("The mastiff command is: " + mastiff_command + "\n\n") #run mastiff command subprocess.call([mastiff_command], shell=True) #move the mastiff output folder to the mantaray output folder move_command = "mv /var/log/mastiff/" + md5_hash + " " + "'" + folder_path + "/" + file_to_process + "/MASTIFF" + "'" print("The move command is: " + move_command) outfile.write("The move command is: " + move_command + "\n\n") #run move_command subprocess.call([move_command], shell=True)
def process_single_file(evidence, outfile, folder_path, key, outfile3): #initialize variables lat_long = [] files_of_interest = {} files_of_interest_list = [] #get file extension fileName, fileExtension = os.path.splitext(evidence) print("The filename is: " + fileName) print("The fileext is: " + fileExtension) filenames = fileName + fileExtension quoted_full_path = '"' + evidence + '"' if(fileExtension.lower() == ".jpg") or (fileExtension.lower() == ".jpeg"): exiftool_command = "exiftool -ext " + fileExtension.lower() + " " + quoted_full_path + " | grep 'GPS Position'" result = subprocess.call([exiftool_command], shell=True) if(result): print("No GPS Data in file: " + filenames) else: #create output folder for processed files check_for_folder(folder_path + "/Processed_files_" + str(key), outfile) check_for_folder(folder_path + "/Processed_files_" + str(key) + "/GPS_DATA", outfile) #check to see if kml file exists if(os.path.isfile(folder_path + "/Processed_files_" +str(key) +"/GPS_DATA/" + "GPS_EXIF_data.kml")): print("KML file already exists") else: #chdir to output folder os.chdir(folder_path + "/Processed_files_" + str(key) + "/GPS_DATA") kml = simplekml.Kml() #copy file with exifdata to output folder #shutil.copyfile(evidence, folder_path + "/Processed_files_" + str(key) + "/GPS_DATA/" + filenames) #call exiftool again and capture the lat long information into a list (longitude, latitude) = convert_dms_to_decimal(quoted_full_path, fileExtension.lower()) print("The latitude is: " + str(latitude)) print("The longitude is: " + str(longitude)) #add data to kml file kml.newpoint(name=filenames, coords=[(latitude, longitude)]) #save kml file kml.save("GPS_EXIF_data.kml") #add filename to list files_of_interest_list.append(filenames) #get filesize file_size = os.path.getsize(evidence) file_size = int(file_size)//1024 #calculate MD5 value of file md5value = subprocess.check_output(["md5sum " + quoted_full_path + "| awk '{print $1}'"], shell=True, universal_newlines=True) md5value = md5value.strip() outfile3.write(quoted_full_path + "\t" + md5value + "\t" + str(file_size) + "\n")
def plaso_mr(item_to_process, case_number, root_folder_path, evidence): #(evidence_type, case_number, folder_path, evidence_path.strip()) print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' root_folder_path_no_quotes = root_folder_path root_folder_path = "'" + root_folder_path + "'" #get datetime now = datetime.datetime.now() #create output folder path folder_path = root_folder_path_no_quotes + "/" + "Plaso" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Plaso_mr_logfile.txt" outfile = open(log_file, 'wt+') if (item_to_process == "Directory"): folder_to_process = evidence_no_quotes process_folder(folder_path, case_number, folder_to_process, outfile) elif (item_to_process == "EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, export_file, outfile) #umount if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif (item_to_process == "Bit-Stream Image"): Image_Path = evidence_no_quotes #get datetime now = datetime.datetime.now() process_folder(folder_path, case_number, Image_Path, outfile) ## I have not been able to test this code yet since I don't have a large enough test imge #set file to split #file_to_split = folder_path + "/" + case_number + ".plaso.csv" #file_to_split_basename = case_number + ".plaso.csv" #pass csv file to split_csv to see if it needs to get split #split_csv(case_number, folder_path, outfile) #split_csv(case_number, folder_path, outfile, file_to_split, file_to_split_basename) #close output file outfile.close()
def run_signsrch(evidence, file_to_process, folder_path, evidence_no_quotes, outfile): print("Getting ready to run PEFRAME.....") print("The file to process is: " + file_to_process) #make output folder for this file check_for_folder(folder_path + "/" + file_to_process + "/SIGNSRCH", "NONE") #set up signsrch command signsrch_command = "signsrch " + evidence + " > " + "'" + folder_path + "/" + file_to_process + "/SIGNSRCH/SIGNSRCH_output.txt" + "'" print("The signsrch command is: " + signsrch_command) outfile.write("The signsrch command is: " + signsrch_command + "\n\n") #run signsrch command subprocess.call([signsrch_command], shell=True)
def run_peframe(evidence, file_to_process, folder_path, evidence_no_quotes, outfile): print("Getting ready to run PEFRAME.....") print("The file to process is: " + file_to_process) #make output folder for this file check_for_folder(folder_path + "/" + file_to_process + "/PEFRAME", "NONE") #set up peframe command peframe_command = "peframe " + evidence + " > " + "'" + folder_path + "/" + file_to_process + "/PEFRAME/PEFRAME_output.txt" + "'" print("The peframe command is: " + peframe_command) outfile.write("The peframe command is: " + peframe_command + "\n\n") #run peframe command subprocess.call([peframe_command], shell=True)
def run_floss(evidence, file_to_process, folder_path, evidence_no_quotes, outfile): print("Getting ready to run FLOSS.....") print("The file to process is: " + file_to_process) #make output folder for this file check_for_folder(folder_path + "/" + file_to_process + "/FLOSS", "NONE") #set up signsrch command signsrch_command = "floss -v " + evidence + " > " + "'" + folder_path + "/" + file_to_process + "/FLOSS/FLOSS_output.txt" + "'" print("The floss command is: " + floss_command) outfile.write("The floss command is: " + floss_command + "\n\n") #run signsrch command subprocess.call([floss_command], shell=True)
def mount_shadow_volumes(vssvolume_mnt, outfile, folder_path, log_folder_path, out_folder, key, searchfile): print("Inside mount_shadow_volumes sub") print("Vssvolume_mnt: " + vssvolume_mnt) #check for existence of folder vss_mount = check_for_folder("/mnt/vss_mount", outfile) vss_volumes = os.listdir(vssvolume_mnt) print(vss_volumes) for item in vss_volumes: print("About to process Shadow Volume: " + item) #Create Output Directory if not os.path.exists(folder_path + "/VSS_" + str(item)): os.makedirs(folder_path + "/VSS_" + str(item)) outfile.write("Just created output folder: " + folder_path + "/VSS_" + str(item) + "\n\n") else: print("Output folder: " + folder_path +"/VSS_" + str(item) + " already exists") outfile.write("Output folder: " + folder_path +"/VSS_" + str(item) + " already exists\n\n") out_folder = folder_path +"/VSS_" + str(item) #call parted function partition_info_dict, temp_time = parted(outfile, vssvolume_mnt + "/"+item) block_size = get_block_size_parted(outfile, temp_time) for key,value in partition_info_dict.items(): print("About to search for files in: " + item) process_overt_deleted_files(value, key, vssvolume_mnt+"/"+item, outfile, folder_path, log_folder_path, out_folder, block_size, item, temp_time, searchfile)
def mount_shadow_volumes(vssvolume_mnt, outfile, folder_path, temp_time): print("Vssvolume_mnt: " + vssvolume_mnt) #check for existence of folder vss_mount = check_for_folder("/mnt/vss_mount", outfile) vss_volumes = os.listdir(vssvolume_mnt) print(vss_volumes) for item in vss_volumes: print("Currently processing vss volume: " + item) #call parted function partition_info_dict, temp_time = parted(outfile, vssvolume_mnt + "/" + item) block_size = get_block_size_parted(outfile, temp_time) for key, value in partition_info_dict.items(): print("About to process registry hives from: " + item) process_overt_deleted_files(value, key, vssvolume_mnt + "/" + item, outfile, folder_path, block_size, item, "SHADOW VOLUME", temp_time) #unmounting vss volume if (vssvolume_mnt != "NULL"): print("Unmounting: " + vssvolume_mnt) outfile.write("Unmounting: " + vssvolume_mnt + "\n") subprocess.call(['sudo umount -f ' + vssvolume_mnt], shell=True) os.rmdir(vssvolume_mnt)
def run_pedump(evidence, file_to_process, folder_path, evidence_no_quotes, outfile): print("Getting ready to run PEDUMP.....") print("The file to process is: " + file_to_process) #make output folder for this file check_for_folder(folder_path + "/" + file_to_process + "/PEDUMP", "NONE") #get md5 hash of file we are processing #md5_hash = calculate_md5(evidence_no_quotes) #print("The md5 hash of this file is: " + md5_hash) #set up pedump command pedump_command = "pedump " + evidence + " > " + "'" + folder_path + "/" + file_to_process + "/PEDUMP/PEDUMP_output.txt" + "'" print("The pedump command is: " + pedump_command) outfile.write("The pedump command is: " + pedump_command + "\n\n") #run pedump command subprocess.call([pedump_command], shell=True)
def run_readpe(evidence, file_to_process, folder_path, evidence_no_quotes, outfile): print("Getting ready to run READPE.....") print("The file to process is: " + file_to_process) #make output folder for this file check_for_folder(folder_path + "/" + file_to_process + "/READPE", "NONE") #get md5 hash of file we are processing #md5_hash = calculate_md5(evidence_no_quotes) #print("The md5 hash of this file is: " + md5_hash) #set up readpe command readpe_command = "readpe " + evidence + " > " + "'" + folder_path + "/" + file_to_process + "/READPE/READPE_output.txt" + "'" print("The readpe command is: " + readpe_command) outfile.write("The readpe command is: " + readpe_command + "\n\n") #run prestr command subprocess.call([readpe_command], shell=True)
def remove_duplicates_mr(root_folder_path, evidence): print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #create output folder path folder_path = root_folder_path + "/" + "Remove_Duplicates" check_for_folder(folder_path, "NONE") remove_dupes_command = "sudo fdupes -r -d -N " + evidence + " > " + '"' + folder_path + "/fdupes_duplicates_log.txt" + '"' print ("The remove dupes command is: " + remove_dupes_command + "\n\n") print ("Removing duplicate files recursively from folder: " + evidence + "\n\n") #run the remove dupes command subprocess.call([remove_dupes_command], shell=True) #get filesize of mmls_output.txt file_size = os.path.getsize(folder_path + "/fdupes_duplicates_log.txt") #if filesize of mmls output is 0 then run parted if(file_size == 0): print("No duplicates found\n") outfile = open(folder_path + "/fdupes_duplicates_log.txt", 'wt+') outfile.write("No duplicate files found!") #close outfile outfile.close() else: #if log file exists then run unix2dos against the logfile unix2dos(folder_path + "/fdupes_duplicates_log.txt") #remove empty directories for root,dirs,files in os.walk(root_folder_path): for directories in dirs: dir_name = os.path.join(root,directories) #if directory is empty then delete it if not os.listdir(dir_name): os.rmdir(dir_name)
def remove_duplicates_mr(root_folder_path, evidence): print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #create output folder path folder_path = root_folder_path + "/" + "Remove_Duplicates" check_for_folder(folder_path, "NONE") remove_dupes_command = "sudo fdupes -r -d -N " + evidence + " > " + '"' + folder_path + "/fdupes_duplicates_log.txt" + '"' print("The remove dupes command is: " + remove_dupes_command + "\n\n") print("Removing duplicate files recursively from folder: " + evidence + "\n\n") #run the remove dupes command subprocess.call([remove_dupes_command], shell=True) #get filesize of mmls_output.txt file_size = os.path.getsize(folder_path + "/fdupes_duplicates_log.txt") #if filesize of mmls output is 0 then run parted if (file_size == 0): print("No duplicates found\n") outfile = open(folder_path + "/fdupes_duplicates_log.txt", 'wt+') outfile.write("No duplicate files found!") #close outfile outfile.close() else: #if log file exists then run unix2dos against the logfile unix2dos(folder_path + "/fdupes_duplicates_log.txt") #remove empty directories for root, dirs, files in os.walk(root_folder_path): for directories in dirs: dir_name = os.path.join(root, directories) #if directory is empty then delete it if not os.listdir(dir_name): os.rmdir(dir_name)
def check_for_shadow_volumes(Image_Path, key, block_size, outfile, folder_path, temp_time): #set shadow volume variables has_shadow_volumes = "NULL" vssvolume_mnt = "NULL" #divide offset by block size so it is in correct format for vshadowinfo key_bytes = int(key)//int(block_size) key_bytes_disk_offset = int(key) * int(block_size) image_no_quotes = Image_Path.replace("'","") print("\nChecking: " + Image_Path + " for shadow volumes") f = open('/tmp/dump_' + temp_time + '.txt', 'w+t') try: vshadow_info_command = "vshadowinfo -v -o " + str(key) + " " + Image_Path# + " > /tmp/dump.txt" #print("The vshadow_command is: " + vshadow_info_command) outfile.write("The vshadow_command is: " + vshadow_info_command) subprocess.call([vshadow_info_command], shell=True, stdout = f, stderr=subprocess.STDOUT) #vshadow_output = subprocess.check_output([vshadow_info_command], shell=True, stderr=subprocess.STDOUT) #f.close() f =open('/tmp/dump_' + temp_time + '.txt', 'rt') #print("try succedded") for line in f: line = line.strip() print(line) if (re.search("No Volume Shadow Snapshots found", line)): has_shadow_volumes = "NO" if(has_shadow_volumes != "NO"): print("Partition at offset: " + str(key_bytes) + " has shadow volumes.") outfile.write("Partition at offset: " + str(key_bytes) + " has shadow volumes.") #check for existence of folder vssvolume_mnt = check_for_folder("/mnt/vssvolume", outfile) #mount shadow volumes for partition mount_shadow_command = "sudo vshadowmount -o " + str(key) + " " + Image_Path + " " + vssvolume_mnt print("The mount_shadow_command is: " + mount_shadow_command) subprocess.call(["sudo vshadowmount -o " + str(key) + " " + Image_Path + " " + vssvolume_mnt], shell=True, stderr=subprocess.STDOUT) #pass vssvolume mount point to mount_shadow_volume for mounting mount_shadow_volumes(vssvolume_mnt, outfile, folder_path, temp_time) elif(has_shadow_volumes == "NO"): print("Partition at offset: " + str(key) + " has no shadow volumes") f.close() except: print("The vshadow_info command for partition: " + str(key) + " failed") return vssvolume_mnt
def pst_processor_mr(item_to_process, case_number, root_folder_path, evidence): #(evidence_type, case_number, folder_path, evidence_path.strip()) print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = "'" + evidence + "'" root_folder_path_no_quotes = root_folder_path root_folder_path = "'" + root_folder_path + "'" #get datetime now = datetime.datetime.now() #create output folder path folder_path = root_folder_path_no_quotes + "/" + "PST_Extracted_Emails" check_for_folder(folder_path, "NONE") #create folder for extracted_messages check_for_folder(folder_path + "/" "All Extracted_Messages", "NONE") #open a log file for output log_file = folder_path + "/PST_mr_logfile.txt" outfile = open(log_file, 'wt+') emails_of_interest_file = subprocess.check_output(['zenity --file-selection --filename="/mnt/hgfs/" ' '--title "Select file containing email addresses of interest (comma seperated)"'], shell=True, universal_newlines=True) #process the PST file process_pst_command = 'readpst -o ' + "'" + folder_path + "/" "All Extracted_Messages" + "'" + " -D -j 4 -r -tea -e " + evidence print("The process_pst_command is: " + process_pst_command) subprocess.call([process_pst_command],shell=True, universal_newlines=True) #open emails_of_interest_file and parse emails into list with open(emails_of_interest_file.strip(), 'r', encoding='utf-8') as infile: for line in infile: email_addresses_split = line.split(',') for element in email_addresses_split: print("Creating output folder for email address: " + element) check_for_folder(folder_path + "/" + element, "NONE") #cd into the extracted_messages SENT folder os.chdir(folder_path + "/" "All Extracted_Messages/Personal Folders/Sent Items") #run the grep command in the SENT folder grep_command = "grep -rl --null --include '*.msg' --include '*.eml' " + element + " | xargs -0r cp -t " + "'" + folder_path + "/" + element + "'" print("The grep_command is: " + grep_command) subprocess.call([grep_command],shell=True, universal_newlines=True) #close output file outfile.close()
def mount_shadow_volumes(vssvolume_mnt, outfile, folder_path): print("Inside mount_shadow_volumes sub") print("Vssvolume_mnt: " + vssvolume_mnt) #check for existence of folder vss_mount = check_for_folder("/mnt/vss_mount", outfile) vss_volumes = os.listdir(vssvolume_mnt) print(vss_volumes) for item in vss_volumes: print("About to process Shadow Volume: " + item) #call parted function partition_info_dict, temp_time = parted(outfile, vssvolume_mnt + "/"+item) block_size = get_block_size_parted(outfile, temp_time) for key,value in partition_info_dict.items(): print("About to process registry hives from: " + item) process_overt_deleted_files(value, key, vssvolume_mnt+"/"+item, outfile, folder_path, block_size, item, temp_time)
def mount_shadow_volumes(vssvolume_mnt, outfile, folder_path, temp_time, parsers): print("Vssvolume_mnt: " + vssvolume_mnt) # disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command # is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && " \ "sudo gsettings set org.gnome.desktop.media-handling automount-open false && " \ "sudo gsettings set org.gnome.desktop.media-handling autorun-never true" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #check for existence of folder vss_mount = check_for_folder("/mnt/vss_mount", outfile) vss_volumes = os.listdir(vssvolume_mnt) print(vss_volumes) for item in vss_volumes: print("Currently processing vss volume: " + item) #call parted function partition_info_dict, temp_time = parted(outfile, vssvolume_mnt + "/" + item) block_size = get_block_size_parted(outfile, temp_time) for key, value in partition_info_dict.items(): print("About to process Google Analytic Cookies from: " + item) mount.mount(value, key, vssvolume_mnt + "/" + item, outfile, vss_mount) os.makedirs(folder_path + "/" + item) process_dir(vss_mount, folder_path + "/" + item, parsers, item) #unmounting vss volume if (vssvolume_mnt != "NULL"): try: print("Unmounting: " + vssvolume_mnt) outfile.write("Unmounting: " + vssvolume_mnt + "\n") subprocess.call(['sudo umount -f ' + vssvolume_mnt], shell=True) os.rmdir(vssvolume_mnt) except: print("Unable to unmount: " + vssvolume_mnt) outfile.write("Unable to unmount: " + vssvolume_mnt)
def mount_shadow_volumes(vssvolume_mnt, outfile, folder_path): print("Inside mount_shadow_volumes sub") print("Vssvolume_mnt: " + vssvolume_mnt) #check for existence of folder vss_mount = check_for_folder("/mnt/vss_mount", outfile) vss_volumes = os.listdir(vssvolume_mnt) print(vss_volumes) for item in vss_volumes: print("About to process Shadow Volume: " + item) #call parted function partition_info_dict, temp_time = parted(outfile, vssvolume_mnt + "/" + item) block_size = get_block_size_parted(outfile, temp_time) for key, value in partition_info_dict.items(): print("About to process registry hives from: " + item) process_overt_deleted_files(value, key, vssvolume_mnt + "/" + item, outfile, folder_path, block_size, item, temp_time)
def mount_shadow_volumes(vssvolume_mnt, outfile, folder_path, temp_time, parsers): print("Vssvolume_mnt: " + vssvolume_mnt) # disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command # is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && " \ "sudo gsettings set org.gnome.desktop.media-handling automount-open false && " \ "sudo gsettings set org.gnome.desktop.media-handling autorun-never true" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #check for existence of folder vss_mount = check_for_folder("/mnt/vss_mount", outfile) vss_volumes = os.listdir(vssvolume_mnt) print(vss_volumes) for item in vss_volumes: print("Currently processing vss volume: " + item) #call parted function partition_info_dict, temp_time = parted(outfile, vssvolume_mnt + "/"+item) block_size = get_block_size_parted(outfile, temp_time) for key,value in partition_info_dict.items(): print("About to process Google Analytic Cookies from: " + item) mount.mount(value,key,vssvolume_mnt+"/"+item,outfile,vss_mount) os.makedirs(folder_path+"/"+item) process_dir(vss_mount, folder_path+"/"+item, parsers,item) #unmounting vss volume if(vssvolume_mnt != "NULL"): try: print("Unmounting: " + vssvolume_mnt) outfile.write("Unmounting: " + vssvolume_mnt + "\n") subprocess.call(['sudo umount -f ' + vssvolume_mnt], shell=True) os.rmdir(vssvolume_mnt) except: print("Unable to unmount: " + vssvolume_mnt) outfile.write("Unable to unmount: " + vssvolume_mnt)
def mount_shadow_volumes(vssvolume_mnt, outfile, folder_path, temp_time): print("Vssvolume_mnt: " + vssvolume_mnt) #check for existence of folder vss_mount = check_for_folder("/mnt/vss_mount", outfile) vss_volumes = os.listdir(vssvolume_mnt) print(vss_volumes) for item in vss_volumes: print("Currently processing vss volume: " + item) #call parted function partition_info_dict, temp_time = parted(outfile, vssvolume_mnt + "/"+item) block_size = get_block_size_parted(outfile, temp_time) for key,value in partition_info_dict.items(): print("About to process registry hives from: " + item) process_overt_deleted_files(value, key, vssvolume_mnt+"/"+item, outfile, folder_path, block_size, item, "SHADOW VOLUME", temp_time) #unmounting vss volume if(vssvolume_mnt != "NULL"): print("Unmounting: " + vssvolume_mnt) outfile.write("Unmounting: " + vssvolume_mnt + "\n") subprocess.call(['sudo umount -f ' + vssvolume_mnt], shell=True) os.rmdir(vssvolume_mnt)
def exifdata_mr(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "EXIF_Tool" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/EXIF_Tool_logfile.txt" outfile = open(log_file, 'wt+') #set up tuple holding all of the file extensions exiftool can process valid_extensions = ('3FR', '3G2', '3GP2', '3GP', '3GPP', 'ACR', 'AFM', 'ACFM', 'AMFM', 'AI', 'AIT', 'AIFF', 'AIF', 'AIFC', 'APE', 'ARW', 'ASF', 'AVI', 'BMP', 'DIB', 'BTF', 'TIFF', 'TIF', 'CHM', 'COS', 'CR2', 'CRW', 'CIFF', 'CS1', 'DCM', 'DC3', 'DIC', 'DICM', 'DCP', 'DCR', 'DFONT', 'DIVX', 'DJVU', 'DJV', 'DNG', 'DOC', 'DOT', 'DOCX', 'DOCM', 'DOTX', 'DOTM', 'DYLIB', 'DV', 'DVB', 'EIP', 'EPS', 'EPSF', 'EXR', 'PS', 'ERF', 'EXE', 'DLL', 'EXIF', 'F4A', 'F4B', 'F4P', 'F4V', 'FFF', 'FLA', 'FLAC', 'FLV', 'FPX', 'GIF', 'GZ', 'GZIP', 'HDP', 'HDR', 'WDP', 'HTML', 'HTM', 'XHTML', 'ICC', 'ICM', 'IIQ', 'IND', 'INDD', 'INDT', 'INX', 'ITC', 'JP2', 'JPF', 'JPM', 'JPX', 'JPEG', 'JPC', 'JPG', 'J2C', 'J2K', 'K25', 'KDC', 'KEY', 'KTH', 'LNK', 'M2TS', 'MTS', 'M2T', 'TS', 'M4A', 'M4B', 'M4P', 'M4V', 'MEF', 'MIE', 'MIFF', 'MIF', 'MKA', 'MKV', 'MKS', 'MOS', 'MOV', 'Q', 'MP3', 'MP4', 'MPC', 'MPEG', 'MPG', 'M2V', 'MPO', 'MQV', 'QT', 'MRW', 'MXF', 'NEF', 'NMBTEMPLATE', 'NRW', 'NUMBERS', 'ODB', 'ODC', 'ODF', 'ODG', 'OGI', 'ODP', 'ODS', 'ODT', 'OGG', 'ORF', 'OTF', 'PAGES', 'PDF', 'PEF', 'PFA', 'PFB', 'PFM', 'PGF', 'PICT', 'PCT', 'PMP', 'PNG', 'JNG', 'MNG', 'PPM', 'PBM', 'PGM', 'PPT', 'PPS', 'POT', 'POTX', 'POTM', 'PPSX', 'PPSM', 'PPTX', 'PPTM', 'PSD', 'PSB', 'PSP', 'PSPIMAGE', 'QTIF', 'QTI', 'QIF', 'RAF', 'RAM', 'RPM', 'RAW', 'RAR', 'RAW', 'RIFF', 'RIF', 'RM', 'RV', 'RMVB', 'RSRC', 'RTF', 'RW2', 'RWL', 'RWZ', 'SO', 'SR2', 'SRF', 'SRW', 'SVG', 'SWF', 'THM', 'THMX', 'TIFF', 'TIF', 'TTF', 'TTC', 'VOB', 'VRD', 'VSD', 'WAV', 'WEBM', 'WEBP', ',WMA', 'WMV', 'X3F', 'XCF', 'XLS', 'XLT', 'XLSX', 'XLSM', 'XLSB', 'XLTX', 'XLTM', 'XMP', 'ZIP') if(item_to_process =="EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, valid_extensions, item_to_process) #umount if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) if(item_to_process == "Directory"): mount_point = evidence_no_quotes process_folder(mount_point, valid_extensions, item_to_process, outfile, folder_path) elif(item_to_process == "Bit-Stream Image"): #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #select dd image to process Image_Path = evidence #check if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path #no_quotes_path = Image_Path.replace("'","") #print("THe no quotes path is: " + no_quotes_path) #call mount_ewf function Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") #if filesize of mmls output is 0 then run parted if(file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key,value in partition_info_dict.items(): #set up file object for output file output_file = folder_path + "/Exif_data_partition_offset_" + str(key) +".txt" print("The output_file is: " + output_file) exif_out = open(output_file, 'wt+') #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #call mount sub-routine success_code, loopback_device_mount = mount(value,key,Image_Path, outfile, mount_point) if(success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + ". Scanning for files of interest.....\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #get the filename without extension for root,dirs,files in os.walk(mount_point): for filenames in files: fileName, fileExtension = os.path.splitext(filenames) #replace the . in the file extension with nothing file_extension = fileExtension.replace('.','') file_extension = file_extension.upper() file_name = os.path.basename(fileName) for extension in valid_extensions: if(file_extension == extension): print("Running exiftool against file: " + filenames) outfile.write("Running exiftool against file: " + filenames) #chdir to output foler os.chdir(folder_path) #get absolute path to file file_name = os.path.join(root,filenames) quoted_file_name = "'" +file_name +"'" #enclose strings in quotes quoted_root = "'" +root +"'" #set up exiftool command exif_command = "exiftool -ext " + extension + " -l -sep *********** -z " + quoted_file_name + " >> " + "'" + folder_path + "/Exif_data_partition_offset_" + str(key) +".txt" + "'" #print("The exif command is: " + exif_command + "\n\n") outfile.write("The exif command is: " + exif_command + "\n\n") #execute the exif command subprocess.call([exif_command], shell=True) #exif_out.write("\n\n") #unmount and remove mount points if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #close outfile exif_out.close() #program cleanup outfile.close() #remove mount points created for this program if(os.path.exists(mount_point)): if not (item_to_process == "Directory"): os.rmdir(mount_point) if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf") #delete empty directories in output folder for root, dirs, files in os.walk(folder_path, topdown=False): for directories in dirs: files = [] dir_path = os.path.join(root,directories) files = os.listdir(dir_path) if(len(files) == 0): os.rmdir(dir_path)
def be_mr(item_to_process, case_number, folder_path, evidence, whitelist_location, speed, keyword_list): evidence = "'" + evidence + "'" speed = speed.strip() #calculate number of processors to use (Speed-Slow, Speed-Fast, Speed-Med calc_cores_command = "cat /proc/cpuinfo | grep processor | wc -l" num_of_cores = subprocess.check_output([calc_cores_command], shell=True) num_of_cores = num_of_cores.decode(encoding='UTF-8') num_of_cores = num_of_cores.strip() print("This VM has " + str(num_of_cores) +" cores") if(num_of_cores == "1"): cores_to_use = 1 elif(speed == "Speed-Slow"): cores_to_use = 1 elif(speed == "Speed-Med"): cores_to_use = int(num_of_cores)//2 elif(speed == "Speed-Fast"): cores_to_use = num_of_cores print("Item to process is: " + item_to_process) print("Case number is: " + case_number) print("Output folder is: " + folder_path) print("Evidence type is: " + evidence) print("Whitelist location is: " + whitelist_location) print("Processing speed is: " + speed) print("Keyword list is: " + keyword_list) #open a log file for output #log_file = folder_path + "/" + case_number + "_logfile.txt" #outfile = open(log_file, 'a') #add subfolder to output path so BE has empty folder to write to folder_path_be = "'" + folder_path +"/Bulk_Extractor_Results'" check_for_folder(folder_path_be, "NONE") if(item_to_process == "Directory"): process_folder(evidence, folder_path_be, whitelist_location, speed, "NONE", keyword_list, cores_to_use) elif(item_to_process == "EnCase Logical Evidence File"): mount_point = mount_encase_v6_l01(case_number, evidence, "NONE") process_folder(mount_point, folder_path_be, whitelist_location, speed, "NONE", keyword_list, cores_to_use) elif(item_to_process == "Single File") or (item_to_process == "Memory Image") or (item_to_process == "EnCase Logical Evidence File"): #set up bulk extractor command if(whitelist_location != "NONE") and (keyword_list == "NONE"): be_command = "bulk_extractor -o " + folder_path_be + ' -w "' + whitelist_location + '" -j ' + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list =="NONE"): be_command = "bulk_extractor -o " + folder_path_be + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location != "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -o " + folder_path_be + ' -w "' + whitelist_location + '" -F "' + keyword_list + '" -j ' + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -o " + folder_path_be + ' -F "' + keyword_list + '" -j ' + str(cores_to_use) + " " + evidence #outfile.write("The be_command is: " + be_command + "\n") #run be_command print("The be command is: " + be_command) subprocess.call([be_command], shell=True) elif(item_to_process == "Bit-Stream Image"): #set up bulk extractor command if(whitelist_location != "NONE") and (keyword_list == "NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + ' -w "' + whitelist_location + '" -j ' + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list =="NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location != "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + ' -w "' + whitelist_location + '" -F "' + keyword_list + '" -j ' + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + ' -F "' + keyword_list + '" -j ' + str(cores_to_use) + " " + evidence #run be_command print("The be command is: " + be_command) subprocess.call([be_command], shell=True) #run fiwalk fiwalk_command = "fiwalk -x " + evidence + " > " + '"' + folder_path + '/Bulk_Extractor_Results/fiwalk_output.xml' + '"' print("Running fiwalk: " + fiwalk_command) subprocess.call([fiwalk_command], shell=True) #run identify_filenames.py identify_filenames_command = "python3 /usr/share/bulk-extractor/python/identify_filenames.py --all --imagefile " + evidence + " --xmlfile " + '"' + folder_path + "/Bulk_Extractor_Results/fiwalk_output.xml" + '" "' + folder_path + "/Bulk_Extractor_Results" + '" "' + folder_path + "/Bulk_Extractor_Results/annotated_results/" + '"' print("Running identify_filenames.py: " + identify_filenames_command) subprocess.call([identify_filenames_command], shell=True) #chdir to output foler os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path + "/Bulk_Extractor_Results/"): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + quoted_full_path) #unix2dos_command = "sudo unix2dos " + "'"+filenames+"'" unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def plist_processor(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + "MantaRay_" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "PLIST_Processor" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/PLIST_processor_logfile.txt" outfile = open(log_file, 'wt+') #open an error file for output log_file = folder_path + "/PLIST_processor_error_log.txt" outfile_error = open(log_file, 'wt+') #open file to write output exp_file = folder_path + "/" + case_number + "_PLIST_Triage.txt" export_file = open(exp_file, 'a') if (item_to_process == "Directory"): folder_to_process = evidence_no_quotes process_folder(folder_to_process, export_file, outfile, outfile_error, now) elif (item_to_process == "EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, export_file, outfile, outfile_error, now) #umount if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif (item_to_process == "Bit-Stream Image"): #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") Image_Path = evidence #check if Image file is in Encase format if re.search(".E01", Image_Path): #set mount point #mount_point = "/mnt/"+ case_number+"_ewf" Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") #if filesize of mmls output is 0 then run parted if (file_size == 0): print("mmls output was empty, running parted\n") outfile.write("mmls output was empty, running parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print( "We found a GUID partition table, need to use parted") outfile.write( "We found a GUID partition table, need to use parted\n" ) #call parted function partition_info_dict, temp_time = parted( outfile, Image_Path) mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key, value in partition_info_dict.items(): cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #process plist files if (value == "hfs+"): #call mount sub-routine success_code, loopback_device_mount = mount( value, str(key), Image_Path, outfile, mount_point) if (success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write( "Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #process process_folder(mount_point, export_file, outfile, outfile_error, now) #unmount subprocess.call(['umount ' + mount_point], shell=True) subprocess.call(['losetup -d ' + loopback_device_mount], shell=True) else: print("This partition is not formatted HFS+") outfile.write("This partition is not formatted HFS+\n\n") #close export_file export_file.close() #chdir to output foler os.chdir(folder_path) #unmount and remount points if re.search(".E01", Image_Path): if (os.path.exists(mount_point + "_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf") #remove empty directories for root, dirs, files in os.walk(folder_path, topdown=False): for directory in dirs: dir_path = os.path.join(root, directory) if not os.listdir(dir_path): outfile.write("Removing empty folder: " + dir_path + "\n") os.rmdir(dir_path) #close outfiles outfile.close() #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True) #delete /tmp/ls_output.txt if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") if (os.path.exists("/tmp/timeline_partition_info_" + temp_time + ".txt")): os.remove("/tmp/timeline_partition_info_" + temp_time + ".txt") if (os.path.exists("/tmp/dump_" + temp_time + ".txt")): os.remove("/tmp/dump_" + temp_time + ".txt") if (os.path.exists("/tmp/fls_output_" + temp_time + ".txt")): os.remove("/tmp/fls_output_" + temp_time + ".txt") if (os.path.exists("/tmp/hives_to_rename_" + temp_time)): shutil.rmtree("/tmp/hives_to_rename_" + temp_time)
def create_kml_from_exif_mr(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #create output folder path folder_path = root_folder_path + "/" + "KML_From_EXIF" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/KML_From_EXIF_logfile.txt" outfile = open(log_file, 'wt+') #initialize variables files_of_interest = {} files_of_interest_list = [] mount_point = "NONE" log_file3 = folder_path + "/" + case_number + "_files_to_exploit.xls" outfile3 = open(log_file3, 'wt+') #write out column headers to xls file outfile3.write("Name\tMD5\tFile Size (kb)\n") if (item_to_process == "Directory"): #select folder to process folder_process = evidence_no_quotes #set folder variable to "folder" since this is a folder and not a disk partition folder = "Directory" #call process subroutine process(folder_process, outfile, folder_path, folder, outfile3) elif (item_to_process == 'EnCase Logical Evidence File'): folder = "LEF" file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process(mount_point, outfile, folder_path, folder, outfile3) #umount if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif (item_to_process == 'Single File'): process_single_file(evidence_no_quotes, outfile, folder_path, "Single-File", outfile3) elif (item_to_process == 'Bit-Stream Image'): #select image to process Image_Path = evidence #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S") #check to see if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path no_quotes_path = Image_Path.replace("'", "") print("The no quotes path is: " + no_quotes_path) #call mount_ewf function cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) #partition_info_dict_temp, temp_time = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") print("The filesize is: " + str(file_size)) #if filesize of mmls output is 0 then run parted if (file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print( "We found a GUID partition table, need to use parted") outfile.write( "We found a GUID partition table, need to use parted\n" ) #call parted function partition_info_dict, temp_time = parted( outfile, Image_Path) #close file mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) #for key,value in partition_info_dict.items(): for key, value in sorted(partition_info_dict.items()): #create output folder for processed files if not os.path.exists(folder_path + "/Processed_files_" + str(key)): os.mkdir(folder_path + "/Processed_files_" + str(key)) #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #call mount sub-routine success_code, loopback_device_mount = mount( value, key, Image_Path, outfile, mount_point) if (success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + ". Scanning for files of interest.....\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #call process subroutine process(mount_point, outfile, folder_path, key, outfile3) #unmount and remove mount points if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #delete /tmp files created for processing bit-stream images if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") #write out list of filenames to end of output file so that user can create a filter for those filenames in Encase outfile3.write( "\n\n******** LIST of FILENAMES of INTEREST ******************\n") #sort list so that all values are unique unique(files_of_interest_list) for files in files_of_interest_list: outfile3.write(files + "\n") #program cleanup outfile.close() outfile3.close() #remove mount points created for this program if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) if (os.path.exists(mount_point + "_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf") #convert outfile using unix2dos #chdir to output foler os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + filenames subprocess.call([unix2dos_command], shell=True) #delete empty directories in output folder for root, dirs, files in os.walk(folder_path, topdown=False): for directories in dirs: files = [] dir_path = os.path.join(root, directories) files = os.listdir(dir_path) if (len(files) == 0): os.rmdir(dir_path) #unmount and remove mount points if (mount_point != "NONE"): if (os.path.exists(mount_point + "_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf")
def av_scanner_mr(item_to_process, case_number, root_folder_path, evidence, conf_file): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) print("The configuration file is located at: " + conf_file) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + "MantaRay_" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path output_folder_path = root_folder_path + "/" + "AV_Scanner" check_for_folder(output_folder_path, "NONE") #open a log file for output log_file = output_folder_path + "/AV_Scanner_logfile.txt" outfile = open(log_file, 'wt+') if(item_to_process == "Single File"): print("Please put your file in a folder and then scan the folder") elif(item_to_process == "Directory"): folder_to_process = evidence_no_quotes process_folder(folder_to_process, output_folder_path, outfile, "Directory", conf_file) elif(item_to_process =="EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, output_folder_path, outfile, "LEF", conf_file) #umount if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif(item_to_process == "Bit-Stream Image"): Image_Path = evidence #process every file on every partition #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #check if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path #no_quotes_path = Image_Path.replace("'","") #print("THe no quotes path is: " + no_quotes_path) #call mount_ewf function Image_Path = mount_ewf(Image_Path, outfile,mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") #if filesize of mmls output is 0 then run parted if(file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key,value in sorted(partition_info_dict.items()): #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #call mount sub-routine success_code, loopback_device_mount = mount(value,str(key),Image_Path, outfile, mount_point) if(success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #call av_scanner function for each mount_point process_folder(mount_point, output_folder_path, outfile, "partition_offset_"+str(key), conf_file) print("We just finished scanning every file...sorting output") #unmount and remove mount points if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #delete /tmp files created for each partition if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") #close logfile outfile.close() #remove mount points created for this program if(os.path.exists(mount_point)): os.rmdir(mount_point) if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf") #run text files through unix2dos for root, dirs, files in os.walk(output_folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + quoted_full_path) #unix2dos_command = "sudo unix2dos " + "'"+filenames+"'" unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def av_scanner_mr(item_to_process, case_number, root_folder_path, evidence, conf_file): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) print("The configuration file is located at: " + conf_file) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + "MantaRay_" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path output_folder_path = root_folder_path + "/" + "AV_Scanner" check_for_folder(output_folder_path, "NONE") #open a log file for output log_file = output_folder_path + "/AV_Scanner_logfile.txt" outfile = open(log_file, 'wt+') if (item_to_process == "Single File"): print("Please put your file in a folder and then scan the folder") elif (item_to_process == "Directory"): folder_to_process = evidence_no_quotes process_folder(folder_to_process, output_folder_path, outfile, "Directory", conf_file) elif (item_to_process == "EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, output_folder_path, outfile, "LEF", conf_file) #umount if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif (item_to_process == "Bit-Stream Image"): Image_Path = evidence #process every file on every partition #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #check if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path #no_quotes_path = Image_Path.replace("'","") #print("THe no quotes path is: " + no_quotes_path) #call mount_ewf function Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") #if filesize of mmls output is 0 then run parted if (file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print( "We found a GUID partition table, need to use parted") outfile.write( "We found a GUID partition table, need to use parted\n" ) #call parted function partition_info_dict, temp_time = parted( outfile, Image_Path) mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key, value in sorted(partition_info_dict.items()): #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #call mount sub-routine success_code, loopback_device_mount = mount( value, str(key), Image_Path, outfile, mount_point) if (success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #call av_scanner function for each mount_point process_folder(mount_point, output_folder_path, outfile, "partition_offset_" + str(key), conf_file) print("We just finished scanning every file...sorting output") #unmount and remove mount points if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #delete /tmp files created for each partition if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") #close logfile outfile.close() #remove mount points created for this program if (os.path.exists(mount_point)): os.rmdir(mount_point) if (os.path.exists(mount_point + "_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf") #run text files through unix2dos for root, dirs, files in os.walk(output_folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + quoted_full_path) #unix2dos_command = "sudo unix2dos " + "'"+filenames+"'" unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def carve_unallocated_mr(item_to_process, case_number, root_folder_path, evidence, options): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) print("The options selected were: " + options) evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S") #create output folder path folder_path = root_folder_path + "/" + "Foremost" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Foremost_logfile.txt" outfile = open(log_file, 'wt+') Image_Path = evidence if(item_to_process == "Single File"): filename_to_process = evidence #set up foremost command if(not re.search('Configuration', options)): foremost_command = "foremost -d -o " + "'" + folder_path + "/" + filename_to_process + "/unallocated_files" + "'" +" -t " + str(options) + " -i " + Image_Path else: foremost_command = "foremost -d -o " + "'" + folder_path + "/" + filename_to_process + "/unallocated_files" + "'" +" -c /etc/foremost.conf -i " + Image_Path print("The foremost_command is: " + foremost_command + "\n") #for a single file we don't need to run blkls, we just need to execute the foremost command #run foremost command subprocess.call([foremost_command], shell=True) elif(item_to_process == "Bit-Stream Image"): #check if Image file is in Encase format if re.search(".E01", Image_Path): #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S") #mount_point = "/mnt/"+case_number+"_unallocated" Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) #partition_info_dict_temp, temp_time = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + str(temp_time) + ".txt") #if filesize of mmls output is 0 then run parted if(file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) #close outfile mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key,value in partition_info_dict.items(): #convert filesystem information into format required by foremost if(value == "hfs+"): value = "hfs" elif(value == "fat"): value = "fat16" #multiply key (offset) by 512 so it is in the right format for blkls key_bytes = int(key)//512 #set up blkls command to gather unallocated clusters blkls_command = "blkls -A -f " + value + " -i raw -o " + str(key_bytes) + " " + Image_Path print("The blkls command is: " + blkls_command + "\n") outfile.write("The blkls command is: " + blkls_command + "\n") #set up foremost command if(not re.search('Configuration', options)): foremost_command = "foremost -d -o " + "'" + folder_path + "/Partition_" + str(key) + "/unallocated_files" + "'" +" -t " + str(options) else: foremost_command = "foremost -d -o " + "'" + folder_path + "/Partition_" + str(key) + "/unallocated_files" + "'" +" -c /etc/foremost.conf" print("The foremost_command is: " + foremost_command + "\n") outfile.write("The foremost_command is: " + foremost_command + "\n") #set up command to pipe blkls through foremost pipe_command = blkls_command + "| " + foremost_command print("The pipe command is: " + pipe_command) outfile.write("The pipe command is: " + pipe_command) #run pipe command subprocess.call([pipe_command], shell=True) #run fdupes against output path to eliminate dupes remove_dupes_module_noask(evidence, outfile, folder_path) #close outfile outfile.close() #chdir to output foler os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True) #unmount and remove mount points if re.search(".E01", Image_Path): if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf") #delete /tmp files if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt")
def extract_registry_hives_mr(item_to_process, case_number, root_folder_path, evidence, options): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) print("The options selected were: " + options) evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "Extracted_Registry_Hives" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Extracted_Registry_Hives_logfile.txt" outfile = open(log_file, 'wt+') Image_Path = evidence #set item variable to tell functions whether data is from shadow volumes item = "NO" #check if Image file is in Encase format if re.search(".E01", Image_Path): #set mount point #mount_point = "/mnt/"+ case_number+"_ewf" Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") #if filesize of mmls output is 0 then run parted if (file_size == 0): print("mmls output was empty, running parted\n") outfile.write("mmls output was empty, running parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) block_size = get_block_size_parted(outfile, temp_time) else: #get block_size since mmls was successful block_size = get_block_size_mmls(Image_Path, outfile, temp_time) #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write( "We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict = parted(outfile, Image_Path) mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key, value in partition_info_dict.items(): #process overt registy hives if (value == "ntfs") or (value == "fat32"): if not os.path.exists(folder_path + "/Partition_" + str(key)): os.makedirs(folder_path + "/Partition_" + str(key)) #print("Just created output folder: " + folder_path + "/Partition_" + str(key)) outfile.write("Just created output folder: " + folder_path + "/Partition_" + str(key) + "\n\n") else: print("Output folder: " + folder_path + "/Partition_" + str(key) + " already exists") outfile.write("Output folder: " + folder_path + "/Partition_" + str(key) + " already exists\n\n") if (re.search("Unallocated", options)): process_unallocated_clusters(value, key, Image_Path, outfile, case_number, folder_path, block_size) if (re.search("Overt", options)): process_overt_deleted_files(value, key, Image_Path, outfile, folder_path, block_size, item, "OVERT/DELETED", temp_time) if (re.search("Shadow", options)): vssvolume_mnt = check_for_shadow_volumes( Image_Path, key, block_size, outfile, folder_path, temp_time) check_for_valid_hives(folder_path, outfile) get_hive_type(folder_path, outfile, temp_time, key) reset_registry_hive_timestamps(folder_path, outfile) else: print("This partition is not formatted NTFS or FAT32") outfile.write("This partition is not formatted NTFS or FAT32\n\n") #run fdupes against output path to eliminate dupes remove_dupes_module_noask(folder_path, outfile, str(key)) #chdir to output foler os.chdir(folder_path) #unmount and remount points if re.search(".E01", Image_Path): if (os.path.exists(mount_point + "_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf") #remove empty directories for root, dirs, files in os.walk(folder_path, topdown=False): for directory in dirs: dir_path = os.path.join(root, directory) if not os.listdir(dir_path): outfile.write("Removing empty folder: " + dir_path + "\n") os.rmdir(dir_path) #close outfiles outfile.close() #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True) #delete /tmp/ls_output.txt if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") if (os.path.exists("/tmp/timeline_partition_info_" + temp_time + ".txt")): os.remove("/tmp/timeline_partition_info_" + temp_time + ".txt") if (os.path.exists("/tmp/dump_" + temp_time + ".txt")): os.remove("/tmp/dump_" + temp_time + ".txt") if (os.path.exists("/tmp/fls_output_" + temp_time + ".txt")): os.remove("/tmp/fls_output_" + temp_time + ".txt") if (os.path.exists("/tmp/hives_to_rename_" + temp_time)): shutil.rmtree("/tmp/hives_to_rename_" + temp_time) return (folder_path)
def sa_mr(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + "MantaRay_" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "Static Malware Analysis" check_for_folder(folder_path , "NONE") #open a log file for output log_file = folder_path + "/Static_Malware_Analysis_logfile.txt" outfile = open(log_file, 'wt+') if(item_to_process == "Single File"): #get base filename to process filename = os.path.basename(evidence_no_quotes) print("The file to process is: " + filename) #make output folder for this file check_for_folder(folder_path + "/" + filename, "NONE") #run Mastiff run_mastiff(evidence, filename, folder_path, evidence_no_quotes, outfile) #run pescanner run_pescanner(evidence, filename, folder_path, evidence_no_quotes, outfile) #run pestr run_pestr(evidence, filename, folder_path, evidence_no_quotes, outfile) #run readpe run_readpe(evidence, filename, folder_path, evidence_no_quotes, outfile) #run pedump run_pedump(evidence, filename, folder_path, evidence_no_quotes, outfile) #run peframe run_peframe(evidence, filename, folder_path, evidence_no_quotes, outfile) #run signsrch run_signsrch(evidence, filename, folder_path, evidence_no_quotes, outfile) elif(item_to_process == "Directory"): folder_to_process = evidence_no_quotes #get base filename to process process_folder(folder_to_process, folder_path, evidence_no_quotes, outfile) elif(item_to_process =="EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, folder_path, evidence_no_quotes, outfile) #umount if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #remove mount points created for this program if(os.path.exists(mount_point)): os.rmdir(mount_point) if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf") #close outfile outfile.close() #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + quoted_full_path) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def volatility_mr(case_number, root_folder_path, evidence, profile_to_use): print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) #create output folder path folder_path = root_folder_path + "/" + "Volatility" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Volatility_logfile.txt" outfile = open(log_file, 'wt+') Image_Path = evidence #add quotes to image path in case of spaces quoted_path = "'" +Image_Path +"'" #allow user to use pre-selected profile name if profile_to_use == "NOPROFILESELECTED": #run first volatility command to get image type print("Checking RAM image for imageinfo information...This may take a few minutes....\n") imageinfo = subprocess.check_output(["vol -f " + quoted_path + " imageinfo"], shell=True, universal_newlines=True) print("The value of imageinfo is: " + imageinfo) outfile.write("The value of imageinfo is: " + imageinfo) #have user specify the image type profile_type = enterbox(msg="Please Enter the profile to use", title='Profile Type',default='',strip=True,image=None,root=None) print("Profile selected: " + profile_type) else: print("Using profile " + profile_to_use) profile_type = profile_to_use #run kdbgscan print("\n\n[1 of 40] Running kdbgscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") kdbgscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " kdbgscan > " + "'"+folder_path + "/" + case_number + "_kdbgscan.txt"+"'" subprocess.call([kdbgscan_command], shell=True) #run kprcscan #print("Running kprcscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") #kprcscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " kprcscan > " + "'"+folder_path + "/" + case_number + "_kprcscan.txt"+"'" #subprocess.call([kprcscan_command], shell=True) #run pslist print("\n\n[2 of 40] Running pslist.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") pslist_command = "vol --profile=" + profile_type + " -f " + quoted_path + " pslist > " + "'"+folder_path + "/" + case_number + "_pslist.txt"+"'" subprocess.call([pslist_command], shell=True) #run pstree print("\n\n[3 of 40] Running pstree.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") pstree_command = "vol --profile=" + profile_type + " -f " + quoted_path + " pstree > " + "'"+folder_path + "/" + case_number + "_pstree.txt"+"'" subprocess.call([pstree_command], shell=True) #run psscan print("\n\n[4 of 40] Running psscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") psscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " psscan > " + "'"+folder_path + "/" + case_number + "_psscan.txt"+"'" subprocess.call([psscan_command], shell=True) #run dlllist print("\n\n[5 of 40] Running dlllist.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") dlllist_command = "vol --profile=" + profile_type + " -f " + quoted_path + " dlllist > " + "'"+folder_path + "/" + case_number + "_dlllist.txt"+"'" subprocess.call([dlllist_command], shell=True) #run handles print("\n\n[6 of 40] Running handles.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") handles_command = "vol --profile=" + profile_type + " -f " + quoted_path + " handles > " + "'"+folder_path + "/" + case_number + "_handles.txt"+"'" subprocess.call([handles_command], shell=True) #run getsids print("\n\n[7 of 40] Running getsids.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") getsids_command = "vol --profile=" + profile_type + " -f " + quoted_path + " getsids > " + "'"+folder_path + "/" + case_number + "_getsids.txt"+"'" subprocess.call([getsids_command], shell=True) #run verinfo #print("Running verinfo.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") #verinfo_command = "vol --profile=" + profile_type + " -f " + quoted_path + " verinfo > " + "'"+folder_path + "/" + case_number + "_verinfo.txt"+"'" #subprocess.call([verinfo_command], shell=True) #run modules print("\n\n[8 of 40] Running modules.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") modules_command = "vol --profile=" + profile_type + " -f " + quoted_path + " modules > " + "'"+folder_path + "/" + case_number + "_modules.txt"+"'" subprocess.call([modules_command], shell=True) #run modscan print("\n\n[9 of 40] Running modscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") modscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " modscan > " + "'"+folder_path + "/" + case_number + "_modscan.txt"+"'" subprocess.call([modscan_command], shell=True) #run moddump #mkdir for moddump os.mkdir(folder_path + "/moddump/") print("\n\n[10 of 40] Running moddump.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") moddump_command = "vol --profile=" + profile_type + " -f " + quoted_path + " moddump -D " + "'" +folder_path + "/moddump/" + "'" + " > " + "'"+folder_path + "/" + case_number + "_moddump.txt"+"'" subprocess.call([moddump_command], shell=True) #run ssdt print("\n\n[11 of 40] Running ssdt.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") ssdt_command = "vol --profile=" + profile_type + " -f " + quoted_path + " ssdt > " + "'"+folder_path + "/" + case_number + "_ssdt.txt"+"'" subprocess.call([ssdt_command], shell=True) #run driverscan print("\n\n[12 of 40] Running driverscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") driverscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " driverscan > " + "'"+folder_path + "/" + case_number + "_driverscan.txt"+"'" subprocess.call([driverscan_command], shell=True) #run modscan print("\n\n[13 of 40] Running modscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") modscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " modscan > " + "'"+folder_path + "/" + case_number + "_modscan.txt"+"'" subprocess.call([modscan_command], shell=True) #run filescan print("\n\n[14 of 40] Running filescan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") filescan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " filescan > " + "'"+folder_path + "/" + case_number + "_filescan.txt"+"'" subprocess.call([filescan_command], shell=True) #run mutantscan print("\n\n[15 of 40] Running mutantscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") mutantscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " mutantscan > " + "'"+folder_path + "/" + case_number + "_mutantscan.txt"+"'" subprocess.call([mutantscan_command], shell=True) #run symlinkscan print("\n\n[16 of 40] Running symlinkscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") symlinkscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " symlinkscan > " + "'"+folder_path + "/" + case_number + "_symlinkscan.txt"+"'" subprocess.call([symlinkscan_command], shell=True) #run thrdscan print("\n\n[17 of 40] Running thrdscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") thrdscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " thrdscan > " + "'"+folder_path + "/" + case_number + "_thrdscan.txt"+"'" subprocess.call([thrdscan_command], shell=True) #run connections print("\n\n[18 of 40] Running connections.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") connections_command = "vol --profile=" + profile_type + " -f " + quoted_path + " connections > " + "'"+folder_path + "/" + case_number + "_connections.txt"+"'" subprocess.call([connections_command], shell=True) #run sockets print("\n\n[19 of 40] Running sockets.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") sockets_command = "vol --profile=" + profile_type + " -f " + quoted_path + " sockets > " + "'"+folder_path + "/" + case_number + "_sockets.txt"+"'" subprocess.call([sockets_command], shell=True) #run sockscan print("\n\n[20 of 40] Running sockscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") sockscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " sockscan > " + "'"+folder_path + "/" + case_number + "_sockscan.txt"+"'" subprocess.call([sockscan_command], shell=True) #run netscan print("\n\n[21 of 40] Running netscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") netscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " netscan > " + "'"+folder_path + "/" + case_number + "_netscan.txt"+"'" subprocess.call([netscan_command], shell=True) #run hivescan print("\n\n[22 of 40] Running hivescan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") hivescan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " hivescan > " + "'"+folder_path + "/" + case_number + "_hivescan.txt"+"'" subprocess.call([hivescan_command], shell=True) #run hivelist print("\n\n[23 of 40] Running hivelist.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") hivelist_command = "vol --profile=" + profile_type + " -f " + quoted_path + " hivelist > " + "'"+folder_path + "/" + case_number + "_hivelist.txt"+"'" subprocess.call([hivelist_command], shell=True) #run userassist print("\n\n[24 of 40] Running userassist.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") userassist_command = "vol --profile=" + profile_type + " -f " + quoted_path + " userassist > " + "'"+folder_path + "/" + case_number + "_userassist.txt"+"'" subprocess.call([userassist_command], shell=True) #run svcscan print("\n\n[25 of 40] Running svcscan.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") svcscan_command = "vol --profile=" + profile_type + " -f " + quoted_path + " svcscan > " + "'"+folder_path + "/" + case_number + "_svcscan.txt"+"'" subprocess.call([svcscan_command], shell=True) #run ldrmodules print("\n\n[26 of 40] Running ldrmodules.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") ldrmodules_command = "vol --profile=" + profile_type + " -f " + quoted_path + " ldrmodules > " + "'"+folder_path + "/" + case_number + "_ldrmodules.txt"+"'" subprocess.call([ldrmodules_command], shell=True) #run idt #print("Running idt.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") #idt_command = "vol idt -f " + quoted_path + " > " + "'"+folder_path + "/" + case_number + "_idt.txt"+"'" #subprocess.call([idt_command], shell=True) #run gdt print("\n\n[27 of 40] Running gdt.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") gdt_command = "vol gdt -f " + quoted_path + " > " + "'"+folder_path + "/" + case_number + "_gdt.txt"+"'" subprocess.call([gdt_command], shell=True) #run callbacks print("\n\n[28 of 40] Running callbacks.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") callbacks_command = "vol -f " + quoted_path + " callbacks > " + "'"+folder_path + "/" + case_number + "_callbacks.txt"+"'" subprocess.call([callbacks_command], shell=True) #run devicetree print("\n\n[29 of 40] Running devicetree.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") devicetree_command = "vol -f " + quoted_path + " devicetree > " + "'"+folder_path + "/" + case_number + "_devicetree.txt"+"'" subprocess.call([devicetree_command], shell=True) #VistaSP0x86run psxview print("\n\n[30 of 40] Running psxview.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.html) for more information\n") psxview_command = "vol -f " + quoted_path + " psxview > " + "'"+folder_path + "/" + case_number + "_psxview.txt"+"'" subprocess.call([psxview_command], shell=True) #run privs print("\n\n[31 of 40] Running privs.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") privs_command = "vol --profile=" + profile_type + " -f " + quoted_path + " privs > " + "'"+folder_path + "/" + case_number + "_privs.txt"+"'" subprocess.call([privs_command], shell=True) #run iehistory print("\n\n[32 of 40] Running devicetree.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") iehistory_command = "vol --profile=" + profile_type + " -f " + quoted_path + " iehistory > " + "'"+folder_path + "/" + case_number + "_iehistory.txt"+"'" subprocess.call([iehistory_command], shell=True) #run unloadedmodules print("\n\n[33 of 40] Running unloadedmodules.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") unloadedmodules_command = "vol --profile=" + profile_type + " -f " + quoted_path + " unloadedmodules > " + "'"+folder_path + "/" + case_number + "_unloadedmodules.txt"+"'" subprocess.call([unloadedmodules_command], shell=True) #run shellbags print("\n\n[34 of 40] Running shellbags.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") shellbags_command = "vol -f " + quoted_path + " shellbags > " + "'"+folder_path + "/" + case_number + "_shellbags.txt"+"'" subprocess.call([shellbags_command], shell=True) #run vboxinfo print("\n\n[35 of 40] Running vboxinfo.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") vboxinfo_command = "vol --profile=" + profile_type + " -f " + quoted_path + " vboxinfo > " + "'"+folder_path + "/" + case_number + "_vboxinfo.txt"+"'" subprocess.call([vboxinfo_command], shell=True) #run vmwareinfo print("\n\n[36 of 40] Running vmwareinfo.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") vmwareinfo_command = "vol -f " + quoted_path + " vmwareinfo > " + "'"+folder_path + "/" + case_number + "_vmwareinfo.txt"+"'" subprocess.call([vmwareinfo_command], shell=True) #run hpakinfo print("\n\n[37 of 40] Running hpakinfo.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") hpakinfo_command = "vol --profile=" + profile_type + " -f " + quoted_path + " hpakinfo > " + "'"+folder_path + "/" + case_number + "_hpakinfo.txt"+"'" subprocess.call([hpakinfo_command], shell=True) #run hpakextract # print("Running hpakextract.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") # hpakextract_command = "vol --profile=" + profile_type + " -f " + quoted_path + " hpakextract > " + "'"+folder_path + "/" + case_number + "_hpakextract.txt"+"'" # subprocess.call([hpakextract_command], shell=True) #run mbrparser print("\n\n[38 of 40] Running mbrparser.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") mbrparser_command = "vol --profile=" + profile_type + " -f " + quoted_path + " mbrparser > " + "'"+folder_path + "/" + case_number + "_mbrparser.txt"+"'" subprocess.call([mbrparser_command], shell=True) #run mftparser print("\n\n[39 of 40] Running mftparser.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") mftparser_command = "vol --profile=" + profile_type + " -f " + quoted_path + " mftparser > " + "'"+folder_path + "/" + case_number + "_mftparser.txt"+"'" subprocess.call([mftparser_command], shell=True) #run timeliner print("\n\n[40 of 40] Running timeliner.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") timeliner_command = "vol --profile=" + profile_type + " -f " + quoted_path + " timeliner > " + "'"+folder_path + "/" + case_number + "_timeliner.txt"+"'" subprocess.call([timeliner_command], shell=True) #run dumpcerts #print("Running dumpcerts.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") #dumpcerts_command = "vol --profile=" + profile_type + " -f " + quoted_path + " dumpcerts > " + "'"+folder_path + "/" + case_number + "_dumpcerts.txt"+"'" #subprocess.call([dumpcerts_command], shell=True) #run dumpfiles #try: # os.mkdir(folder_path + "/dumpfiles") # print("Running dumpfiles.\nSee Volatility Commands reference data (/usr/local/src/Manta_Ray/docs/VolatilityUsage23.rst) for more information\n") # dumpfiles_command = "vol --profile=" + profile_type + " -f " + quoted_path + " dumpfiles --dump-dir " + "'"+folder_path + "/dumpfiles"+"'" # subprocess.call([dumpfiles_command], shell=True) #except: # print("Dumpdirs failed. Please report to MantaRay Forums at MantaRayForensics.com") # outfile.write("\n#######\nDumpdirs failed. Please report to MantaRay Forums at MantaRayForensics.com\n#######\n") #run timers #print("Running timers.\nSee Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n") #timers_command = "vol --profile=" + profile_type + " -f " + quoted_path + " timers > " + "'"+folder_path + "/" + case_number + "_timers.txt"+"'" #subprocess.call([timers_command], shell=True) #close outfile outfile.close() #change dir into output folder os.chdir(folder_path) #run unix2dos on text files unix2dos_command = "sudo unix2dos *.txt" subprocess.call([unix2dos_command], shell=True)
def volatility_mr(case_number, root_folder_path, evidence, selected_profile, selected_plugin, selected_plugin_descr, complete_plugin_list): ###Debug testing code### #print("The case_name is: " + case_number) #print("The output folder is: " + root_folder_path) #print("The evidence to process is: " + evidence) #create output folder path folder_path = root_folder_path + "/" + "Volatility" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Volatility_logfile.txt" outfile = open(log_file, 'wt+') Image_Path = evidence #add quotes to image path in case of spaces quoted_path = "'" + Image_Path + "'" #See Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n #start reporting lists####Still needs development; not being used at this time... win_plugins_complete = [] win_plugins_not_supported = [] win_plugins_skipped = [] win_plugins_error = [] ###debug printing### #print("This is selected_plugin type:\n",type(selected_plugin)) #print("This is selected_plugin:\n",selected_plugin) #print("This is selected_plugin_descr:\n",selected_plugin_descr) #print banner - MR print("\nMantaRay > " + version) print("mantarayforensics.com/forums/") print("*****@*****.**") print("github.com/mantarayforensics/mantaray\n") #print banner - Vol print("Volatility v2.4") print("volatilityfoundation.org") print("volatility-labs.blogspot.com") print("github.com/volatilityfoundation/volatility\n") print("Processing requested plugins:") #run selected plugins for plugin in selected_plugin: if plugin in suppress_list: num_index = complete_plugin_list.index(plugin) #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] print("\nRunning " + plugin + "...") print(descr + "...") print("The plugin " + plugin + " is not supported...") print("This plugin has advanced features. Run manually...") outfile.write("The plugin " + plugin + " is not supported...\n") outfile.write( "This plugin has advanced features. Run manually...\n\n") win_plugins_not_supported.append(plugin) continue if plugin in plugin_not_currently_supported: num_index = complete_plugin_list.index(plugin) #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] print("\nRunning " + plugin + "...") print(descr + "...") print("The plugin " + plugin + " is not currently supported...") print("Support may be added in a future release...") print("Check GitHub for updates...") print("github.com/mantarayforensics/mantaray") print("Currently running:", version) outfile.write("The plugin " + plugin + " is not currently supported.\n") outfile.write("Support may be added in a future release.\n") outfile.write("Check GitHub for updates...\n") outfile.write("github.com/mantarayforensics/mantaray\n") outfile.write("The plugin was skipped.\n\n") win_plugins_skipped.append(plugin) continue if plugin == 'pstotal': num_index = complete_plugin_list.index('pstotal') #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] plugin = 'pstotal.dot.full-graph' print("\nRunning pstotal...") pstotal_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path \ + " pstotal --output=dot > " + "'" + folder_path + \ "/pstotal.dot.full-graph.txt" + "'" print("Processing DOT output for full process graph...") output = Popen([pstotal_command], shell=True, stderr=PIPE) error_logging(outfile, folder_path, selected_profile, plugin, output, win_plugins_error) pstotal_hidden_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path \ + " pstotal --output=dot -S -C > " + "'" + folder_path + \ "/pstotal.dot.hidden-only-graph.txt" + "'" print("Processing DOT output for only hidden process graph...") output = Popen([pstotal_hidden_command], shell=True, stderr=PIPE) plugin = 'pstotal.dot.hidden-only-graph' error_logging(outfile, folder_path, selected_profile, plugin, output, win_plugins_error) pstotal_text_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path + \ " pstotal --output=text > " + "'" + folder_path + \ "/pstotal.text-only.txt" + "'" print("Processing text output for hidden processes...") output = Popen([pstotal_text_command], shell=True, stderr=PIPE) plugin = 'pstotal.text-only' error_logging(outfile, folder_path, selected_profile, plugin, output, win_plugins_error) pstotal_graphviz_command1 = "dot -Tpng " + "'" + folder_path + "/pstotal.dot.full-graph.txt" \ + "'" + " -o " + "'" + folder_path + \ "/pstotal.dot.full-graph.png" + "'" print("Running Graphviz to create full graph (PNG)...") output = Popen([pstotal_graphviz_command1], shell=True, stderr=PIPE) plugin = 'pstotal.dot.full-graph' error_logging(outfile, folder_path, selected_profile, plugin, output, win_plugins_error) pstotal_graphviz_command2 = "dot -Tpng " + "'" + folder_path + "/pstotal.dot.hidden-only-graph.txt" \ + "'" + " -o " + "'" + folder_path + \ "/pstotal.dot.hidden-only-graph.png" + "'" print("Running Graphviz to create hidden graph (PNG)...") output = Popen([pstotal_graphviz_command2], shell=True, stderr=PIPE) plugin = 'pstotal.dot.hidden-only-graph' error_logging(outfile, folder_path, selected_profile, plugin, output, win_plugins_error) plugin = 'pstotal' win_plugins_complete.append(plugin) continue xp_2003_only_plugins = ['connections', 'evtlogs'] if plugin in xp_2003_only_plugins: if re.search('XP', selected_profile): print("\nRunning [Windows XP and 2003 Only] plugin...") elif re.search('2003', selected_profile): print("\nRunning [Windows XP and 2003 Only] plugin...") else: continue xp_only_plugins = ['sockets', 'sockscan'] if plugin in xp_only_plugins: if re.search('XP', selected_profile): print("\nRunning [Windows XP Only] plugin...") else: continue vista_and_newer_only_plugins = ['netscan', 'pooltracker'] if plugin in vista_and_newer_only_plugins: os_support = ['Vista', 'Win7', 'Win8'] for os_type in os_support: if re.search(os_type, selected_profile): print("\nRunning Vista and newer only plugin...") else: continue ####ADD NEW MODULE#### #elif plugin == <plugin name>: # print("\nRunning " + plugin + "...") # <plugin name>_command = "vol.py -f " + quoted_path + plugin + " > " \ # + "'" + folder_path + "/<plugin name>.txt"+"'" # output = Popen([<plugin name>_command], shell=True, stderr=PIPE) # error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) # win_plugins_complete.append('devicetree') try: num_index = complete_plugin_list.index(plugin) #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] print("\nRunning " + plugin + "...") print(descr) #print("This is plugin:\n",plugin) processing_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path + " " + plugin + " > " \ + "'" + folder_path + "/" + plugin + ".txt"+"'" #print("Vol Processing Command:",processing_command) output = Popen([processing_command], shell=True, stderr=PIPE) error_logging(outfile, folder_path, selected_profile, plugin, output, win_plugins_error) win_plugins_complete.append(plugin) except OSError as error: print("The plugin " + pluin + "experienced an OSError and failed, see log file...\n") outfile.write("The plugin " + plugin + " experienced an OSError and failed.\n") outfile.write(error + "\n") #close outfile outfile.close() #change permissions (option) #chmod_command = "chmod -R 777 " + root_folder_path #subprocess.call([chmod_command], shell=True) #change dir into output folder os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def process_single_file(evidence, outfile, folder_path, key, outfile3): #initialize variables lat_long = [] files_of_interest = {} files_of_interest_list = [] #get file extension fileName, fileExtension = os.path.splitext(evidence) print("The filename is: " + fileName) print("The fileext is: " + fileExtension) filenames = fileName + fileExtension quoted_full_path = '"' + evidence + '"' if (fileExtension.lower() == ".jpg") or (fileExtension.lower() == ".jpeg"): exiftool_command = "exiftool -ext " + fileExtension.lower( ) + " " + quoted_full_path + " | grep 'GPS Position'" result = subprocess.call([exiftool_command], shell=True) if (result): print("No GPS Data in file: " + filenames) else: #create output folder for processed files check_for_folder(folder_path + "/Processed_files_" + str(key), outfile) check_for_folder( folder_path + "/Processed_files_" + str(key) + "/GPS_DATA", outfile) #check to see if kml file exists if (os.path.isfile(folder_path + "/Processed_files_" + str(key) + "/GPS_DATA/" + "GPS_EXIF_data.kml")): print("KML file already exists") else: #chdir to output folder os.chdir(folder_path + "/Processed_files_" + str(key) + "/GPS_DATA") kml = simplekml.Kml() #copy file with exifdata to output folder #shutil.copyfile(evidence, folder_path + "/Processed_files_" + str(key) + "/GPS_DATA/" + filenames) #call exiftool again and capture the lat long information into a list (longitude, latitude) = convert_dms_to_decimal(quoted_full_path, fileExtension.lower()) print("The latitude is: " + str(latitude)) print("The longitude is: " + str(longitude)) #add data to kml file kml.newpoint(name=filenames, coords=[(latitude, longitude)]) #save kml file kml.save("GPS_EXIF_data.kml") #add filename to list files_of_interest_list.append(filenames) #get filesize file_size = os.path.getsize(evidence) file_size = int(file_size) // 1024 #calculate MD5 value of file md5value = subprocess.check_output( ["md5sum " + quoted_full_path + "| awk '{print $1}'"], shell=True, universal_newlines=True) md5value = md5value.strip() outfile3.write(quoted_full_path + "\t" + md5value + "\t" + str(file_size) + "\n")
def mr_registry(case_number, folder_to_process, root_folder_path): print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) #get datetime now = datetime.datetime.now() temp_time = now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "RegRipper" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/RegRipper_logfile.txt" outfile = open(log_file, 'wt+') #set path to text files containing plugins to run for each hive type sam_plugins = "/usr/share/regripper/plugins/sam" ntuser_plugins = "/usr/share/regripper/plugins/ntuser-all" system_plugins = "/usr/share/regripper/plugins/system" software_plugins = "/usr/share/regripper/plugins/software" usrclass_plugins = "/usr/share/regripper/plugins/usrclass-all" security_plugins = "/usr/share/regripper/plugins/security" #read filename and atime into dictionary file_metadata = {} #run ls command against folder containing registry hives f = open('/tmp/ls_output_' + temp_time + '.txt', 'wt') os.chdir(folder_to_process) ls_command = "ls -lt -ur | awk '{print $9, $10}'" print("The ls_command is: " + ls_command) try: subprocess.call([ls_command], shell=True, stdout=f, stderr=subprocess.STDOUT) f.close() except: print("Call to ls command failed") f.close() #read infile and process each file from oldest to youngest based on atime f = open('/tmp/ls_output_' + temp_time + '.txt', 'rt') for line in f: line = line.strip() file_name = line abs_file_path = os.path.join(folder_to_process, file_name) #process hives in ascending order based on atime if (re.search("USRCLASS", file_name)): print("About to process file: " + file_name) process_usrclass(abs_file_path, usrclass_plugins, file_name, folder_path, outfile) elif (re.search("NTUSER", file_name)): print("About to process file: " + file_name) process_ntuser(abs_file_path, ntuser_plugins, file_name, folder_path, outfile) elif (re.search("SAM", file_name)): hive_name_info = "SAM_INFO" process_other_hives(abs_file_path, sam_plugins, file_name, hive_name_info, folder_path, outfile) elif (re.search("SOFTWARE", file_name)): hive_name_info = "SOFTWARE_INFO" process_other_hives(abs_file_path, software_plugins, file_name, hive_name_info, folder_path, outfile) elif (re.search("SYSTEM", file_name)): hive_name_info = "SYSTEM_INFO" process_other_hives(abs_file_path, system_plugins, file_name, hive_name_info, folder_path, outfile) elif (re.search("SECURITY", file_name)): hive_name_info = "SECURITY_INFO" process_other_hives(abs_file_path, security_plugins, file_name, hive_name_info, folder_path, outfile) f.close() #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True) #close outfile outfile.close() #delete /tmp/ls_output.txt if (os.path.exists("/tmp/ls_output_" + temp_time + ".txt")): os.remove("/tmp/ls_output_" + temp_time + ".txt")
def jumplist_mr(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S") #create output folder path folder_path = root_folder_path + "/" + "Jumplist_Parser" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Jumplist_Parser_logfile.txt" outfile = open(log_file, 'wt+') #select image to process Image_Path = evidence print("The image path is: " + Image_Path) #check to see if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path no_quotes_path = Image_Path.replace("'","") print("The no quotes path is: " + no_quotes_path) #call mount_ewf function Image_Path = mount_ewf(no_quotes_path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time +".txt") print("The filesize is: " + str(file_size)) #if filesize of mmls output is 0 then run parted if(file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) #for key,value in partition_info_dict.items(): for key,value in sorted(partition_info_dict.items()): #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #run mount command success_code, loopback_device_mount = mount(value,key,Image_Path, outfile, mount_point) if(success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + ".\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #run jl.pl against every JumpList file found under mount_point if filesystem is fat32 or ntfs if(value == "ntfs") or (value=="fat32"): for root, dirs, files in os.walk(mount_point): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".automaticdestinations-ms"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Processing Jump List: " + filenames) outfile.write("Processing Jump List: " + filenames + "\n") #get profile name profile = get_account_profile_names(full_path, outfile) print("The profile is: " + profile) outfile.write("The profile is: " + profile + "\n") #process Jumplist files with jl.pl #jl_command = "perl /usr/share/windows-perl/jl.pl -u " + "'" + profile + "'" + " -f " + full_path + " >> " + "'" + folder_path + "/jumplist_metadata.txt" + "'" jl_command_tln = "perl /usr/share/windows-perl/jl.pl -u " + "'" + profile + "'" + " -t -f " + quoted_full_path + " >> " + "'" + folder_path + "/jumplist_metadata_tln.txt" + "'" outfile.write("The jl_command_tln is: " + jl_command_tln + "\n") subprocess.call([jl_command_tln], shell=True) else: print("Scanning file: " + filenames + ". This file is not a jumplist.") #unmount and remove mount points if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) else: print("Filesystem: " + value + " at offset:" + str(key) + " is not NTFS or FAT32") outfile.write("Filesystem: " + value + " at offset:" + str(key) + " is not NTFS or FAT32\n") if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #create timeline parse_command = "perl /usr/share/windows-perl/parse.pl -f " + "'" + folder_path + "/jumplist_metadata_tln.txt" + "'" + "> " + "'" + folder_path + "/jumplist_timeline.txt" + "'" subprocess.call([parse_command], shell=True) #unmount and remove mount points #if(os.path.exists(mount_point)): # os.rmdir(mount_point) if(os.path.exists(mount_point+"_ewf")): print("Unmounting mount point for ewf before exiting\n\n") subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf") #program cleanup outfile.close() #convert outfile using unix2dos #chdir to output foler os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + "'"+filenames+"'" subprocess.call([unix2dos_command], shell=True)
def entropy_mr(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + "MantaRay_" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "Entropy" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Entropy_logfile.txt" outfile = open(log_file, 'wt+') #open file to write output exp_file = folder_path + "/" + case_number +"_entropy.csv" export_file = open(exp_file, 'a+', encoding='latin-1', errors="ignore") #export_file = open(exp_file, 'a') if(item_to_process == "Single File"): ent = calc_entropy(evidence) print(ent) elif(item_to_process == "Directory"): folder_to_process = evidence_no_quotes process_folder(folder_to_process, export_file, outfile) elif(item_to_process =="EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, export_file, outfile) #umount if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif(item_to_process == "Bit-Stream Image"): Image_Path = evidence #process every file on every partition #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #check if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path #no_quotes_path = Image_Path.replace("'","") #print("THe no quotes path is: " + no_quotes_path) #call mount_ewf function Image_Path = mount_ewf(Image_Path, outfile,mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") #if filesize of mmls output is 0 then run parted if(file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key,value in sorted(partition_info_dict.items()): #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #call mount sub-routine success_code, loopback_device_mount = mount(value,str(key),Image_Path, outfile, mount_point) if(success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #call entropy function for each mount_point process_folder(mount_point, export_file, outfile) print("We just finished calculating the entropy for every file...sorting output") #unmount and remove mount points if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #delete /tmp files created for each partition if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") #close output file export_file.close() #sort output file sort_command = "strings -a " + "'" + exp_file + "'" + " |sort -t\| -r -k 2n > " + "'" + folder_path + "'" + "/" + case_number +"_entropy_sorted.csv" subprocess.call([sort_command], shell=True) #write header row to export_file #sed_command = "sed -i '1i\ Entropy,File Name,File Size,MD5,File Path' " + "'" + folder_path + "'" + "/" + case_number +"_entropy_sorted.csv" sed_command = "sed -i '1i\ Entropy,File Name,File Size,FilePath' " + "'" + folder_path + "'" + "/" + case_number +"_entropy_sorted.csv" subprocess.call([sed_command], shell=True) #remove original output file os.remove(exp_file) #remove mount points created for this program if(os.path.exists(mount_point)): os.rmdir(mount_point) if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf")
def extract_registry_hives_mr(item_to_process, case_number, root_folder_path, evidence, options): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) print("The options selected were: " + options) evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "Extracted_Registry_Hives" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Extracted_Registry_Hives_logfile.txt" outfile = open(log_file, 'wt+') Image_Path = evidence #set item variable to tell functions whether data is from shadow volumes item = "NO" #check if Image file is in Encase format if re.search(".E01", Image_Path): #set mount point #mount_point = "/mnt/"+ case_number+"_ewf" Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time +".txt") #if filesize of mmls output is 0 then run parted if(file_size == 0): print("mmls output was empty, running parted\n") outfile.write("mmls output was empty, running parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) block_size = get_block_size_parted(outfile, temp_time) else: #get block_size since mmls was successful block_size = get_block_size_mmls(Image_Path, outfile, temp_time) #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict = parted(outfile, Image_Path) mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key,value in partition_info_dict.items(): #process overt registy hives if(value =="ntfs") or (value=="fat32"): if not os.path.exists(folder_path + "/Partition_" + str(key)): os.makedirs(folder_path + "/Partition_" + str(key)) #print("Just created output folder: " + folder_path + "/Partition_" + str(key)) outfile.write("Just created output folder: " + folder_path + "/Partition_" + str(key) + "\n\n") else: print("Output folder: " + folder_path +"/Partition_" + str(key) + " already exists") outfile.write("Output folder: " + folder_path +"/Partition_" + str(key) + " already exists\n\n") if(re.search("Unallocated", options)): process_unallocated_clusters(value, key, Image_Path, outfile, case_number, folder_path, block_size) if(re.search("Overt", options)): process_overt_deleted_files(value, key, Image_Path, outfile, folder_path, block_size, item, "OVERT/DELETED", temp_time) if(re.search("Shadow", options)): vssvolume_mnt = check_for_shadow_volumes(Image_Path, key, block_size, outfile, folder_path, temp_time) check_for_valid_hives(folder_path, outfile) get_hive_type(folder_path, outfile, temp_time, key) reset_registry_hive_timestamps(folder_path, outfile) else: print("This partition is not formatted NTFS or FAT32") outfile.write("This partition is not formatted NTFS or FAT32\n\n") #run fdupes against output path to eliminate dupes remove_dupes_module_noask(folder_path, outfile, str(key)) #chdir to output foler os.chdir(folder_path) #unmount and remount points if re.search(".E01", Image_Path): if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf") #remove empty directories for root, dirs, files in os.walk(folder_path, topdown = False): for directory in dirs: dir_path = os.path.join(root, directory) if not os.listdir(dir_path): outfile.write("Removing empty folder: " + dir_path + "\n") os.rmdir(dir_path) #close outfiles outfile.close() #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True) #delete /tmp/ls_output.txt if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") if (os.path.exists("/tmp/timeline_partition_info_" + temp_time +".txt")): os.remove("/tmp/timeline_partition_info_" + temp_time +".txt") if (os.path.exists("/tmp/dump_" + temp_time + ".txt")): os.remove("/tmp/dump_" + temp_time + ".txt") if (os.path.exists("/tmp/fls_output_" + temp_time + ".txt")): os.remove("/tmp/fls_output_" + temp_time + ".txt") if (os.path.exists("/tmp/hives_to_rename_" + temp_time)): shutil.rmtree("/tmp/hives_to_rename_" + temp_time) return(folder_path)
def filename_search_mr(item_to_process, case_number, root_folder_path, evidence, searchfile): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S") #create output folder path folder_path = root_folder_path + "/" + "Filename_Search" check_for_folder(folder_path, "NONE") #create Log Folder log_folder_path = folder_path + "/" + "Filename_Logs" check_for_folder(log_folder_path, "NONE") #open a log file for output log_file = log_folder_path + "/Filename_Search_Log.txt" outfile = open(log_file, 'wt+') Image_Path = '"' + evidence + '"' #set item variable to tell functions whether data is from shadow volumes item = "NO" #check if Image file is in Encase format if re.search(".E01", Image_Path): #set mount point mount_point = "/mnt/" + case_number + "_unallocated" Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") #if filesize of mmls output is 0 then run parted if (file_size == 0): print("mmls output was empty, running parted\n") outfile.write("mmls output was empty, running parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) block_size = get_block_size_parted(outfile, temp_time) else: #get block_size since mmls was successful block_size = get_block_size_mmls(Image_Path, outfile) #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write( "We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key, value in partition_info_dict.items(): #process overt registy hives if (value == "ntfs") or (value == "fat32"): if not os.path.exists(folder_path + "/Partition_" + str(key)): os.makedirs(folder_path + "/Partition_" + str(key)) #print("Just created output folder: " + folder_path + "/Partition_" + str(key)) outfile.write("Just created output folder: " + folder_path + "/Partition_" + str(key) + "\n\n") else: print("Output folder: " + folder_path + "/Partition_" + str(key) + " already exists") outfile.write("Output folder: " + folder_path + "/Partition_" + str(key) + " already exists\n\n") #chande output dir out_folder = folder_path + "/Partition_" + str(key) process_overt_deleted_files(value, key, Image_Path, outfile, folder_path, log_folder_path, out_folder, block_size, item, temp_time, searchfile) vssvolume_mnt = check_for_shadow_volumes( Image_Path, key, block_size, outfile, folder_path, log_folder_path, out_folder, temp_time, searchfile) else: print("This partition is not formatted NTFS or FAT32") outfile.write("This partition is not formatted NTFS or FAT32\n\n") #run fdupes against output path to eliminate dupes remove_dupes_module_noask(folder_path, outfile, str(key)) shutil.copyfile("/tmp/fdupes_duplicates_log.txt", log_folder_path + "/fdupes_duplicates_log.txt") #chdir to output foler os.chdir(folder_path) #unmount shadow volumes if (vssvolume_mnt != "NULL"): print("Unmounting: " + vssvolume_mnt) outfile.write("Unmounting: " + vssvolume_mnt + "\n") subprocess.call(['sudo umount -f ' + vssvolume_mnt], shell=True) os.rmdir(vssvolume_mnt) #unmount and remount points if re.search(".E01", Image_Path): if (os.path.exists(mount_point + "_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf") #remove empty directories for root, dirs, files in os.walk(folder_path, topdown=False): for directory in dirs: dir_path = os.path.join(root, directory) if not os.listdir(dir_path): outfile.write("Removing empty folder: " + dir_path + "\n") os.rmdir(dir_path) #close outfiles outfile.close() #add md5 later # for root, dirs, files in os.walk(folder_path): # for f in files: # current_file = os.path.join(root,f) # H = hashlib.md5() # with open(current_file) as FIN: # H.update(FIN.read().encode('utf8')) # out_prep = current_file + H.hexdigest() # md5out.write(out_prep) # md5out.close() #delete temp files #os.remove('/tmp/fls_output_ntfs_' + temp_time + '.txt') #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def volatility_mr(case_number, root_folder_path, evidence, selected_profile, selected_plugin, selected_plugin_descr, complete_plugin_list): ###Debug testing code### #print("The case_name is: " + case_number) #print("The output folder is: " + root_folder_path) #print("The evidence to process is: " + evidence) #create output folder path folder_path = root_folder_path + "/" + "Volatility" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Volatility_logfile.txt" outfile = open(log_file, 'wt+') Image_Path = evidence #add quotes to image path in case of spaces quoted_path = "'" + Image_Path + "'" #See Volatility Commands reference data (/usr/share/mantaray/docs/VolatilityUsage23.rst) for more information\n #start reporting lists####Still needs development; not being used at this time... win_plugins_complete = [] win_plugins_not_supported = [] win_plugins_skipped = [] win_plugins_error = [] ###debug printing### #print("This is selected_plugin type:\n",type(selected_plugin)) #print("This is selected_plugin:\n",selected_plugin) #print("This is selected_plugin_descr:\n",selected_plugin_descr) #print banner - MR print("\nMantaRay > " + version) print("mantarayforensics.com/forums/") print("*****@*****.**") print("github.com/mantarayforensics/mantaray\n") #print banner - Vol print("Volatility v2.4") print("volatilityfoundation.org") print("volatility-labs.blogspot.com") print("github.com/volatilityfoundation/volatility\n") print("Processing requested plugins:") #run selected plugins for plugin in selected_plugin: if plugin in suppress_list: num_index = complete_plugin_list.index(plugin) #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] print("\nRunning " + plugin + "...") print(descr + "...") print("The plugin " + plugin + " is not supported...") print("This plugin has advanced features. Run manually...") outfile.write("The plugin " + plugin + " is not supported...\n") outfile.write("This plugin has advanced features. Run manually...\n\n") win_plugins_not_supported.append(plugin) continue if plugin in plugin_not_currently_supported: num_index = complete_plugin_list.index(plugin) #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] print("\nRunning " + plugin + "...") print(descr + "...") print("The plugin " + plugin + " is not currently supported...") print("Support may be added in a future release...") print("Check GitHub for updates...") print("github.com/mantarayforensics/mantaray") print("Currently running:",version) outfile.write("The plugin " + plugin + " is not currently supported.\n") outfile.write("Support may be added in a future release.\n") outfile.write("Check GitHub for updates...\n") outfile.write("github.com/mantarayforensics/mantaray\n") outfile.write("The plugin was skipped.\n\n") win_plugins_skipped.append(plugin) continue if plugin == 'pstotal': num_index = complete_plugin_list.index('pstotal') #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] plugin = 'pstotal.dot.full-graph' print("\nRunning pstotal...") pstotal_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path \ + " pstotal --output=dot > " + "'" + folder_path + \ "/pstotal.dot.full-graph.txt" + "'" print("Processing DOT output for full process graph...") output = Popen([pstotal_command], shell=True, stderr=PIPE) error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) pstotal_hidden_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path \ + " pstotal --output=dot -S -C > " + "'" + folder_path + \ "/pstotal.dot.hidden-only-graph.txt" + "'" print("Processing DOT output for only hidden process graph...") output = Popen([pstotal_hidden_command], shell=True, stderr=PIPE) plugin = 'pstotal.dot.hidden-only-graph' error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) pstotal_text_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path + \ " pstotal --output=text > " + "'" + folder_path + \ "/pstotal.text-only.txt" + "'" print("Processing text output for hidden processes...") output = Popen([pstotal_text_command], shell=True, stderr=PIPE) plugin = 'pstotal.text-only' error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) pstotal_graphviz_command1 = "dot -Tpng " + "'" + folder_path + "/pstotal.dot.full-graph.txt" \ + "'" + " -o " + "'" + folder_path + \ "/pstotal.dot.full-graph.png" + "'" print("Running Graphviz to create full graph (PNG)...") output = Popen([pstotal_graphviz_command1], shell=True, stderr=PIPE) plugin = 'pstotal.dot.full-graph' error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) pstotal_graphviz_command2 = "dot -Tpng " + "'" + folder_path + "/pstotal.dot.hidden-only-graph.txt" \ + "'" + " -o " + "'" + folder_path + \ "/pstotal.dot.hidden-only-graph.png" + "'" print("Running Graphviz to create hidden graph (PNG)...") output = Popen([pstotal_graphviz_command2], shell=True, stderr=PIPE) plugin = 'pstotal.dot.hidden-only-graph' error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) plugin = 'pstotal' win_plugins_complete.append(plugin) continue xp_2003_only_plugins = ['connections', 'evtlogs'] if plugin in xp_2003_only_plugins: if re.search('XP', selected_profile): print("\nRunning [Windows XP and 2003 Only] plugin...") elif re.search('2003', selected_profile): print("\nRunning [Windows XP and 2003 Only] plugin...") else: continue xp_only_plugins = ['sockets','sockscan'] if plugin in xp_only_plugins: if re.search('XP', selected_profile): print("\nRunning [Windows XP Only] plugin...") else: continue vista_and_newer_only_plugins = ['netscan','pooltracker'] if plugin in vista_and_newer_only_plugins: os_support = ['Vista','Win7','Win8'] for os_type in os_support: if re.search(os_type, selected_profile): print("\nRunning Vista and newer only plugin...") else: continue ####ADD NEW MODULE#### #elif plugin == <plugin name>: # print("\nRunning " + plugin + "...") # <plugin name>_command = "vol.py -f " + quoted_path + plugin + " > " \ # + "'" + folder_path + "/<plugin name>.txt"+"'" # output = Popen([<plugin name>_command], shell=True, stderr=PIPE) # error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) # win_plugins_complete.append('devicetree') try: num_index = complete_plugin_list.index(plugin) #print("This is num_index:",num_index) descr = selected_plugin_descr[num_index] print("\nRunning " + plugin + "...") print(descr) #print("This is plugin:\n",plugin) processing_command = "vol.py --profile=" + selected_profile + " -f " + quoted_path + " " + plugin + " > " \ + "'" + folder_path + "/" + plugin + ".txt"+"'" #print("Vol Processing Command:",processing_command) output = Popen([processing_command], shell=True, stderr=PIPE) error_logging(outfile,folder_path,selected_profile,plugin,output,win_plugins_error) win_plugins_complete.append(plugin) except OSError as error: print("The plugin " + pluin + "experienced an OSError and failed, see log file...\n") outfile.write("The plugin " + plugin + " experienced an OSError and failed.\n") outfile.write(error + "\n") #close outfile outfile.close() #change permissions (option) #chmod_command = "chmod -R 777 " + root_folder_path #subprocess.call([chmod_command], shell=True) #change dir into output folder os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def be_mr(item_to_process, case_number, folder_path, evidence, whitelist_location, speed, keyword_list): evidence = "'" + evidence + "'" speed = speed.strip() #calculate number of processors to use (Speed-Slow, Speed-Fast, Speed-Med calc_cores_command = "cat /proc/cpuinfo | grep processor | wc -l" num_of_cores = subprocess.check_output([calc_cores_command], shell=True) num_of_cores = num_of_cores.decode(encoding='UTF-8') num_of_cores = num_of_cores.strip() print("This VM has " + str(num_of_cores) +" cores") if(num_of_cores == "1"): cores_to_use = 1 elif(speed == "Speed-Slow"): cores_to_use = 1 elif(speed == "Speed-Med"): cores_to_use = int(num_of_cores)//2 elif(speed == "Speed-Fast"): cores_to_use = num_of_cores print("Item to process is: " + item_to_process) print("Case number is: " + case_number) print("Output folder is: " + folder_path) print("Evidence type is: " + evidence) print("Whitelist location is: " + whitelist_location) print("Processing speed is: " + speed) print("Keyword list is: " + keyword_list) #open a log file for output #log_file = folder_path + "/" + case_number + "_logfile.txt" #outfile = open(log_file, 'a') #add subfolder to output path so BE has empty folder to write to folder_path_be = "'" + folder_path +"/Bulk_Extractor_Results'" check_for_folder(folder_path_be, "NONE") if(item_to_process == "Directory"): process_folder(evidence, folder_path_be, whitelist_location, speed, "NONE", keyword_list, cores_to_use) elif(item_to_process == "EnCase Logical Evidence File"): mount_point = mount_encase_v6_l01(case_number, evidence, "NONE") process_folder(mount_point, folder_path_be, whitelist_location, speed, "NONE", keyword_list, cores_to_use) elif(item_to_process == "Single File") or (item_to_process == "Memory Image") or (item_to_process == "EnCase Logical Evidence File"): #set up bulk extractor command if(whitelist_location != "NONE") and (keyword_list == "NONE"): be_command = "bulk_extractor -o " + folder_path_be + " -w " + whitelist_location + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list =="NONE"): be_command = "bulk_extractor -o " + folder_path_be + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location != "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -o " + folder_path_be + " -w " + whitelist_location + " -x find l -F " + keyword_list + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -o " + folder_path_be + " -x find -F " + keyword_list + " -j " + str(cores_to_use) + " " + evidence #outfile.write("The be_command is: " + be_command + "\n") #run be_command print("The be command is: " + be_command) subprocess.call([be_command], shell=True) elif(item_to_process == "Bit-Stream Image"): #set up bulk extractor command if(whitelist_location != "NONE") and (keyword_list == "NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + " -w " + whitelist_location + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list =="NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location != "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + " -w " + whitelist_location + " -x find -F " + keyword_list + " -j " + str(cores_to_use) + " " + evidence elif(whitelist_location == "NONE") and (keyword_list != "NONE"): be_command = "bulk_extractor -C 60 -o " + folder_path_be + " -x find -F " + keyword_list + " -j " + str(cores_to_use) + " " + evidence #run be_command print("The be command is: " + be_command) subprocess.call([be_command], shell=True) #run fiwalk fiwalk_command = "fiwalk -x " + evidence + " >" + '"' + folder_path + "/Bulk_Extractor_Results/fiwalk_output.xml" + "'" print("Running fiwalk: " + fiwalk_command) subprocess.call([fiwalk_command], shell=True) #run identify_filenames.py identify_filenames_command = "python3 /usr/share/bulk_extractor/python/identify_filenames.py --all --imagefile " + evidence + " --xmlfile " + '"' + folder_path + "/Bulk_Extractor_Results/fiwalk_output.xml" + '"' + " " + '"' + folder_path + "/Bulk_Extractor_Results" + '"' + " " + '"' + folder_path + "/Bulk_Extractor_Results/annotated_results/" + '"' print("Running identify_filenames.py: " + identify_filenames_command) subprocess.call([identify_filenames_command], shell=True) #chdir to output foler os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path + "/Bulk_Extractor_Results/"): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + quoted_full_path) #unix2dos_command = "sudo unix2dos " + "'"+filenames+"'" unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)
def mr_registry(case_number, folder_to_process, root_folder_path): print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) #get datetime now = datetime.datetime.now() temp_time = now.strftime("%Y-%m-%d_%H_%M_%S_%f") #create output folder path folder_path = root_folder_path + "/" + "RegRipper" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/RegRipper_logfile.txt" outfile = open(log_file, 'wt+') #set path to text files containing plugins to run for each hive type sam_plugins = "/usr/share/regripper/plugins/sam" ntuser_plugins = "/usr/share/regripper/plugins/ntuser-all" system_plugins = "/usr/share/regripper/plugins/system" software_plugins = "/usr/share/regripper/plugins/software" usrclass_plugins = "/usr/share/regripper/plugins/usrclass-all" security_plugins = "/usr/share/regripper/plugins/security" #read filename and atime into dictionary file_metadata = {} #run ls command against folder containing registry hives f = open('/tmp/ls_output_' + temp_time + '.txt', 'wt') os.chdir(folder_to_process) ls_command = "ls -lt -ur | awk '{print $9, $10}'" print("The ls_command is: " + ls_command) try: subprocess.call([ls_command], shell=True, stdout = f, stderr=subprocess.STDOUT) f.close() except: print("Call to ls command failed") f.close() #read infile and process each file from oldest to youngest based on atime f = open('/tmp/ls_output_' + temp_time + '.txt', 'rt') for line in f: line = line.strip() file_name = line abs_file_path = os.path.join(folder_to_process,file_name) #process hives in ascending order based on atime if(re.search("USRCLASS", file_name)): print("About to process file: " + file_name) process_usrclass(abs_file_path, usrclass_plugins, file_name, folder_path, outfile) elif(re.search("NTUSER", file_name)): print("About to process file: " + file_name) process_ntuser(abs_file_path, ntuser_plugins, file_name, folder_path, outfile) elif(re.search("SAM", file_name)): hive_name_info = "SAM_INFO" process_other_hives(abs_file_path, sam_plugins, file_name, hive_name_info, folder_path, outfile) elif(re.search("SOFTWARE", file_name)): hive_name_info = "SOFTWARE_INFO" process_other_hives(abs_file_path, software_plugins, file_name, hive_name_info, folder_path, outfile) elif(re.search("SYSTEM", file_name)): hive_name_info = "SYSTEM_INFO" process_other_hives(abs_file_path, software_plugins, file_name, hive_name_info, folder_path, outfile) elif(re.search("SECURITY", file_name)): hive_name_info = "SECURITY_INFO" process_other_hives(abs_file_path, software_plugins, file_name, hive_name_info, folder_path, outfile) f.close() #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True) #close outfile outfile.close() #delete /tmp/ls_output.txt if (os.path.exists("/tmp/ls_output_" + temp_time + ".txt")): os.remove("/tmp/ls_output_" + temp_time +".txt")
def plaso_mr(item_to_process, case_number, root_folder_path, evidence): #(evidence_type, case_number, folder_path, evidence_path.strip()) print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' root_folder_path_no_quotes = root_folder_path root_folder_path = "'" + root_folder_path + "'" #get datetime now = datetime.datetime.now() #create output folder path folder_path = root_folder_path_no_quotes + "/" + "Plaso" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Plaso_mr_logfile.txt" outfile = open(log_file, 'wt+') if(item_to_process == "Directory"): folder_to_process = evidence_no_quotes process_folder(folder_path, case_number, folder_to_process, outfile) elif(item_to_process =="EnCase Logical Evidence File"): file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, export_file, outfile) #umount if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif(item_to_process == "Bit-Stream Image"): Image_Path = evidence_no_quotes #get datetime now = datetime.datetime.now() process_folder(folder_path, case_number, Image_Path, outfile) ## I have not been able to test this code yet since I don't have a large enough test imge #set file to split #file_to_split = folder_path + "/" + case_number + ".plaso.csv" #file_to_split_basename = case_number + ".plaso.csv" #pass csv file to split_csv to see if it needs to get split #split_csv(case_number, folder_path, outfile) #split_csv(case_number, folder_path, outfile, file_to_split, file_to_split_basename) #close output file outfile.close()
def pst_processor_mr(item_to_process, case_number, root_folder_path, evidence): #(evidence_type, case_number, folder_path, evidence_path.strip()) print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = "'" + evidence + "'" root_folder_path_no_quotes = root_folder_path root_folder_path = "'" + root_folder_path + "'" #get datetime now = datetime.datetime.now() #create output folder path folder_path = root_folder_path_no_quotes + "/" + "PST_Extracted_Emails" check_for_folder(folder_path, "NONE") #create folder for extracted_messages check_for_folder(folder_path + "/" "All Extracted_Messages", "NONE") #open a log file for output log_file = folder_path + "/PST_mr_logfile.txt" outfile = open(log_file, 'wt+') emails_of_interest_file = subprocess.check_output([ 'zenity --file-selection --filename="/mnt/hgfs/" ' '--title "Select file containing email addresses of interest (comma seperated)"' ], shell=True, universal_newlines=True) #process the PST file process_pst_command = 'readpst -o ' + "'" + folder_path + "/" "All Extracted_Messages" + "'" + " -D -j 4 -r -tea -e " + evidence print("The process_pst_command is: " + process_pst_command) subprocess.call([process_pst_command], shell=True, universal_newlines=True) #open emails_of_interest_file and parse emails into list with open(emails_of_interest_file.strip(), 'r', encoding='utf-8') as infile: for line in infile: email_addresses_split = line.split(',') for element in email_addresses_split: print("Creating output folder for email address: " + element) check_for_folder(folder_path + "/" + element, "NONE") #cd into the extracted_messages SENT folder os.chdir(folder_path + "/" "All Extracted_Messages/Personal Folders/Sent Items") #run the grep command in the SENT folder grep_command = "grep -rl --null --include '*.msg' --include '*.eml' " + element + " | xargs -0r cp -t " + "'" + folder_path + "/" + element + "'" print("The grep_command is: " + grep_command) subprocess.call([grep_command], shell=True, universal_newlines=True) #close output file outfile.close()
def create_kml_from_exif_mr(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' #create output folder path folder_path = root_folder_path + "/" + "KML_From_EXIF" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/KML_From_EXIF_logfile.txt" outfile = open(log_file, 'wt+') #initialize variables files_of_interest = {} files_of_interest_list = [] mount_point = "NONE" log_file3 = folder_path + "/" + case_number + "_files_to_exploit.xls" outfile3 = open(log_file3, 'wt+') #write out column headers to xls file outfile3.write("Name\tMD5\tFile Size (kb)\n") if(item_to_process == "Directory"): #select folder to process folder_process = evidence_no_quotes #set folder variable to "folder" since this is a folder and not a disk partition folder = "Directory" #call process subroutine process(folder_process, outfile, folder_path, folder, outfile3) elif(item_to_process == 'EnCase Logical Evidence File'): folder = "LEF" file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process(mount_point, outfile, folder_path, folder, outfile3) #umount if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) elif(item_to_process == 'Single File'): process_single_file(evidence_no_quotes, outfile, folder_path, "Single-File", outfile3) elif(item_to_process == 'Bit-Stream Image'): #select image to process Image_Path = evidence #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S") #check to see if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path no_quotes_path = Image_Path.replace("'","") print("The no quotes path is: " + no_quotes_path) #call mount_ewf function cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") Image_Path = mount_ewf(Image_Path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) #partition_info_dict_temp, temp_time = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time +".txt") print("The filesize is: " + str(file_size)) #if filesize of mmls output is 0 then run parted if(file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) #close file mmls_output_file.close() #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) #for key,value in partition_info_dict.items(): for key,value in sorted(partition_info_dict.items()): #create output folder for processed files if not os.path.exists(folder_path + "/Processed_files_" + str(key)): os.mkdir(folder_path + "/Processed_files_" + str(key)) #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #call mount sub-routine success_code, loopback_device_mount = mount(value,key,Image_Path, outfile, mount_point) if(success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + ". Scanning for files of interest.....\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #call process subroutine process(mount_point, outfile, folder_path, key, outfile3) #unmount and remove mount points if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #delete /tmp files created for processing bit-stream images if (os.path.exists("/tmp/mmls_output_" + temp_time + ".txt")): os.remove("/tmp/mmls_output_" + temp_time + ".txt") #write out list of filenames to end of output file so that user can create a filter for those filenames in Encase outfile3.write("\n\n******** LIST of FILENAMES of INTEREST ******************\n") #sort list so that all values are unique unique(files_of_interest_list) for files in files_of_interest_list: outfile3.write(files + "\n") #program cleanup outfile.close() outfile3.close() #remove mount points created for this program if(os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf") #convert outfile using unix2dos #chdir to output foler os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if(fileExtension.lower() == ".txt"): full_path = os.path.join(root,filenames) quoted_full_path = "'" +full_path+"'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + filenames subprocess.call([unix2dos_command], shell=True) #delete empty directories in output folder for root, dirs, files in os.walk(folder_path, topdown=False): for directories in dirs: files = [] dir_path = os.path.join(root,directories) files = os.listdir(dir_path) if(len(files) == 0): os.rmdir(dir_path) #unmount and remove mount points if(mount_point != "NONE"): if(os.path.exists(mount_point+"_ewf")): subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point+"_ewf")
def plist_processor(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence_no_quotes = evidence evidence = '"' + evidence + '"' # get datetime now = datetime.datetime.now() # set Mount Point mount_point = "/mnt/" + "MantaRay_" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") # create output folder path folder_path = root_folder_path + "/" + "PLIST_Processor" check_for_folder(folder_path, "NONE") # open a log file for output log_file = folder_path + "/PLIST_processor_logfile.txt" outfile = open(log_file, "wt+") # open an error file for output log_file = folder_path + "/PLIST_processor_error_log.txt" outfile_error = open(log_file, "wt+") # open file to write output exp_file = folder_path + "/" + case_number + "_PLIST_Triage.txt" export_file = open(exp_file, "a") if item_to_process == "Directory": folder_to_process = evidence_no_quotes process_folder(folder_to_process, export_file, outfile, outfile_error, now) elif item_to_process == "EnCase Logical Evidence File": file_to_process = evidence mount_point = mount_encase_v6_l01(case_number, file_to_process, outfile) process_folder(mount_point, export_file, outfile, outfile_error, now) # umount if os.path.exists(mount_point): subprocess.call(["sudo umount -f " + mount_point], shell=True) os.rmdir(mount_point) elif item_to_process == "Bit-Stream Image": # set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S_%f") Image_Path = evidence # check if Image file is in Encase format if re.search(".E01", Image_Path): # set mount point # mount_point = "/mnt/"+ case_number+"_ewf" Image_Path = mount_ewf(Image_Path, outfile, mount_point) # call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict # get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") # if filesize of mmls output is 0 then run parted if file_size == 0: print("mmls output was empty, running parted\n") outfile.write("mmls output was empty, running parted\n") # call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: # read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", "r") for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write("We found a GUID partition table, need to use parted\n") # call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) mmls_output_file.close() # loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) for key, value in partition_info_dict.items(): cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") # process plist files if value == "hfs+": # call mount sub-routine success_code, loopback_device_mount = mount(value, str(key), Image_Path, outfile, mount_point) if success_code: print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") # process process_folder(mount_point, export_file, outfile, outfile_error, now) # unmount subprocess.call(["umount " + mount_point], shell=True) subprocess.call(["losetup -d " + loopback_device_mount], shell=True) else: print("This partition is not formatted HFS+") outfile.write("This partition is not formatted HFS+\n\n") # close export_file export_file.close() # chdir to output foler os.chdir(folder_path) # unmount and remount points if re.search(".E01", Image_Path): if os.path.exists(mount_point + "_ewf"): subprocess.call(["sudo umount -f " + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf") # remove empty directories for root, dirs, files in os.walk(folder_path, topdown=False): for directory in dirs: dir_path = os.path.join(root, directory) if not os.listdir(dir_path): outfile.write("Removing empty folder: " + dir_path + "\n") os.rmdir(dir_path) # close outfiles outfile.close() # run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: # get file extension fileName, fileExtension = os.path.splitext(filenames) if fileExtension.lower() == ".txt": full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + filenames) unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True) # delete /tmp/ls_output.txt if os.path.exists("/tmp/mmls_output_" + temp_time + ".txt"): os.remove("/tmp/mmls_output_" + temp_time + ".txt") if os.path.exists("/tmp/timeline_partition_info_" + temp_time + ".txt"): os.remove("/tmp/timeline_partition_info_" + temp_time + ".txt") if os.path.exists("/tmp/dump_" + temp_time + ".txt"): os.remove("/tmp/dump_" + temp_time + ".txt") if os.path.exists("/tmp/fls_output_" + temp_time + ".txt"): os.remove("/tmp/fls_output_" + temp_time + ".txt") if os.path.exists("/tmp/hives_to_rename_" + temp_time): shutil.rmtree("/tmp/hives_to_rename_" + temp_time)
def jumplist_mr(item_to_process, case_number, root_folder_path, evidence): print("The item to process is: " + item_to_process) print("The case_name is: " + case_number) print("The output folder is: " + root_folder_path) print("The evidence to process is: " + evidence) evidence = '"' + evidence + '"' #get datetime now = datetime.datetime.now() #set Mount Point mount_point = "/mnt/" + now.strftime("%Y-%m-%d_%H_%M_%S") #create output folder path folder_path = root_folder_path + "/" + "Jumplist_Parser" check_for_folder(folder_path, "NONE") #open a log file for output log_file = folder_path + "/Jumplist_Parser_logfile.txt" outfile = open(log_file, 'wt+') #select image to process Image_Path = evidence print("The image path is: " + Image_Path) #check to see if Image file is in Encase format if re.search(".E01", Image_Path): #strip out single quotes from the quoted path no_quotes_path = Image_Path.replace("'", "") print("The no quotes path is: " + no_quotes_path) #call mount_ewf function Image_Path = mount_ewf(no_quotes_path, outfile, mount_point) #call mmls function partition_info_dict, temp_time = mmls(outfile, Image_Path) partition_info_dict_temp = partition_info_dict #get filesize of mmls_output.txt file_size = os.path.getsize("/tmp/mmls_output_" + temp_time + ".txt") print("The filesize is: " + str(file_size)) #if filesize of mmls output is 0 then run parted if (file_size == 0): print("mmls output was empty, running parted") outfile.write("mmls output was empty, running parted") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) else: #read through the mmls output and look for GUID Partition Tables (used on MACS) mmls_output_file = open("/tmp/mmls_output_" + temp_time + ".txt", 'r') for line in mmls_output_file: if re.search("GUID Partition Table", line): print("We found a GUID partition table, need to use parted") outfile.write( "We found a GUID partition table, need to use parted\n") #call parted function partition_info_dict, temp_time = parted(outfile, Image_Path) #loop through the dictionary containing the partition info (filesystem is VALUE, offset is KEY) #for key,value in partition_info_dict.items(): for key, value in sorted(partition_info_dict.items()): #disable auto-mount in nautilis - this stops a nautilis window from popping up everytime the mount command is executed cmd_false = "sudo gsettings set org.gnome.desktop.media-handling automount false && sudo gsettings set org.gnome.desktop.media-handling automount-open false" try: subprocess.call([cmd_false], shell=True) except: print("Autmount false failed") #run mount command success_code, loopback_device_mount = mount(value, key, Image_Path, outfile, mount_point) if (success_code): print("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) outfile.write("Could not mount partition with filesystem: " + value + " at offset:" + str(key)) else: print("We just mounted filesystem: " + value + " at offset:" + str(key) + ".\n") outfile.write("We just mounted filesystem: " + value + " at offset:" + str(key) + "\n") #run jl.pl against every JumpList file found under mount_point if filesystem is fat32 or ntfs if (value == "ntfs") or (value == "fat32"): for root, dirs, files in os.walk(mount_point): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".automaticdestinations-ms"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Processing Jump List: " + filenames) outfile.write("Processing Jump List: " + filenames + "\n") #get profile name profile = get_account_profile_names( full_path, outfile) print("The profile is: " + profile) outfile.write("The profile is: " + profile + "\n") #process Jumplist files with jl.pl #jl_command = "perl /usr/share/windows-perl/jl.pl -u " + "'" + profile + "'" + " -f " + full_path + " >> " + "'" + folder_path + "/jumplist_metadata.txt" + "'" jl_command_tln = "perl /usr/share/windows-perl/jl.pl -u " + "'" + profile + "'" + " -t -f " + quoted_full_path + " >> " + "'" + folder_path + "/jumplist_metadata_tln.txt" + "'" outfile.write("The jl_command_tln is: " + jl_command_tln + "\n") subprocess.call([jl_command_tln], shell=True) else: print("Scanning file: " + filenames + ". This file is not a jumplist.") #unmount and remove mount points if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) else: print("Filesystem: " + value + " at offset:" + str(key) + " is not NTFS or FAT32") outfile.write("Filesystem: " + value + " at offset:" + str(key) + " is not NTFS or FAT32\n") if (os.path.exists(mount_point)): subprocess.call(['sudo umount -f ' + mount_point], shell=True) os.rmdir(mount_point) #unmount loopback device if this image was HFS+ - need to run losetup -d <loop_device> before unmounting if not (loopback_device_mount == "NONE"): losetup_d_command = "losetup -d " + loopback_device_mount subprocess.call([losetup_d_command], shell=True) #create timeline parse_command = "perl /usr/share/windows-perl/parse.pl -f " + "'" + folder_path + "/jumplist_metadata_tln.txt" + "'" + "> " + "'" + folder_path + "/jumplist_timeline.txt" + "'" subprocess.call([parse_command], shell=True) #unmount and remove mount points #if(os.path.exists(mount_point)): # os.rmdir(mount_point) if (os.path.exists(mount_point + "_ewf")): print("Unmounting mount point for ewf before exiting\n\n") subprocess.call(['sudo umount -f ' + mount_point + "_ewf"], shell=True) os.rmdir(mount_point + "_ewf") #program cleanup outfile.close() #convert outfile using unix2dos #chdir to output foler os.chdir(folder_path) #run text files through unix2dos for root, dirs, files in os.walk(folder_path): for filenames in files: #get file extension fileName, fileExtension = os.path.splitext(filenames) if (fileExtension.lower() == ".txt"): full_path = os.path.join(root, filenames) quoted_full_path = "'" + full_path + "'" print("Running Unix2dos against file: " + quoted_full_path) #unix2dos_command = "sudo unix2dos " + "'"+filenames+"'" unix2dos_command = "sudo unix2dos " + quoted_full_path subprocess.call([unix2dos_command], shell=True)