def verify_all_exec_bin_files(self, pack_id, image_file_name, 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_path = FwFilesStorage.export(file_item['file_id'],
                                              file_name=task_id,
                                              override=True)
            file_type, extra_props = FsBase.verify_exec_bin_file(file_path)

            # 修改文件的类型属性,或增加可执行二进制文件的CPU架构
            # 暂时不更新存储桶中的“内容类型”
            FwFileDO.update_verified_file_type(file_item['file_id'],
                                               file_type,
                                               extra_props=extra_props)

        # 保存任务完成状态
        MyTask.save_exec_info(task_id, 100.0)

        # 完成验证二进制文件,启动任务cfg_analyze
        PackFiles.start_exec_bin_cfg_analyze_task(self.pack_id,
                                                  image_file_name)
예제 #2
0
 def stop_running_tasks_of_pack(pack_id):
     tasks_list = TasksDAO.search_by_pack(pack_id)
     for task_info in tasks_list:
         task_status = task_info['task_status']
         # 没有执行完成的任务状态,用缓存中任务信息代替
         if task_status == TaskStatus.START or task_status == TaskStatus.RUNNING:
             MyTask.stop_task(task_info['task_id'])
    def save_proc(self,
                  name,
                  path,
                  file_type,
                  content,
                  index,
                  total,
                  extra_props=None):
        name = str(name)
        file_id = StrUtils.uuid_str()

        # 保存文件参数
        FwFileDO.save_file_item(self.pack_id,
                                file_id,
                                name,
                                file_type,
                                file_path=path,
                                extra_props=extra_props)
        # 保存文件内容
        FwFilesStorage.save(file_id, name, path, file_type, content)

        percent = (index + 1) * 100.0 / total
        MyTask.save_task_percentage(self.task_id, percent)

        return not MyTask.is_task_stopped(self.task_id)
def _proc_func_info(file_id, func_addr, task_id):
    # 通过 project 快速解析文件
    angr_proj = AngrProj(file_id,
                         progress_callback=run_percent_cb,
                         task_id=task_id)

    # 生成函数解析对象
    func_parse = FwFuncParse(angr_proj)

    # 读取函数的汇编代码
    asm = func_parse.func_asm(func_addr)
    # print(asm)

    # 读取函数的中间代码
    vex = func_parse.func_vex(func_addr)
    # print(vex)

    # 获取函数的后继调用
    successors = func_parse.func_successors(func_addr)
    # print(successors)

    # 保存执行完成后的状态和结果集
    MyTask.save_exec_info(
        task_id, 100.0, {
            'asm': str(asm),
            'vex': str(vex),
            'successors_count': len(successors),
            'successors': successors
        })

    return
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))
예제 #6
0
 def auto_cfg_task():
     cfg_analyze = CfgAnalyzeService('')
     extra_info = {
         'task_type': TaskType.CFG_ANALYZE,
         'task_name': '控制流分析',
         'task_desc': '进行控制流分析,保存 CFG graph 和函数列表。'
     }
     task = MyTask(cfg_analyze.analyze_cfg_proc_auto, extra_info=extra_info)
     # task = MyTask(cfg_analyze.analyze_cfg_proc_auto,)
     return task.get_task_id()
 def start_detect_task(file_id):
     detect = OverflowDetectService(file_id)
     extra_info = {
         'file_id': file_id,
         'task_type': TaskType.DETECT_OVERFLOW,
         'task_name': '检测漏洞溢出',
         'task_desc': '检测漏洞溢出,保存 缓冲区 整数 命令注入溢出输入数据。'
     }
     task = MyTask(detect.detect_overflow_proc, (file_id, ),
                   extra_info=extra_info)
     return task.get_task_id()
예제 #8
0
 def start_remove_packs_task(pack_id):
     pack_proc_serv = PackProcessService()
     extra_info = {
         'pack_id': pack_id,
         'task_type': TaskType.REMOVE_FW_PACKS,
         'task_name': '清空固件包',
         'task_desc': '清空指定固件包(ID: {})下的所有文件项,并删除其文件内容。'.format(pack_id)
     }
     task = MyTask(pack_proc_serv.remove_pack_proc, (pack_id, ),
                   extra_info=extra_info)
     return task.get_task_id()
예제 #9
0
 def start_cfg_task(file_id):
     cfg_analyze = CfgAnalyzeService(file_id)
     extra_info = {
         'file_id': file_id,
         'task_type': TaskType.CFG_ANALYZE,
         'task_name': '控制流分析',
         'task_desc': '进行控制流分析,保存 CFG graph 和函数列表。'
     }
     task = MyTask(cfg_analyze.analyze_cfg_proc, (file_id, ),
                   extra_info=extra_info)
     return task.get_task_id()
