def pack_delete(request): pack_id = ReqParams.one(request, 'pack_id') # delete fw_files_storage # delete fw_files # delete pack_files_storage # delete pack_files file_list = FwFileDO.search_files_of_pack(pack_id) for file in file_list: FwFilesStorage.delete(file['file_id']) # if len(file_list) > 0: FwFileDO.delete_many_of_pack(pack_id) pack_info = PackFileDO.fetch_pack(pack_id) PackFilesStorage.delete(pack_info['file_id']) PackFileDO.delete(pack_id) # 保存操作日志 LogRecords.save('', category='statistics', action='删除固件包', desc='删除指定固件包(ID=%s)的信息,' % pack_id) return sys_app_ok_p([])
def remove_virtual_pack(pack_id): # 获取该固件包关联的所有文件 ID files_list = FwFileDO.get_files_of_pack(pack_id) file_id_list = [file_item['file_id'] for file_item in files_list] # 移除存储桶中的文件内容 FwFilesStorage.delete_many(file_id_list) # 移除该固件包关联的所有文件记录 FwFileDO.delete_many_of_pack(pack_id) # 移除固件包记录 PackFileDO.delete(pack_id)
def pack_edit(request): pack_id, manufacturer, model, version = ReqParams.many( request, ['pack_id', 'manufacturer', 'model', 'version'], protocol='POST') PackFileDO.save_manufacturer(pack_id, manufacturer, model, version) # 保存操作日志 LogRecords.save('', category='statistics', action='编辑指定固件包信息', desc='编辑指定固件包信息 厂商 型号(ID=%s)的信息' % pack_id) return sys_app_ok_p([])
def cfg_all_exec_bin_files(self, pack_id, task_id): # 获取本固件包所有的二进制可执行文件记录 bin_files_list = FwFileDO.search_files_of_pack(pack_id, FileType.EXEC_FILE) # 枚举每个文件,读出其文件数据,校验 total_count = len(bin_files_list) for index, file_item in enumerate(bin_files_list): # 检查任务状态 if MyTask.is_task_stopped(task_id): break # 保存任务执行百分比 self._save_task_percentage(task_id, index, total_count) # 注意:此处一定要设置覆写,否则判定的是旧文件数据,造成判定结果错误 file_id = file_item['file_id'] file_path = FwFilesStorage.export(file_item['file_id'], file_name=task_id, override=True) is_cfg = CfgAnalyzeService.has_cfg_analyze(file_id) if not is_cfg: try: # 通过 project 快速解析文件 angr_proj = AngrProj(file_id, progress_callback=self.run_percent_cb, task_id=task_id, cfg_mode='cfg_fast') # 从 project 中提取函数列表 functions = FunctionParse.functions_extract(angr_proj.proj) # 保存 函数列表到数据库 FileCacheDAO.save_functions(file_id, functions) arch = str(angr_proj.proj.arch) # 设置文件已完成 CFG 分析的标记 FwFileDO.set_cfg_analyzed(file_id, 1, arch) PackFileDO.updateArch(pack_id, arch) except Exception as e: print(e) # 保存任务完成状态 MyTask.save_exec_info(task_id, 100.0) # 包分析完成标志 PackFileDO.analyze_complet(pack_id, 1)
def summary_info(content, firmware_name, firmware_md5, firmware_size, pack_id, firmware_file_num, execute_file_num): Graphs.draw_con(content, '1 固件分析综述', Graphs.text_type(18, 30, colors.black, 0)) pack = PackFileDO.fetch_pack(pack_id) pack_filesystem = pack.get('filesystem') pack_arch = pack.get('arch') pack_arch = str(pack_arch).replace("<", '').replace(">", '') content.append(Graphs.draw_text('固件名称:' + firmware_name, '0')) if len(firmware_md5) > 0: content.append(Graphs.draw_text('固件 MD5:' + firmware_md5, '0')) if len(firmware_size) > 0: content.append(Graphs.draw_text('固件大小:' + firmware_size, '0')) if len(pack_filesystem) > 0: content.append(Graphs.draw_text('文件系统:' + pack_filesystem, '0')) if len(pack_arch) > 0: content.append(Graphs.draw_text('架构:' + pack_arch, '0')) content.append( Graphs.draw_text('固件中共有' + str(firmware_file_num) + '个文件', '0')) content.append( Graphs.draw_text('固件中共有' + str(execute_file_num) + '个可执行文件', '0')) content.append(Spacer(300, 10)) # 添加空白,长度300,宽10
def fs_image_extract(self, pack_id, task_id): self.task_id = task_id image, image_file_name, fs = self.open_image() PackFileDO.savefs(self.pack_id, fs) # 任务关联文件名 MyTask.save_exec_info_name(task_id, image_file_name) # 在主进程或任务中,采用预订的文件系统抽取文件 if image.extract_files(extract_func=self.save_proc): # 正常处理完毕后,保存任务完成状态 MyTask.save_exec_info(task_id, 100.0) # 完成抽取后,启动任务检验该包中所有可执行二进制文件的验证 PackFiles.start_exec_bin_verify_task(self.pack_id, image_file_name)
def remove_all_packs_by_type(pack_type): packs_list = PackFileDO.all_packs_type(pack_type) if len(packs_list) == 0: # 返回空任务列表 return [] # 固件包 ID 列表 # pack_id_list = [pack_item['pack_id'] for pack_item in packs_list] tasks_list = [] for pack_item in packs_list: pack_id = pack_item['pack_id'] pack_type = pack_item['pack_type'] # 停止所有当前包的运行任务 PackProcessService.stop_running_tasks_of_pack(pack_id) if pack_type == PackType.REAL: # 启动移除实体固件包的任务 task_id = PackProcessService.start_remove_packs_task(pack_id) tasks_list.append(task_id) elif pack_type == PackType.VIRTUAL: # 虚拟包不需要后台任务 PackProcessService.remove_virtual_pack(pack_id) # 返回所有任务的列表 return tasks_list
def check_component(pack_id, task_id): MyRedis.set('running_check_com_flag', True) # 获取本固件包所有的二进制可执行文件记录 fw_files_list = FwFileDO.search_files_of_pack(pack_id, FileType.EXEC_FILE) pack_item = PackFileDO.fetch_pack(pack_id) process_file_name = pack_item.get('name') # pack_item['name'] MyTask.save_exec_info_name(task_id, process_file_name) # 枚举每个文件,根据文件名检索组件库(make),校验 total_count = len(fw_files_list) for index, file_item in enumerate(fw_files_list): percentage = round(index * 100 / total_count, 1) MyTask.save_exec_info(task_id, percentage) componentinfo = MakeCOMFileDO.search_component_name( file_item['file_name']) if componentinfo is None: continue FwFileDO.set_component(file_item['file_id'], 1) # 相似度匹配计算,标记漏洞(version / edbid) fw_file_id = file_item['file_id'] component_file_id = componentinfo['file_id'] print(SysUtils.get_now_time()) # 计算相似度 比较耗时 openssl计算大约两分钟 similarity = assembly.calc_cosine_algorithm(fw_file_id, component_file_id) print(SysUtils.get_now_time()) # 相似度阈值设定: 0-100 if similarity < utils.sys.config.g_similarity: print(similarity) continue # 相似度大于阈值 标记漏洞(version / edbid) com_file_info = PackCOMFileDO.fetch_pack(componentinfo['pack_id']) version = com_file_info['version'] name = com_file_info['name'] edb_id = com_file_info['edb_id'] FwFileDO.set_component_extra_props( fw_file_id, { 'version': version, 'name': name, 'edb_id': edb_id, 'similarity': similarity }) MyRedis.set('running_check_com_flag', False) # 保存任务完成状态 MyTask.save_exec_info(task_id, 100.0) return
def _save_pack_db(fw_download_url, path_file_name, download_info, task_id): # todo file_type file_type, contents = check_file_type(path_file_name) file_type = FileType.PACK file_name = os.path.basename(path_file_name) # 新建或保存文件记录 # 新的 pack ID pack_id = StrUtils.uuid_str() # 新的 pack 文件 UUID file_id = StrUtils.uuid_str() # 读取包文件内容 contents = MyFile.read(path_file_name) # 保存文件记录 PackFileDO.save(pack_id, file_id, name=file_name, file_type=file_type) # 保存文件内容 PackFilesStorage.save(file_id, file_name, FileType.PACK, contents) # 返回固件包ID,文件ID return pack_id, file_id
def _save_pack(pack_index, pack_name): # 获取 pack 文件的路径 file_path = LoadDefaultPack._get_fw_file_path(pack_index) if file_path is None: return None, None # 文件类型 file_type = LoadDefaultPack._get_file_type(pack_index) # 新建或保存文件记录 # 新的 pack ID pack_id = StrUtils.uuid_str() # 新的 pack 文件 UUID file_id = StrUtils.uuid_str() # 读取包文件内容 contents = MyFile.read(file_path) # 保存文件记录 PackFileDO.save(pack_id, file_id, name=pack_name, file_type=file_type) # 保存文件内容 PackFilesStorage.save(file_id, pack_name, file_type, contents) return pack_id, file_id
def add_single_exec(file_name, file_data): # 新的 pack ID pack_id = StrUtils.uuid_str() # 保存虚拟包记录 PackFileDO.save(pack_id, '', name=file_name, pack_type=PackType.VIRTUAL, file_type=FileType.PACK) # 新的 pack 文件 UUID exec_file_id = StrUtils.uuid_str() # 保存文件记录 FwFileDO.save_file_item(pack_id, exec_file_id, file_name, FileType.EXEC_FILE) # 在存储桶中保存文件数据 # 保存文件内容 FwFilesStorage.save(exec_file_id, file_name, file_name, FileType.EXEC_FILE, file_data) return pack_id, exec_file_id
def remove_pack_proc(self, pack_id, task_id): # 获取该固件包关联的所有文件 ID files_list = FwFileDO.get_files_of_pack(pack_id) file_id_list = [file_item['file_id'] for file_item in files_list] # 第一步,总进度条的 0-80% # 移除存储桶中,该固件包关联的所有文件 total_count = len(file_id_list) for index, file_id in enumerate(file_id_list): if MyTask.is_task_stopped(task_id): return self._save_task_percentage(task_id, index, total_count, 80.0) FwFilesStorage.delete(file_id) # print('delete {} of {}'.format(index, total_count)) # time.sleep(2) # FwFilesStorage.delete_many(file_id_list) # 第二步,总进度条的 80-85% # 移除存储桶中,固件包自身文件 MyTask.save_task_percentage(task_id, 80.0) pack_item = PackFileDO.fetch_pack(pack_id) pack_file_id = pack_item['file_id'] PackFilesStorage.delete(pack_file_id) # 第三步,总进度条的 85-95% # 移除该固件包关联的所有文件记录 MyTask.save_task_percentage(task_id, 85.0) FwFileDO.delete_many_of_pack(pack_id) # 第四步,总进度条的 95-100% # 移除该固件包自身记录 MyTask.save_task_percentage(task_id, 95.0) PackFileDO.delete(pack_id) # 完成任务 MyTask.save_task_percentage(task_id, 100.0)
def all_packs_info(request): # 所有包的基本信息 packs_list = PackFileDO.all_packs() info_list = [] for pack in packs_list: # 各个包的所含文件信息 # 各个包的提取任务和分析任务状态 pack_id = pack['pack_id'] pack_service = PackInfoService(pack_id, pack) pack = pack_service.pack_summary() info_list.append(pack) # 保存操作日志 LogRecords.save('', category='statistics', action='查询所有包信息', desc='查询所有固件包的信息,统计其文件数量,查询任务信息') return sys_app_ok_p(info_list)
def __init__(self, pack_id, pack_info=None): self.pack_id = pack_id if pack_info is None: pack_info = PackFileDO.fetch_pack(pack_id) self.pack_info = pack_info