def runcmd(command, work_path=MyPath.component(), task_id=None, env=None): # 1. 命令被分号“;”分隔,这些命令会顺序执行下去; # 2. 命令被“ && ”分隔,这些命令会顺序执行下去,遇到执行错误的命令停止; # 3. 命令被双竖线“ || ”分隔,这些命令会顺序执行下去,遇到执行成功的命令停止,后面的所有命令都将不会执行; print(command) # command = '/bin/sh -c ' + cmd # command = cmd args = shlex.split(command) # sub_proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=work_path, env={'CC':'arm-linux-gnueabihf-gcc', 'RANLIB':'arm-linux-gnueabihf-ranlib'}) sub_proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=work_path) output, stderr = sub_proc.communicate() exit_code = sub_proc.returncode # process = output[0].decode('utf-8') # result = output[1].decode('utf-8') process = output.decode('utf-8') # result = output.decode('utf-8') websocket_callback(task_id, process) if exit_code != 0: process = 'run %s error , returncode = %d' % (command, exit_code) websocket_callback(task_id, process) print(process) # print(result) return process, exit_code
def test_angr_reaching_definitions(request): file_id, file_name, func_addr = ReqParams.many(request, ['file_id', 'file_name', 'func_addr.hex']) file_path = os.path.join(MyPath.samples(), file_name) project = angr.Project(file_path, load_options={'auto_load_libs': False}) # cfg = project.analyses.CFGFast() cfg = project.analyses.CFGEmulated() function = FunctionParse.func_by_addr(func_addr, cfg=cfg) tmp_kb = angr.KnowledgeBase(project) reaching_definition = project.analyses.ReachingDefinitions( subject=function, kb=tmp_kb, observe_all=True ) # nose.tools.assert_equal(reaching_definition.subject.__class__ is Subject, True) def _result_extractor(rda): unsorted_result = map( lambda x: {'key': x[0], 'register_definitions': x[1].register_definitions._storage, 'stack_definitions': x[1].stack_definitions._storage, 'memory_definitions': x[1].memory_definitions._storage}, rda.observed_results.items() ) return list(sorted( unsorted_result, key=lambda x: x['key'] )) result = _result_extractor(reaching_definition) pass
def load_default_virtual_packs(file_name=''): # 如果没有给定文件名称,则使用默认文件列表 if len(file_name) == 0: file_name_list = [ 'msvc_cfg_0_debug.exe', 'CADET_00002', '1.6.26-libjsound.so', 'ais3_crackme', 'bash', 'datadep_test', 'opkg', 'regedit.exe', 'true' ] else: file_name_list = [file_name] pack_list = [] for file_name in file_name_list: # 从 samples 文件中读取文件内容 file_path = os.path.join(MyPath.samples(), file_name) file_data = MyFile.read(file_path) # 添加虚拟包和可执行文件记录及数据存储 pack_id, exec_file_id = PackProcessService.add_single_exec( file_name, file_data) # 验证是否可执行文件,并分析 arch PackFiles.start_exec_bin_verify_task(pack_id) pack_list.append({'pack_id': pack_id, 'file_id': exec_file_id}) return pack_list
def test_bin_info(request): file_name, load_options = ReqParams.many(request, ['file_name', 'load_options.int']) file_path = os.path.join(MyPath.samples(), 'bin', file_name) # bw_result = binwalk.scan(file_path, signature=True, opcodes=True) bw_result = binwalk.scan('--signature', '--opcodes', file_path) bw_result = binwalk.scan('--signature', file_path) return sys_app_ok_p({}) if load_options == 1: proj = angr.Project(file_path, load_options={ 'main_opts': { 'backend': 'blob', 'base_addr': 0x10000, 'entry_point': 0x10000, 'arch': 'ARM', 'offset': 0, } }) else: # proj = angr.Project(file_path) proj = angr.Project(file_path, load_options={'auto_load_libs': False, 'main_opts': {}, }) boyscout = proj.analyses.BoyScout() # proj2 = angr.Project(file_path, arch=angr.SimARM(endness="Iend_BE"), # load_options={ # 'backend': 'blob', # 'base_addr': 0x10000, # 'entry_point': 0x10000, # 'arch': 'ARM', # 'offset': 0, # }) # girlscout = proj2.analyses.GirlScout(pickle_intermediate_results=True) return sys_app_ok_p({'arch': boyscout.arch, 'endianness': boyscout.endianness})
def test_angr_backward_slice(request): file_name, func_addr = ReqParams.many(request, ['file_name', 'func_addr.hex']) file_path = os.path.join(MyPath.samples(), file_name) project = angr.Project(file_path, load_options={"auto_load_libs": False}) cfg = project.analyses.CFGEmulated(keep_state=True, state_add_options=angr.sim_options.refs, context_sensitivity_level=2) cdg = project.analyses.CDG(cfg) ddg = project.analyses.DDG(cfg) target_node = cfg.get_any_node(func_addr) bs = project.analyses.BackwardSlice(cfg, cdg=cdg, ddg=ddg, targets=[(target_node, -1)]) # bs.dbg_repr() node_has_type = False for node in bs.taint_graph.nodes(): # param taint_type: Type of the taint, might be one of the following: 'reg', 'tmp', 'mem'. # print(node.stmt_idx) if hasattr(node, 'type'): print(node.type) node_has_type = True # if n.type == taint_type and n.addr == simrun_addr and n.stmt_id == stmt_idx: # taint = n print('node type %s found' % ('' if node_has_type else 'not')) # VSA_DDG # vsa_ddg = project.analyses.VSA_DDG() return sys_app_ok()
def export(file_id, file_name=None, folder=None, override=False): # 在存储桶中读取文件记录 grid_out = fw_files_storage.find_one({'filename': file_id}) item = SysUtils.grid_out_to_dict(grid_out) if item is None: return None # 设置文件路径,默认文件导出到临时目录 if file_name is None: file_name = item['filename'] if folder is None: folder = MyPath.temporary() file_path = os.path.join(folder, file_name) # 不设置覆写时,如果文件已存在,则跳过文件创建和写数据的操作 if not override and MyFile.exist(file_path): return file_path # 读取文件数据 data = grid_out.read() # 创建文件并写入数据 with open(file_path, 'wb') as file: file.write(data) return file_path
def test_angr_constraints(request): # state 的 constraints file_id, file_name, func_addr = ReqParams.many(request, ['file_id', 'file_name', 'func_addr.hex']) file_path = os.path.join(MyPath.samples(), file_name) project = angr.Project(file_path, load_options={"auto_load_libs": False}) cfg = project.analyses.CFG() return sys_app_ok()
def cdg_graph(self): project = self.angr_proj.proj cfg = CFGAnalyze.emulated_normal(self.angr_proj.proj, self.func_addr) cdg = project.analyses.CDG(cfg=cfg, start=self.func_addr) # 将控制依赖图生成到一个随机文件名的 png 中 graph_file = os.path.join(MyPath.temporary(), StrUtils.uuid_str()) plot_cdg(cfg, cdg, graph_file, pd_edges=True, cg_edges=True) # 读取文件内容的b64编码结果并返回 return MyFile.read_and_b64encode(graph_file + '.png')
def test_angr_plot_graph(request): file_id, file_name, func_addr = ReqParams.many(request, ['file_id', 'file_name', 'func_addr.hex']) if len(file_id) == 0: if len(file_name) == 0: return sys_app_err_p('INVALID_REQ_PARAM', 'file_id 或 file_name 必填其一') file_path = os.path.join(MyPath.samples(), file_name) project = angr.Project(file_path, load_options={'auto_load_libs': False}) start_state = project.factory.blank_state(addr=func_addr) start_state.stack_push(0x0) with hook0(project): cfg = project.analyses.CFGEmulated(fail_fast=True, starts=[func_addr], initial_state=start_state, context_sensitivity_level=2, keep_state=True, call_depth=100, normalize=True) graph_file = os.path.join(MyPath.temporary(), StrUtils.uuid_str()) plot_cfg(cfg, graph_file, asminst=True, vexinst=False, func_addr={func_addr: True}, debug_info=False, remove_imports=True, remove_path_terminator=True) else: func_parse = FunctionParse(file_id, func_addr) content = func_parse.cfg_graph() return sys_app_ok()
def test_angr_identifier(request): file_id, file_name, func_addr = ReqParams.many(request, ['file_id', 'file_name', 'func_addr.hex']) file_path = os.path.join(MyPath.samples(), file_name) project = angr.Project(file_path, load_options={"auto_load_libs": False}) # p = angr.Project(os.path.join(bin_location, "tests", "i386", "identifiable")) idfer = project.analyses.Identifier(require_predecessors=False) seen = dict() for addr, symbol in idfer.run(): seen[addr] = symbol return sys_app_ok()
def _get_fw_file_path(index): # 不能识别的 ID,不做处理 if index not in LoadDefaultPack.default_file_list: return None # 测试用固件文件的根目录 root_path = MyPath.firmware() fw_path = root_path for path in LoadDefaultPack.default_file_list[index]['paths']: fw_path = os.path.join(fw_path, path) file_name = LoadDefaultPack.default_file_list[index]['file_name'] return os.path.join(fw_path, file_name)
def cg_graph(self, verbose=True): cfg = CFGAnalyze.emulated_cg(self.angr_proj.proj, self.func_addr) # 将函数调用关系图生成到一个随机文件名的 png 中 graph_file = os.path.join(MyPath.temporary(), StrUtils.uuid_str()) # graph_file = StrUtils.uuid_str() set_plot_style('kyle') plot_cg(self.angr_proj.proj.kb, graph_file, format="png", verbose=verbose) # 读取文件内容的b64编码结果并返回 contents = MyFile.read_and_b64encode(graph_file + '.png') return contents
def test_angr_cfg(request): file_name = ReqParams.one(request, 'file_name') file_path = os.path.join(MyPath.samples(), file_name) project = angr.Project(file_path, load_options={'auto_load_libs': False}) main_symbol = project.loader.main_object.get_symbol('main') start_addr = main_symbol.rebased_addr start_state = project.factory.blank_state(addr=start_addr) start_state.stack_push(0x0) project.factory.full_init_state(add_options={angr.options.STRICT_PAGE_ACCESS, angr.options.ENABLE_NX, angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY, angr.options.USE_SYSTEM_TIMES}) cfg = project.analyses.CFG() functions = cfg.kb.functions return sys_app_ok_p(functions)
def async_com_download(request): com_download_url = ReqParams.one(request, 'url', protocol='POST') # 启动下载任务 extra_info = {'task_type': TaskType.REMOTE_DOWNLOAD, 'task_name': '组件源码下载', 'task_desc': '下载组件源码入库存储桶'} task = MyTask(_proc_component_tasks, (com_download_url, MyPath.component()), extra_info=extra_info) task_id = task.get_task_id() # 保存操作日志 LogRecords.save({'task_id': task_id}, category='download', action='组件源码下载', desc='下载组件源码入库存储桶') # 返回响应:任务初始化的信息 return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
def open(self, file_path): try: folder = MyPath.temporary() self.file_extract_dir = os.path.join(folder, "cramfs") print(self.file_extract_dir) # cramfsck only for linux cmds = "cramfsck -x " + self.file_extract_dir + " " + file_path print(cmds) ret = subprocess.call(cmds, shell=True) except OSError as e: # 格式错误时,镜像对象设置为无效 self.image = None print("cramfsck error", e)
def testcmd(request): process, result = runcmd('pwd') process, result = runcmd('ls -l') # # cmd = ReqParams.one(request, 'url', protocol='GET') # cmd = 'tar -xzvf ' + 'openssl-1.0.0s.tar.gz' # # process, result = runcmd(cmd, MyPath.component()) # process, result = runcmd(cmd) work_path = MyPath.component() + '/openssl-1.0.0s' testfile = work_path + '/CHANGES' SysUtils.chmod(testfile, "777") # save_make_files('18e2f698-487a-47d4-9bf0-3c33d7a78320', work_path) # return # cmd = MyPath.component() + '/openssl-1.0.0s/' + 'CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar RANLIB=arm-linux-gnueabihf-ranlib ./Configure no-asm shared --prefix=/usr/local/arm/openssl linux-armv4' # cmd = '/bin/sh -c CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar RANLIB=arm-linux-gnueabihf-ranlib ./Configure no-asm shared --prefix=/usr/local/arm/openssl linux-armv4' # runcmd(cmd, work_path) # cmd = '/bin/sh -c CC=arm-linux-gnueabihf-gccCXX=arm-linux-gnueabihf-g++AR=arm-linux-gnueabihf-arRANLIB=arm-linux-gnueabihf-ranlib ./Configure no-asm shared --prefix=/usr/local/arm/openssl linux-armv4' # runcmd(cmd, work_path) # cmd = 'CC=arm-linux-gnueabihf-gcc RANLIB=arm-linux-gnueabihf-ranlib ./Configure --prefix=/usr/local/arm/openssl linux-armv4' cmd = './Configure --prefix=/usr/local/arm/openssl linux-armv4' runcmd( cmd, work_path, "{'CC':'arm-linux-gnueabihf-gcc', 'RANLIB':'arm-linux-gnueabihf-ranlib'}" ) cmd = '/bin/sh -c CC=arm-linux-gnueabihf-gccRANLIB=arm-linux-gnueabihf-ranlib ./Configure --prefix=/usr/local/arm/openssl linux-armv4' runcmd(cmd, work_path) tmp = tempfile.TemporaryFile() rval = subprocess.call(shlex.split(cmd), stdout=tmp, stderr=tmp) cmd = 'make' runcmd(cmd, work_path) # print(process) # print(result) # result = output[1].decode('utf-8') # print(result) return sys_app_ok_p({})
def cfg_graph(self, verbose=True): cfg = CFGAnalyze.emulated_normal(self.angr_proj.proj, self.func_addr) # 将控制流程图生成到一个随机文件名的 png 中 graph_file = os.path.join(MyPath.temporary(), StrUtils.uuid_str()) set_plot_style('kyle') plot_cfg( cfg, graph_file, asminst=True, vexinst=False, # func_addr={self.func_addr: True}, debug_info=verbose, remove_imports=True, remove_path_terminator=True, color_depth=True) # 读取文件内容的b64编码结果并返回 return MyFile.read_and_b64encode(graph_file + '.png')
def _test_func(file_name): file_path = os.path.join(MyPath.samples(), file_name) p = angr.Project(file_path) p.analyses.CFGEmulated() f_arg1 = p.kb.functions['arg1'] # SimCCSystemVAMD64 print(type(f_arg1.calling_convention)) print(len(f_arg1.arguments)) print(f_arg1.arguments[0].reg_name) # # f_arg7 = p.kb.functions['arg7'] # print(type(f_arg7.calling_convention)) # print(len(f_arg7.arguments)) # print(f_arg7.arguments[1].reg_name) f_arg9 = p.kb.functions['arg9'] print(type(f_arg9.calling_convention)) print(len(f_arg9.arguments)) print(f_arg9.arguments[8].stack_offset)
def test(request): value = ReqParams.one(request, 'value', protocol='GET') # 启动下载任务 extra_info = { 'task_type': TaskType.REMOTE_DOWNLOAD, 'task_name': 'test组件源码下载', 'task_desc': 'test下载组件源码入库存储桶' } task = MyTask(_proc_inverted_tasks, (value, MyPath.component()), extra_info=extra_info) task_id = task.get_task_id() # 保存操作日志 LogRecords.save({'task_id': task_id}, category='download', action='test组件源码下载', desc='test下载组件源码入库存储桶') # 返回响应:任务初始化的信息 return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
def test_angr_functions(request): file_name = ReqParams.one(request, 'file_name') file_path = os.path.join(MyPath.samples(), file_name) # --disasm # bw_result = binwalk.scan('--signature', file_path) # bw_result = binwalk.scan('--signature', '--opcodes', file_path) # bw_result = binwalk.scan('--signature', '--opcodes', '--disasm', file_path) # bw_result = binwalk.scan('--signature', '--disasm', file_path) # bw_result = binwalk.scan('--signature', '--opcodes', '--disasm', '--verbose', file_path) project = angr.Project(file_path, load_options={'auto_load_libs': False}) # project = angr.Project(file_path, load_options={ # 'auto_load_libs': False, # 'main_opts': { # 'backend': 'blob', # 'base_addr': 0x10000, # 'entry_point': 0x10000, # 'arch': 'MIPS32', # 'offset': 0, # } # }) cfg = project.analyses.CFGFast(resolve_indirect_jumps=True, force_complete_scan=False, normalize=True, # context_sensitivity_level=1, # enable_advanced_backward_slicing=False, # enable_symbolic_back_traversal=False ) items = cfg.kb.functions.items() functions = [] for addr, func in items: func_name = func.name if func_name == 'UnresolvableJumpTarget' or func_name == 'UnresolvableCallTarget': continue functions.append({'address': hex(addr), 'name': func.name}) return sys_app_ok_p({'count': len(functions), 'functions': functions})
def test_check_file_type(request): category = ReqParams.one(request, 'category') if len(category) == 0: # 未指定检查类型时,可执行文件和非可执行都检测一遍 check_exec = check_no_exec = True elif category == '1': # 指定'1'时,只检测非可执行文件 check_exec = False check_no_exec = True elif category == '2': # 指定'2'时,只检测可执行文件 check_exec = True check_no_exec = False else: return sys_app_ok_p( 'category=1,检测非可执行文件;category=2,检测可执行文件;category为空时,检测全部文件') results = [] if check_no_exec: files_list = [ 'image.bmp', 'image.gif', 'image.jpg', 'image.png', 'image.tif', 'image2.png', 'office.docx', 'office.pptx', 'office.xlsx', 'office2.docx', 'office2.xlsx', 'pdf.pdf', 'text.js', 'text.py', 'text.txt', 'zip.zip', 'zip2.zip', 'rar.rar', '7z.7z', 'tar.tar' ] for file_name in files_list: file_path = os.path.join(MyPath.samples(), 'bin', file_name) file_type, extra_props = FileTypeJudge.scan_file_type(file_path, quiet=False) results.append({ 'file_name': file_name, 'file_type': file_type, 'type_name': FileType.get_alias(file_type) }) if check_exec: files_list = [ 'libebt_standard.so', 'bash', 'regedit.exe', 'opkg', 'polkitd', 'true', 'ais3_crackme', 'r100', 'AcXtrnal.dll', 'WdNisDrv.sys', ] for file_name in files_list: file_path = os.path.join(MyPath.samples(), 'bin', file_name) file_type, extra_props = FileTypeJudge.scan_file_type(file_path, quiet=False) if file_type == FileType.EXEC_FILE: arch, endianness = ExecFile.parse_exec_arch(file_path, prefer=extra_props) else: arch = endianness = '' results.append({ 'file_name': file_name, 'file_type': file_type, 'type_name': FileType.get_alias(file_type), 'arch': arch, 'endianness': endianness, }) # break return sys_app_ok_p(results)
from utils.db.mongodb.pack_file import PackFileDO from utils.db.mongodb.pack_files_storage import PackFilesStorage from utils.gadget.general import SysUtils from utils.gadget.strutil import StrUtils from utils.http.response import sys_app_ok, sys_app_ok_p, sys_app_err from utils.gadget.my_path import MyPath pack_files_col = utils.sys.config.g_firmware_db_full["pack_files"] fw_files_col = utils.sys.config.g_firmware_db_full["fw_files"] file_inverted_col = utils.sys.config.g_firmware_db_full["file_inverted_index"] report_record_col = utils.sys.config.g_firmware_db_full["report_record"] component_files_col = utils.sys.config.g_firmware_db_full["component_files"] # 注册字体 # pdfmetrics.registerFont(TTFont('SimSun', 'simsun.ttc')) path_font = MyPath.work_root() + '/report/simsun.ttc' pdfmetrics.registerFont(TTFont('SimSun', path_font)) class Graphs: # def __init__(self): # pass @staticmethod def text_type(font_size, leading, text_color, alignment): style = getSampleStyleSheet() ct = style['Normal'] ct.fontName = 'SimSun' ct.fontSize = font_size
def getmakepath(file_name): # root, ext = os.path.splitext(file_name) dir = file_name.split('.tar.gz')[0] return os.path.join(MyPath.component(), dir)
def verify_exec_bin_file(file_path, content=None): if file_path is None: if content is None: return FileType.OTHER_FILE, None file_path = MyFile.write('verify_exec_' + StrUtils.uuid_str(), content, folder=MyPath.temporary()) # 疑似可执行文件,结合 binwalk 和 angr project 检验是否为可执行文件 file_type, extra_props = FileTypeJudge.scan_file_type(file_path) if file_type == FileType.EXEC_FILE: arch, endianness = ExecFile.parse_exec_arch(file_path, prefer=extra_props) return file_type, {'arch': arch, 'endianness': endianness} return file_type, None