예제 #10
0
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 async_function_call_graph(request):
    # 从请求中取参数:文件 ID,函数地址
    file_id, func_addr = _req_params(request)

    # 启动分析任务
    task = MyTask(_proc_func_call_graph, (
        file_id,
        func_addr,
    ))
    task_id = task.get_task_id()

    # 返回响应:任务初始化的信息
    return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
    def run_percent_cb(self, percentage, **kwargs):
        if self.task_id is None:
            return

        task_id = self.task_id

        # 调试信息打印
        # info = 'Func-list({}): {}%'.format(task_id, percentage)
        # print(info)
        # print(self.task_id)

        # 只在运行百分比变化时才更新任务状态
        MyTask.save_task_percentage(task_id, percentage)
예제 #13
0
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))
예제 #14
0
def _proc_compile_tasks(arch, pack_id, task_id):

    # 1 DB中导出源码文件/目录
    path, file_name = export_files(pack_id)
    print(path)
    if path is None:
        print("export_files error")
        MyTask.save_exec_info(task_id, 0, {'compile': "组件源码编译失败,导出组件库源码失败"})
        PackCOMFileDO.set_compile_flag(pack_id, CompileStatus.failed)

        return

    MyTask.save_exec_info_name(task_id, file_name)

    # cmd = 'tar -xzvf ' + file_name
    # runcmd(cmd)

    # 2 make
    if arch == 'x86':
        build_path, exit_code = compile_x86(file_name, task_id)
    elif arch == 'arm':
        build_path, exit_code = compile_arm(file_name, task_id)

    if exit_code != 0:
        MyTask.save_exec_info(task_id, 100, {'compile': "组件源码编译操作失败"})
        return

    # 3 save make file to db
    save_make_files(pack_id, build_path, arch)

    # 4 set compile flag
    PackCOMFileDO.set_compile_flag(pack_id, CompileStatus.success)

    total_percentage = 100.0
    MyTask.save_exec_info(task_id, total_percentage, {'compile': "组件源码编译操作完成"})
    def start_fs_image_extract_task(pack_id):
        fs_image = FsImage(pack_id)
        # if fs_image.image is None:
        #     return

        extra_info = {
            'pack_id': pack_id,
            'task_type': TaskType.FS_EXTRACT,
            'task_name': '文件系统解析',
            'task_desc': '从文件系统镜像包中提取文件,判断文件类型,并保存文件内容到数据库中。'
        }
        task = MyTask(fs_image.fs_image_extract, (pack_id, ),
                      extra_info=extra_info)
        return task.get_task_id()
def _proc_func_call_graph(file_id, func_addr, task_id):
    # 生成 project 对象,但不做 cfg_fast 解析
    angr_proj = AngrProj(file_id,
                         cfg_mode='cfg_emu',
                         progress_callback=run_percent_cb,
                         task_id=task_id)

    # 解析并生成调用流程图的数据
    func_parse = FwFuncParse(angr_proj)
    graph = func_parse.call_graph(func_addr)

    # 保存执行完成后的状态和结果集
    b64_graph = base64.b64encode(graph).decode()
    MyTask.save_exec_info(task_id, 100.0, {'call_graph': b64_graph})
    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)
예제 #18
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 _proc_fw_functions_list(file_id, task_id):
    cfg_progress = CfgProgress(task_id=task_id)
    # 通过 project 快速解析文件
    angr_proj = AngrProj(file_id,
                         progress_callback=cfg_progress.run_percent_cb,
                         task_id=task_id)

    # 获取代码中的函数列表
    func_parse = FwFuncParse(angr_proj)
    functions = func_parse.func_list()

    # 保存执行完成后的状态和结果集
    MyTask.save_exec_info(task_id, 100.0, {
        'functions_count': len(functions),
        'functions': functions
    })
def auto_vuler_association(request):
    pack_id = ReqParams.one(request, 'pack_id')
    task_id = start_check_component_task(pack_id)
    if task_id is None:
        return sys_app_ok_p("自动组件漏洞关联正在运行中")

    return sys_app_ok_p(MyTask.fetch_exec_info(task_id))
    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 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)
예제 #23
0
def async_fwdownload(request):
    # 获取下载URL
    fw_download_url, ftp_user, ftp_password = ReqParams.many(request, ['url', 'user', 'password'], protocol='POST')

    # 启动下载任务
    extra_info = {'task_type': TaskType.REMOTE_DOWNLOAD,
                  'task_name': '固件下载',
                  'task_desc': '下载固件入库存储桶并进行文件抽取操作'}
    task = MyTask(_proc_tasks, (fw_download_url, settings.FW_PATH, ftp_user, ftp_password), 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))
