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 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 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)
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
Example #5
0
    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 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)
Example #7
0
 def _get_arch(self, file_id):
     file_item = FwFileDO.find(file_id)
     # if file_item['extra_props'] is None or file_item['extra_props']['arch'] is None:
     if file_item.get('extra_props') is None:
         return 'ARM', None
     else:
         return file_item['extra_props'].get(
             'arch'), file_item['extra_props'].get('endianness')
def pack_exec_files_tree(request):
    pack_id, tree_type = ReqParams.many(request, ['pack_id', 'tree_type'])

    start_check_component_task(pack_id)
    # # # 检查组件关联
    # # 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()

    # 读取所有可执行文件
    exec_list = FwFileDO.search_files_of_pack(pack_id, FileType.EXEC_FILE)

    if tree_type is None or len(tree_type) == 0 or tree_type == 'normal':
        # file_path_insert_into_tree 树,初始化为字典
        tree_type = 'normal'
        exec_tree = {}
    elif tree_type == 'antd':
        # file_path_insert_into_antd_tree 树,初始化为数组
        exec_tree = []
    else:
        tree_type = 'normal'
        exec_tree = {}

    # 对每个文件做树的各级节点定位和创建
    for exec_file in exec_list:
        # 获取文件路径
        file_path = exec_file['file_path']
        file_id = exec_file['file_id']

        component = exec_file['component']
        # if exec_file['component'] is not None:
        #     component = exec_file['component']
        # else:
        #     component = 0

        if file_path is None or len(file_path) == 0:
            continue

        if tree_type == 'normal':
            MyTree.file_path_insert_into_tree(exec_tree, file_path, file_id,
                                              component)
        elif tree_type == 'antd':
            MyTree.file_path_insert_into_antd_tree(exec_tree, file_path,
                                                   file_id, component)

    # 保存操作日志
    LogRecords.save('',
                    category='statistics',
                    action='读取固件包文件结构',
                    desc='获取指定固件包(ID=%s)的文件结构(模式为:%s)' % (pack_id, tree_type))

    return sys_app_ok_p(exec_tree)
Example #9
0
    def has_cfg_analyze(file_id):
        try:
            item = FwFileDO.find(file_id)
            item['cfg_analyze'] == 1
        except Exception as e:
            # print(e)
            return False

        return True
Example #10
0
    def analyze_cfg_proc(self, file_id, task_id):
        self.task_id = task_id

        # 通过 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)

        print(str(angr_proj.proj.arch))
        arch = str(angr_proj.proj.arch)
        # 设置文件已完成 CFG 分析的标记
        FwFileDO.set_cfg_analyzed(file_id, 1, arch)
    def has_detect_overflow(file_id):
        try:
            item = FwFileDO.find(file_id)
            if item['file_detect_overflow'] == 1:
                return True
        except Exception as e:
            # print(e)
            return False

        return False
def com_files_list(request):
    # 读取所有组件文件
    com_list = FwFileDO.search_all_com_files()
    print(com_list)
    comlist = []

    for com in com_list:
        print(com)
        inverted = com.get('inverted')
        cfg_analyze = com.get('cfg_analyze')
        file_type_verified = com.get('file_type_verified')
        extra_props = com.get('extra_props')

        if extra_props is not None:
            extra_props.setdefault('name', '')
            extra_props.setdefault('version', '')
            extra_props.setdefault('edb_id', '')
            extra_props.setdefault('similarity', '')

            name = extra_props['name']
            version = extra_props['version']
            edb_id = extra_props['edb_id']
            similarity = extra_props['similarity']
        else:
            name = ""
            version = ""
            edb_id = ""
            similarity = ""

        doc = {
            'file_id': com['file_id'],
            'file_path': com['file_path'],
            'component': com['component'],
            'create_time': com['create_time'],
            'file_name': com['file_name'],
            'file_type': com['file_type'],
            'pack_id': com['pack_id'],
            'version': version,
            'name': name,
            'edb_id': edb_id,
            'file_type_verified': file_type_verified,
            'cfg_analyze': cfg_analyze,
            'inverted': inverted,
            'similarity': similarity,
            'fw_name': com['pack_docs'][0]['name']
        }
        comlist.append(doc)

    # 保存操作日志
    LogRecords.save('',
                    category='statistics',
                    action='查询所有组件文件列表',
                    desc='查询所有组件文件列表')
    return sys_app_ok_p(comlist)
Example #13
0
    def _save_image(file_index, pack_id):
        # 获取 文件的路径和文件类型
        file_path = LoadDefaultPack._get_fw_file_path(file_index)
        if file_path is None:
            return None

        # 文件类型
        file_type = LoadDefaultPack._get_file_type(file_index)

        # 新的文件 UUID
        file_id = StrUtils.uuid_str()
        # 读取文件内容
        contents = MyFile.read(file_path)
        # 保存文件记录
        FwFileDO.save_file_item(pack_id, file_id, os.path.basename(file_path),
                                file_type)
        # 保存文件内容
        FwFilesStorage.save(file_id, os.path.basename(file_path),
                            os.path.basename(file_path), file_type, contents)

        return file_id
