def binwalk_file_test(request): filename = req_get_param(request, 'filename') try: for module in binwalk.scan(filename, filesystem=True, quiet=True): for result in module.results: if result.file.path in module.extractor.output: # These are files that binwalk carved out of the original firmware image, a la dd if result.offset in module.extractor.output[ result.file.path].carved: print "Carved data from offset 0x%X to %s" % ( result.offset, module.extractor.output[ result.file.path].carved[result.offset]) # These are files/directories created by extraction utilities (gunzip, tar, unsquashfs, etc) if result.offset in module.extractor.output[ result.file.path].extracted: print "Extracted %d files from offset 0x%X to '%s' using '%s'" % ( len(module.extractor.output[result.file.path]. extracted[result.offset].files), result.offset, module.extractor.output[result.file.path]. extracted[result.offset].files[0], module.extractor.output[result.file.path]. extracted[result.offset].command) except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_err('ERROR_INTERNAL_ERROR') return sys_app_ok_p({ 'extract': 'ok', })
def angr_recognize_func(request): functions = [] try: filename = req_get_param(request, 'filename') arch = getarch(filename) proj = angr.Project(filename, load_options={ 'auto_load_libs': False, 'main_opts': { 'backend': 'blob', 'base_addr': 0, 'arch': arch, }, }) cfg = proj.analyses.CFGFast() for address, func in cfg.functions.items(): print(hex(address), func.name) functions.append(func.name) except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_err('ERROR_INTERNAL_ERROR') return sys_app_ok_p({ 'functions': functions, })
def poc_search(request): offset = req_get_param_int(request, 'offset') count = req_get_param_int(request, 'count') value = req_get_param(request, 'value') # 查找利用信息 result_cursor = firmware_db.search(value) item_list = list(result_cursor) # 获取信息总数,并判断指定偏移量是否越界 total = len(item_list) if total == 0 or offset >= total: return app_err_p(Error.NO_MORE_DATA, {'total': total, 'count': 0}) # 读取指定位置和数量的利用信息 if count > total - offset: count = total - offset item_list = item_list[offset: offset + count] # 查询poc信息,添加到漏洞信息中 # poc_list = [] for item in item_list: poc = firmware_pocs.fetch_no_content(item['firmware_id']) item['poc'] = poc # poc_list.append(poc) #SysLog.success('搜索POC', '成功搜索POC文件,总数={}'.format(len(item_list))) return sys_app_ok_p({'total': total, 'count': len(item_list), 'items': item_list})
def binwalk_scan_opcodes(request): filename = req_get_param(request, 'filename') #print(filename) # filename = "D:/code/work/firmwareanalyze/HC5611.bin" structure = '' try: for module in binwalk.scan(filename, opcodes=True, quiet=True): print("%s Results:" % module.name) for result in module.results: print("\t%s 0x%.8X %s" % (result.file.path, result.offset, result.description)) if ("X86" in result.description.upper()): structure = 'X86' break elif ("ARM" in result.description.upper()): structure = "ARM" break elif ("MIPS" in result.description.upper()): structure = "MIPS" break else: structure = "PowerPC" break except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_err('ERROR_INTERNAL_ERROR') return sys_app_ok_p({ 'structure': structure, })
def get_task_result(request): # 从请求中取参数:文件 ID task_id = req_get_param(request, 'task_id') # 从缓存中读取任务执行信息 task_info = MyTask.fetch_exec_info(task_id) return sys_app_ok_p(task_info)
def fw_functions_list(request): # 从请求中取参数:文件 ID file_id = req_get_param(request, 'file_id') # 获取代码中的函数列表 func_parse = _get_func_parse(file_id) functions = func_parse.func_list() return sys_app_ok_p({'functions_count': len(functions), 'functions': functions})
def async_fw_functions_list(request): # 从请求中取参数:文件 ID file_id = req_get_param(request, 'file_id') # 启动分析任务 task = MyTask(_proc_fw_functions_list, (file_id, )) task_id = task.get_task_id() # 返回响应:任务初始化的信息 return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
def fetch(request): firmware_id = req_get_param(request, 'firmware_id') if StrUtils.is_blank(firmware_id): return sys_app_err('ERROR_INVALID_PARAMETER') doc = firmware_db.fetch(firmware_id) if doc is None: #SysLog.fail('提取漏洞', '没有提取到漏洞信息(ID={})'.format(firmware_id)) return sys_app_err('ERROR_FWID_NOT_FOUND') #SysLog.success('提取漏洞', '成功提取漏洞信息(ID={})'.format(firmware_id)) return app_ok_p(doc)
def stop_task(request): # 从请求中取参数:任务 ID task_id = req_get_param(request, 'task_id') task_info = MyTask.stop_task(task_id) # 保存操作日志 LogRecords.save(task_info, category='task', action='停止任务', desc='停止指定的任务(ID=%s)' % task_id) return sys_app_ok_p(task_info)
def async_fwdownload(request): # 获取下载URL downloadurl = req_get_param(request, 'url') print(downloadurl) # 启动下载任务 task = MyTask(_proc_func_download, (downloadurl, settings.FW_PATH, )) task_id = task.get_task_id() # 返回响应:任务初始化的信息 return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
def poc_delete(request): firmware_id = req_get_param(request, 'firmware_id') if StrUtils.is_blank(firmware_id): return app_err(Error.INVALID_REQ_PARAM) # 删除POC if not firmware_pocs.delete(firmware_id): #SysLog.fail('删除POC', '删除POC失败(漏洞ID={})'.format(firmware_id)) return app_err(Error.EDB_POC_NOT_FOUND) #SysLog.success('删除POC', '成功删除漏洞的POC(漏洞ID={})'.format(firmware_id)) return app_ok()
def get_task_result(request): # 从请求中取参数:任务 ID task_id = req_get_param(request, 'task_id') # 从缓存中读取任务执行信息 task_info = MyTask.fetch_exec_info(task_id) # 保存操作日志 LogRecords.save(task_info, category='query_task', action='查询任务状态', desc='读取任务(ID=%s)当前执行状态及结果信息' % task_id) return sys_app_ok_p(task_info)
def search_tasks_by_file(request): # 从请求中取参数:文件 ID file_id = req_get_param(request, 'file_id') if file_id is None: return sys_app_ok_p([]) tasks_list = TasksDAO.search_by_file(file_id) # 保存查询日志 LogRecords.save(tasks_list, category='query_task', action='查询文件任务', desc='查询指定的文件(ID=%s)所有的任务信息' % file_id) return sys_app_ok_p(tasks_list)
def entry_state_info(request): # 从请求中取参数:文件 ID file_id = req_get_param(request, 'file_id') info = FilesService.bin_state_info(file_id) # 保存操作日志 LogRecords.save(info, category='analysis', action='入口状态机', desc='分析可执行文件的入口状态机参数') return sys_app_ok_p(info)
def angr_convert_code(request): try: filename = req_get_param(request, 'filename') arch = getarch(filename) # load_options = {'auto_load_libs': False, 'main_opts': {'base_addr': 0}}) # proj = angr.Project(filename, load_options={ # 'main_opts': { # 'backend': 'blob', # 'base_addr': 0, # 'arch': arch, # }, # }) # 装载二进制程序 proj = angr.Project(filename, load_options={ 'auto_load_libs': False, 'main_opts': { 'backend': 'blob', 'base_addr': 0, 'arch': arch, }, }) print(proj.arch) state = proj.factory.entry_state() print(proj.entry) #### Blocks # 转换入口点为基本块 block = proj.factory.block( proj.entry) # lift a block of code from the program's entry point pp = block.pp() # pretty-print a disassembly to stdout print(block.instructions) # how many instructions are there? print(block.instruction_addrs ) # what are the addresses of the instructions? print(block.capstone) # capstone disassembly print( block.vex ) # VEX IRSB (that's a python internal address, not a program address) irsb = proj.factory.block(proj.entry).vex irsb.pp() irsb.next.pp() except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_err('ERROR_INTERNAL_ERROR') return sys_app_ok_p({ 'code': str(block.vex), })
def async_funcs_fetch(request): # 获取固件ID firmware_id = req_get_param(request, 'firmware_id') # 启动任务 存储桶读取固件内容 task = MyTask(_proc_fetch, (firmware_id, settings.FW_PATH)) task_id = task.get_task_id() # 保存操作日志 LogRecords.save({'task_id': task_id, 'file_id': firmware_id}, category='fetch', action='下载固件', desc='存储桶读取固件保存并进行文件抽取') # 返回响应:任务初始化的信息 return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
def filter(request): offset = req_get_param_int(request, 'offset') count = req_get_param_int(request, 'count') field = req_get_param(request, 'field') value = req_get_param(request, 'value') # 查找利用信息 result_cursor = firmware_db.filter(field, value) if result_cursor is None: return app_err(Error.INVALID_REQ_PARAM) item_list = list(result_cursor) # 获取信息总数,并判断指定偏移量是否越界 total = len(item_list) if total == 0 or offset >= total: return app_err_p(Error.NO_MORE_DATA, {'total': total, 'count': 0}) # 读取指定位置和数量的利用信息 if count > total - offset: count = total - offset item_list = item_list[offset: offset + count] #SysLog.success('查询漏洞', '成功查询漏洞信息,查询到漏洞信息总数={}'.format(len(item_list))) return app_ok_p({'total': total, 'count': len(item_list), 'items': item_list})
def poc_download(request): firmware_id = req_get_param(request, 'firmware_id') item = firmware_pocs.fetch(firmware_id) if item is None: return sys_app_err('ERROR_FWPOC_NOT_FOUND') file_name = item['aliases'] # 对文本类型的文件名称增加txt后缀 download_name = SysUtils.add_plain_text_file_suffix(file_name) # 设置响应内容的文件下载参数 response = HttpResponse(item['content'], content_type='application/octet-stream') response['Content-Disposition'] = 'attachment;filename="%s"' % (urlquote(download_name)) #SysLog.success('下载POC', '成功下载POC文件,漏洞ID={}'.format(firmware_id)) return response
def delete(request): firmware_id = req_get_param(request, "firmware_id") if not firmware_db.custom_firmware_id(firmware_id): #SysLog.fail('删除漏洞', '删除漏洞(ID={})失败,只有定制的漏洞信息才能进行删除操作。'.format(firmware_id)) return firmware_db.err_not_custom() # firmware_id不存在,表示没有可以删除的漏洞信息条目 if not firmware_db.exist_firmware_id(firmware_id): #SysLog.fail('删除漏洞', '删除漏洞失败,该漏洞(ID={})不存在。'.format(firmware_id)) return app_err(Error.firmware_id_NOT_FOUND) result = firmware_db.delete(firmware_id) # 本版本不检查成功与否 #SysLog.success('删除漏洞', '成功删除漏洞信息,漏洞ID={}'.format(firmware_id)) return app_ok()
def binwalk_scan_signature(request): filename = req_get_param(request, 'filename') result_list = list() try: for module in binwalk.scan(filename, signature=True, quiet=True): print("%s Results:" % module.name) for result in module.results: result_list.append( "\t%s 0x%.8X %s" % (result.file.path, result.offset, result.description)) print("\t%s 0x%.8X %s" % (result.file.path, result.offset, result.description)) except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_ok_p({'decode': result_list})
def binwalk_scan_signatureEx(request): firmware_id = req_get_param(request, 'firmware_id') try: # 查询数据库 得到固件名 fw = firmware_db.fetch(firmware_id) # todo check fw is NULL if fw['fw_info']['filepath'] is not None: filename = fw['fw_info']['filepath'] + fw['fw_info']['filename'][0] else: return sys_app_ok_p({'decode': 'Null', 'description': "解析文件名出错"}) result_list = list() offset_list = list() description_list = list() index = 0 # try: for module in binwalk.scan(filename, signature=True, quiet=True): print("%s Results:" % module.name) for result in module.results: result_list.append( "\t%s 0x%.8X %s" % (result.file.path, result.offset, result.description)) print("\t%s 0x%.8X %s" % (result.file.path, result.offset, result.description)) offset_list.append(result.offset) description_list.append(result.description) # 将解压缩后的固件文件信息存入mongodb firmware_info dic = {} item = {} for off_set in offset_list: index += 1 offset = 'offset' + str(index) description = 'description' + str(index) dic[offset] = off_set dic[description] = description_list[index - 1] item['decode_info'] = dic firmware_db.update(firmware_id, item) except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_ok_p({'decode': result_list})
def recover_config(request): # 从请求中取参数:新的系统配置 new_config_key = req_get_param(request, 'config_key') # 数据库中写入系统配置参数 SystemConfig.recover_db(new_config_key) # 重新加载新的配置参数到缓存 config = SystemConfig.cache_load() # 保存操作日志 LogRecords.save(config, category='system_config', action='备份系统配置', desc='备份系统各项配置参数') return sys_app_ok_p(config)
def binwalk_file_extract(request): filename = req_get_param(request, 'filename') try: list_temp = [] # filename=US_W331AV1.0BR_V1.0.0.12_cn&en_TD.bin 文件名带特殊符号无法进行抽取文件 for module in binwalk.scan(filename, signature=True, quiet=True, extract=True): for result in module.results: if result.file.path in module.extractor.output: # These are files that binwalk carved out of the original firmware image, a la dd if result.offset in module.extractor.output[ result.file.path].carved: print "Carved data from offset 0x%X to %s" % ( result.offset, module.extractor.output[ result.file.path].carved[result.offset]) list_temp.append(module.extractor.output[ result.file.path].carved[result.offset]) # These are files/directories created by extraction utilities (gunzip, tar, unsquashfs, etc) if result.offset in module.extractor.output[ result.file.path].extracted: if len(module.extractor.output[result.file.path]. extracted[result.offset].files): print "Extracted %d files from offset 0x%X to '%s' using '%s'" % ( len(module.extractor.output[result.file.path]. extracted[result.offset].files), result.offset, module.extractor.output[result.file.path]. extracted[result.offset].files[0], module.extractor.output[result.file.path]. extracted[result.offset].command) list_temp.append( module.extractor.output[result.file.path]. extracted[result.offset].files) except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_err('ERROR_INTERNAL_ERROR') return sys_app_ok_p({'extract': 'ok', 'filelist': list_temp})
def search_tasks_by_pack(request): # 从请求中取参数:包 ID pack_id = req_get_param(request, 'pack_id') if pack_id is None: return sys_app_ok_p([]) tasks_list = TasksDAO.search_by_pack(pack_id) task_info_list = [] for task_info in tasks_list: # 没有执行完成的任务状态,用缓存中任务信息代替 if task_info['task_status'] != TaskStatus.COMPLETE: task_info = MyTask.fetch_exec_info(task_info['task_id']) task_info_list.append(task_info) # 保存查询日志 LogRecords.save(task_info_list, category='query_task', action='查询固件包任务', desc='查询指定的固件包(ID=%s)所有的任务信息' % pack_id) return sys_app_ok_p(task_info_list)
def inverted(request): # 获取参数 file_id = req_get_param(request, 'file_id') # 启动编译任务 extra_info = { 'task_type': TaskType.INVERTED, 'task_name': '倒排索引', 'task_desc': '建立倒排索引' } task = MyTask(_proc_inverted_tasks, (file_id, ), extra_info=extra_info) task_id = task.get_task_id() # 保存操作日志 LogRecords.save({'task_id': task_id}, category='compile', action='倒排索引', desc='建立倒排索引') # 返回响应:任务初始化的信息 return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
def search(request): offset = req_get_param_int(request, 'offset') count = req_get_param_int(request, 'count') value = req_get_param(request, 'value') # 查找利用信息 result_cursor = firmware_db.search(value) item_list = list(result_cursor) # 获取信息总数,并判断指定偏移量是否越界 total = len(item_list) if total == 0 or offset >= total: return app_err_p(Error.NO_MORE_DATA, {'total': total, 'count': 0}) # 读取指定位置和数量的利用信息 if count > total - offset: count = total - offset item_list = item_list[offset: offset + count] # 为性能测试中降低CPU使用率,小段延时 time.sleep(1.0) #SysLog.success('搜索漏洞', '成功搜索漏洞信息,查询到漏洞信息总数={}'.format(len(item_list))) return app_ok_p({'total': total, 'count': len(item_list), 'items': item_list})
def poc_fetch(request): firmware_id = req_get_param(request, 'firmware_id') # doc = firmware_db.fetch(firmware_id) poc = firmware_pocs.fetch(firmware_id) if poc is None: return sys_app_err('ERROR_FWPOC_NOT_FOUND') print(poc['aliases']) # print(poc['firmware_path']) # print(poc['length']) # print(poc['filelist']) filepath = poc['firmware_path'] filename = poc['filelist'] length = poc['length'] #SysLog.success('提取POC', '成功提取漏洞的POC(漏洞ID={})'.format(firmware_id)) # doc['poc'] = poc # 将解压缩后的固件文件信息存入mongodb firmware_info item = {'fw_info': {'filepath': filepath, 'filename': filename, 'length': length}} firmware_db.update(firmware_id, item) return sys_app_ok_p(poc)
def angr_convert2asm(request): insns = [] asms = [] try: filename = req_get_param(request, 'filename') arch = getarch(filename) p = angr.Project(filename, load_options={ 'auto_load_libs': False, 'main_opts': { 'backend': 'blob', 'base_addr': 0, 'arch': arch, }, }) maxadd = p.loader.max_addr minadd = p.loader.min_addr print(minadd, maxadd) # let's disasm with capstone to search targets insn_bytes = p.loader.memory.load(0, maxadd) for cs_insn in p.arch.capstone.disasm(insn_bytes, 0): insns.append(CapstoneInsn(cs_insn)) print("0x%x:\t%s\t\t%s" % (cs_insn.address, cs_insn.mnemonic, cs_insn.op_str)) # print(str(CapstoneInsn(cs_insn))) block = CapstoneBlock(0, insns, 0, p.arch) for ins in block.insns: asms.append(str(ins)) # print(ins) except Exception as e: print("Critical failure:", e) return sys_app_err('ERROR_INTERNAL_ERROR') return sys_app_ok_p({ 'ASM': asms, })
def _req_params(request): file_id = req_get_param(request, 'file_id') func_addr_hex = req_get_param(request, 'func_addr') func_addr = int(func_addr_hex, 16) return file_id, func_addr
def binwalk_file_extractEx(request): # filename = req_get_param(request, 'filename') firmware_id = req_get_param(request, 'firmware_id') try: # 查询数据库 得到固件名 fw = firmware_db.fetch(firmware_id) # todo check fw is NULL if fw['fw_info']['filepath'] is not None: filename = fw['fw_info']['filepath'] + fw['fw_info']['filename'][0] else: return sys_app_ok_p({'decode': 'Null', 'description': "解析文件名出错"}) list_temp = [] # filename=US_W331AV1.0BR_V1.0.0.12_cn&en_TD.bin 文件名带特殊符号无法进行抽取文件 for module in binwalk.scan(filename, signature=True, quiet=True, extract=True): for result in module.results: if result.file.path in module.extractor.output: # These are files that binwalk carved out of the original firmware image, a la dd if result.offset in module.extractor.output[ result.file.path].carved: print "Carved data from offset 0x%X to %s" % ( result.offset, module.extractor.output[ result.file.path].carved[result.offset]) list_temp.append(module.extractor.output[ result.file.path].carved[result.offset]) # These are files/directories created by extraction utilities (gunzip, tar, unsquashfs, etc) if result.offset in module.extractor.output[ result.file.path].extracted: if len(module.extractor.output[result.file.path]. extracted[result.offset].files): print "Extracted %d files from offset 0x%X to '%s' using '%s'" % ( len(module.extractor.output[result.file.path]. extracted[result.offset].files), result.offset, module.extractor.output[result.file.path]. extracted[result.offset].files[0], module.extractor.output[result.file.path]. extracted[result.offset].command) list_temp.append( module.extractor.output[result.file.path]. extracted[result.offset].files) # 将抽取的文件信息存入mongodb firmware_info dic = {} item = {} index = 0 for off_set in list_temp: index += 1 filex = 'file' + str(index) dic[filex] = list_temp[index - 1] item['extract_info'] = dic firmware_db.update(firmware_id, item) except binwalk.ModuleException as e: print("Critical failure:", e) return sys_app_err('ERROR_INTERNAL_ERROR') return sys_app_ok_p({'extract': 'ok', 'filelist': list_temp})