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
Example #3
0
    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()
Example #8
0
    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()
Example #11
0
    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)
Example #12
0
    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)
Example #14
0
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({})
Example #17
0
    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