Example #14
0
def _save_file_db(path_file_name, pack_id):
    # 获取 文件的路径和文件类型
    # file_path = _get_fw_file_path(virtual_id)
    # if file_path is None:
    #     return None
    #
    print(path_file_name)
    file_path, file_name = os.path.split(path_file_name)
    # 新的文件 UUID
    file_id = StrUtils.uuid_str()
    # 获取文件类型 内容
    file_type, contents = check_file_type(path_file_name)
    # file_type = _get_file_type(file_name)
    if contents is None:  # linux 系统下 BINWALK会提取出空目录,读目录文件为None
        return None
    # 保存文件记录
    FwFileDO.save_file_item(pack_id, file_id, file_name, file_type, file_path)
    # 保存文件内容
    FwFilesStorage.save(file_id, file_name, file_path, file_type, contents)

    # 返回文件ID
    return file_id
Example #15
0
    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
Example #16
0
    def analyze_cfg_proc_auto(self, task_id):
        # 查询所有文件
        list_file_id = FwFileDO._db_get_all_file(FileType.EXEC_FILE)
        for file in list_file_id:
            # print(file)
            file_id = file['file_id']

            is_cfg = CfgAnalyzeService.has_cfg_analyze(file_id)
            if not is_cfg:
                # 启动分析任务
                self.task_id = task_id
                self.file_id = file_id

                try:

                    # 通过 project 快速解析文件
                    angr_proj = AngrProj(file_id,
                                         progress_callback=self.run_percent_cb,
                                         task_id=task_id,
                                         cfg_mode='cfg_fast')
                    # angr_proj = AngrProj(file_id, progress_callback=self.run_percent_cb, cfg_mode='cfg_fast')

                    # 从 project 中提取函数列表
                    functions = FunctionParse.functions_extract(angr_proj.proj)

                    # 保存 函数列表到数据库
                    FileCacheDAO.save_functions(file_id, functions)

                    print(str(angr_proj.proj.arch))
                    arch = str(angr_proj.proj.arch)
                    # 设置文件已完成 CFG 分析的标记
                    FwFileDO.set_cfg_analyzed(file_id, 1, arch)
                    # PackFileDO.updateArch(arch)

                    time.sleep(1)
                except Exception as e:
                    print(e)
Example #17
0
    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)
Example #18
0
    def get_unpack_files_stat(self):
        pack_id = self.pack_id
        file_type_list = PackInfoService._file_type_list()

        unpack_files = {}
        for file_type in file_type_list:
            # 不统计固件包的文件数量
            if file_type == FileType.PACK:
                continue

            # 获取文件类型的别名
            alias = FileType.get_alias(file_type)

            # 统计指定类型文件的数量
            count = FwFileDO.count_files(pack_id, file_type)
            unpack_files[str(file_type)] = {'alias': alias, 'count': count}

        fw_files = {'unpack_files': unpack_files}
        return fw_files
def vuler_association(request):
    print('vuler_association')
    file_id, version, name, edb_id = ReqParams.many(
        request, ['file_id', 'version', 'name', 'edb_id'])

    rv = FwFileDO.set_component_extra_props(file_id, {
        'version': version,
        'name': name,
        'edb_id': edb_id
    })

    # 保存操作日志
    LogRecords.save('',
                    category='statistics',
                    action='组件手动漏洞关联',
                    desc='组件手动漏洞关联(漏洞编号 版本 名称)')

    if rv.matched_count == 1:
        return sys_app_ok_p('组件手动漏洞关联成功')
    else:
        return sys_app_ok_p('组件手动漏洞关联失败,文件未找到')
def com_files_tree(request):
    tree_type = ReqParams.one(request, 'tree_type')
    # 读取所有组件文件
    com_list = FwFileDO.search_all_com_files()

    if tree_type is None or len(tree_type) == 0 or tree_type == 'normal':
        tree_type = 'normal'
        exec_tree = {}
    elif tree_type == 'antd':
        exec_tree = []
    else:
        tree_type = 'normal'
        exec_tree = {}

    # 对每个文件做树的各级节点定位和创建
    for exec_file in com_list:
        # 获取文件路径
        file_path = exec_file['file_path']
        file_id = exec_file['file_id']

        component = exec_file['component']

        if file_path is None or len(file_path) == 0:
            continue

        if tree_type == 'normal':
            MyTree.file_path_insert_into_tree(exec_tree, file_path, file_id)
        elif tree_type == 'antd':
            MyTree.file_path_insert_into_antd_tree(exec_tree, file_path,
                                                   file_id)

    # 保存操作日志
    LogRecords.save('',
                    category='statistics',
                    action='查询所有组件文件目录树',
                    desc='获取所有组件文件目录树结构(模式为:%s)' % (tree_type))

    return sys_app_ok_p(exec_tree)
    def open_image(self):
        # 查找指定包的 FS 镜像文件
        file_docs = FwFileDO.search_files_of_pack(self.pack_id,
                                                  FileType.FS_IMAGE)
        if len(file_docs) == 0:
            print("find nothing file_docs")
            return
        # 只取第一个镜像文件
        image_file = file_docs[0]

        # 导出镜像文件到临时目录
        image_file_path = FwFilesStorage.export(image_file['file_id'])

        # 返回实际文件名 任务对应文件名
        image_file_name = image_file['file_name']

        # 解析镜像文件
        image, fs = self.parse_image_file(image_file, image_file_path)
        # 尝试 SquashFS 解析,并验证
        # image = SquashFS(image_file_path)
        # if image.check_format():
        #     pass
        return image, image_file_name, fs