예제 #24
0
def _proc_tasks(fw_download_url, g_fw_save_path, ftp_user, ftp_password, task_id):
    print("download task_id", task_id)
    # 检查本地保存路径 没有则创建
    SysUtils.check_filepath(g_fw_save_path)

    # 1 时间消耗总占比30  执行下载操作
    total_percentage = 30.0
    ret_download_info = fw_filename = ""
    file_list = []

    if 'ftp://' in fw_download_url:
        ret_download_info, fw_filename, file_list = Mydownload.ftp_download(fw_download_url, g_fw_save_path, ftp_user,
                                                                            ftp_password, task_id, total_percentage)
    else:
        ret_download_info, fw_filename, file_list = Mydownload.http_download(fw_download_url, g_fw_save_path, task_id,
                                                                             total_percentage)

    print(ret_download_info, fw_filename)
    MyTask.save_exec_info_name(task_id, fw_filename)

    # 2 时间消耗总占比0 保存到 pack_file to mongodb
    pack_id, pack_file_id = _save_pack_db(fw_download_url, os.path.join(g_fw_save_path, fw_filename), ret_download_info,
                                          task_id)
    MyTask.save_exec_info_pack_id(task_id, pack_id)

    # 3 时间消耗总占比0 解压缩固件包->系统镜像文件,提取文件到mongo
    img_filename = _proc_uncompress(os.path.join(g_fw_save_path, fw_filename), g_fw_save_path, task_id)
    if len(img_filename) == 0:
        print("package uncompress error")
        img_filename = fw_filename  # bin文件做为包名(文件名)
        # return "package uncompress error"

    # 4 时间消耗总占比0 保存系统镜像文件 to mongodb
    file_id = _save_file_db(os.path.join(g_fw_save_path, img_filename), pack_id)

    # 5 时间消耗总占比40 BIN提取子文件
    total_percentage = 70.0
    extract_bin_files = MyBinwalk.binwalk_file_extract(os.path.join(g_fw_save_path, img_filename))
    MyTask.save_exec_info(task_id, total_percentage, {'binwalk_file_extract': extract_bin_files})

    for file in extract_bin_files:
        # binwalk解包返回的文件名带全路径
        # 对变量类型进行判断 list 值带[] 如: ['C:\\GIT\\firmware_analyze_serv\\files\\firmware\\_CF-EW71-V2.6.0.bin-2.extracted\\40']
        if isinstance(file, list):
            file_id = _save_file_db(file[0], pack_id)
        else:
            file_id = _save_file_db(file, pack_id)

    # 6 时间消耗总占比30 提取文件系统
    FsImage.start_fs_image_extract_task(pack_id)

    total_percentage = 100.0
    MyTask.save_exec_info(task_id, total_percentage, {'download': "固件下载、提取、入库操作完成"})

    # 7 clear temp files
    return 'ERROR_OK'
    def run_percent_cb(self, percentage, **kwargs):
        # 由于大于50%进程后没有 project 可以获取,需要做进度百分比转换
        # if 'cfg' in kwargs:
        #     if 'cfg' in kwargs:
        # 从动态参数中获取 project 中保存的任务 ID
        # task_id = kwargs['cfg'].project.my_task_id

        task_id = self.task_id

        # 调试信息打印
        info = 'Func-list({}): {}%'.format(task_id, percentage)
        print(info)
        print(self.task_id)

        # 只在运行百分比变化时才更新任务状态
        new_percentage = self.translate_percent(percentage)
        exec_info = MyTask.fetch_exec_info(task_id)
        old_percentage = exec_info['percentage']
        if new_percentage != old_percentage:
            MyTask.save_exec_info(task_id, new_percentage)
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 start_check_component_task(pack_id):

    # 检查组件关联是否运行,运行中则跳过
    isrun = MyRedis.get('running_check_com_flag')
    if isrun:
        return None

    # # 检查组件关联
    # check_component(pack_id, FileType.EXEC_FILE)
    # 修改为任务处理方式进行检查组件关联 关联组件标记,相似度匹配计算,标记漏洞(version/edbid)
    # 启动编译任务
    extra_info = {
        'task_type': TaskType.COMPONENT_CHECK,
        'task_name': '组件文件漏洞自动关联',
        'task_desc': '检查组件关联,相似度匹配计算,标记漏洞(version/edbid)'
    }

    task = MyTask(check_component, (pack_id, ), extra_info=extra_info)
    task_id = task.get_task_id()
    return task_id
예제 #28
0
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 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)
예제 #30
0
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))