def detect_vulner(request):
    file_id = ReqParams.one(request, 'file_id')
    # pack_id = ReqParams.one(request, 'pack_id')
    # fw_vul_analyze = FwVulnerAnalyze(file_id)
    # res = fw_vul_analyze.vuler_analyze()
    # return sys_app_ok_p({'res': res})

    # 查询文件 detect 分析的标记
    is_detect = OverflowDetectService.has_detect_overflow(file_id)
    if not is_detect:
        # 启动detect任务
        task_id = OverflowDetectService.start_detect_task(file_id)
        # 保存操作日志
        LogRecords.save({
            'task_id': task_id,
            'file_id': file_id
        },
                        category='analysis',
                        action='分析OVERFLOW',
                        desc='对二进制文件做溢出漏洞分析')

        # 返回响应:任务初始化的信息
        return sys_app_ok_p(MyTask.fetch_exec_info(task_id))

    file_item = FwFileDO.find(file_id)
    buffer_overflow = file_item.get('buffer_overflow')
    integer_overflow = file_item.get('integer_overflow')
    cmd_injection_overflow = file_item.get('cmd_injection_overflow')
    # return sys_app_ok_p({'缓冲区溢出': buffer_overflow, '整数溢出': integer_overflow, '命令注入溢出': cmd_injection_overflow})

    overflow_list = []
    overflow_list.append({"name": "缓冲区溢出", "value": buffer_overflow})
    overflow_list.append({"name": "整数溢出", "value": integer_overflow})
    overflow_list.append({"name": "命令注入溢出", "value": cmd_injection_overflow})

    return sys_app_ok_p({'overflow': overflow_list})
 def detect(self):
     type_name, buffer_overflow = Overflow_Detect.buffer_overflow(self)
     FwFileDO.set_file_detect_overflow(self.file_id, buffer_overflow, None,
                                       None)
     return buffer_overflow
Example #24
0
    def inverted(self, file_id):

        file_result = fw_files_col.find({'file_id': file_id})
        file_list = list(file_result)

        if file_list is None or len(file_list) == 0:
            return sys_app_err('ERROR_INVALID_PARAMETER')

        filePo = file_list[0]
        file_path = filePo.get('file_path')

        # file_path = 'E:/samples/argv_test'
        # file_path = 'E:/samples/py_code.txt'

        dict1 = {}
        dict2 = {}
        sentences = InvertedIndex.read_file(self, file_path)

        sentencesLen = len(sentences)

        for i in range(sentencesLen):
            sentence = sentences[i]
            for word in sentence:
                if word == '':
                    continue
                if word.lower() not in dict1:
                    dict1[word.lower()] = set()  # new word
                    dict2[word.lower()] = 1
                else:
                    dict2[word.lower()] += 1
                dict1[word.lower()].add(i + 1)  # update for dictionary

        answer_list = sorted(dict2.items(), key=lambda d: d[1],
                             reverse=True)  # Sort by wordcount of dictionary.
        answer_sort_ascll = sorted(answer_list, key=lambda x: x[0])

        for word in answer_sort_ascll:
            word0 = InvertedIndex.str_to_hex(word[0]).replace('/x0', '')
            sort_dotid = sorted(dict1[word[0]])

            position = ''
            for i in range(len(sort_dotid)):
                position += str(sort_dotid[i])
                if i != (len(sort_dotid) - 1):
                    position += ','

            index_con = word0
            index_con_str = InvertedIndex.hex_to_str(word0)
            appear_total = word[1]

            vulner_info = {
                'file_id': file_id,
                'file_path': file_path,
                'index_con': index_con,
                'appear_total': appear_total,
                'position': position
            }

            result = file_inverted_col.find({
                'file_id': file_id,
                'index_con': index_con,
                'appear_total': appear_total
            })
            item_list = list(result)

            if (item_list is None or len(item_list)
                    == 0) and len(index_con) > 0 and len(index_con_str) > 10:
                file_inverted_col.save(vulner_info)

        # 对组件列表增加建立 inverted 完成标志
        FwFileDO.set_inverted(file_id)

        return sys_app_ok()