Beispiel #1
0
def main():
    '''POC 执行入口'''
    args = None
    parser = create_parser()
    try:
        args = parser.parse_args()
    except:
        logger.exception('解析错误')
        raise
    if not args.poc_id:
        parser.print_usage()
        logger.warning('参数解析错误: poc-id 为空')
        return
    if not args.url:
        parser.print_usage()
        logger.warning('参数解析错误: url 为空')
        return
    setup_cscan_poc_logger(verbose=args.verbose,
                           very_verbose=args.very_verbose)
    (poc_id, index_dir) = (args.poc_id, args.index_dir)

    poc = None
    try:
        logger.debug('查找 POC[id=%s] index_dir=%s', poc_id, index_dir)
        poc = find_poc(poc_id, index_dir)
    except:
        logger.exception('POC[id=%s, index_dir=%s]加载失败,退出执行', poc_id,
                         index_dir)
        raise

    try:
        poc.run(args=args)
    except:
        logger.exception('%s执行异常', poc)
Beispiel #2
0
    def insert_strategies(self, strategy_id_set):
        if not strategy_id_set:
            return
        logger.info('开始插入策略【%s】', len(strategy_id_set))

        strategy_insert_sql = '''INSERT INTO strategy
            (strategy_id, strategy_name, author, `desc`, create_time, created_at, updated_at)
            VALUES(%s, %s, %s, %s, %s, %s, %s)'''

        now = datetime.datetime.now()

        count = 0
        successful_count = 0
        cursor = self.cnx.cursor()
        for info in [
                x for x in [self.strategy_ind[x] for x in strategy_id_set]
                if x is not None
        ]:
            progress(count, len(strategy_id_set),
                     '插入策略 {}'.format(info.get('strategy_id')))
            info['created_at'] = now
            info['updated_at'] = now
            try:
                cursor.execute(strategy_insert_sql, [
                    info.get(k) for k in [
                        'strategy_id', 'name', 'author', 'desc', 'create_date',
                        'created_at', 'updated_at'
                    ]
                ])
                successful_count += 1
            except Exception as err:
                logger.warning('策略插入失败:%s\n%s', info, err)
        self.cnx.commit()
        logger.info('成功插入策略【%s个】', successful_count)
Beispiel #3
0
 def update_strategies(self, strategy_id_set):
     if not strategy_id_set:
         return
     strategy_update_sql = '''UPDATE strategy
         SET strategy_name=%s, author=%s, `desc`=%s, create_time=%s, updated_at=%s
         WHERE strategy_id=%s'''
     count = 0
     successful_count = 0
     cursor = self.cnx.cursor()
     for info in [
             x for x in [self.strategy_ind[x] for x in strategy_id_set]
             if x is not None
     ]:
         progress(count, len(strategy_id_set),
                  '更新策略 {}'.format(info.get('strategy_id')))
         info['updated_at'] = datetime.datetime.now()
         try:
             cursor.execute(strategy_update_sql, [
                 info.get(k) for k in [
                     'name', 'author', 'desc', 'create_date', 'updated_at',
                     'strategy_id'
                 ]
             ])
             successful_count += 1
         except Exception as err:
             logger.warning('策略更新失败:%s\n%s', info, err)
     self.cnx.commit()
     logger.info('成功更新策略【%s个】', successful_count)
Beispiel #4
0
def indexing_strategies(strategy_dir, index_dir=None):
    strategy_ind_file = INDEX_CONFIG.get_strategy_index_file(index_dir)
    with open(strategy_ind_file, 'w') as strategy_ind:
        mod_count = 0
        successful_count = 0
        strategy_ids = {}
        for (mod, dirpath, filename) in iter_modules(strategy_dir):
            pth = os.path.join(dirpath, filename)
            mod_count += 1
            progress(mod_count, successful_count, '处理模块', pth)
            strategy = None
            try:
                strategy = load_strategy_mod(mod)
            except:
                logger.exception('模块加载出错: %s', pth)
                continue
            if strategy.strategy_id in strategy_ids:
                logger.warning('相同 id 的策略在 %s 已经出现: %s',
                               strategy_ids[strategy.strategy_id], pth)
                continue
            strategy_ids[strategy.strategy_id] = pth
            strategy_dict = dump_strategy_to_dict(strategy)
            strategy_dict['__file__'] = pth
            strategy_dict['__class__'] = strategy.__class__.__name__
            _write_obj(strategy_ind, strategy_dict)
            successful_count += 1
    logger.info('*********** 成功加载 %s 个模块【共计 %s 个】**********', successful_count,
                mod_count)
Beispiel #5
0
def main():
    (parser, args) = (None), None
    try:
        parser = create_parser()
        args = parser.parse_args()
    except:
        return
    setup_cscan_poc_logger(verbose=args.verbose,
                           very_verbose=args.very_verbose)

    if args.sort:
        if not args.doc_dir:
            logger.warning('未指定 --poc-dir')
            parser.print_usage()
            return
        sort_pocs(args.poc_dir)
        return

    if args.vuln_detail_dir:
        args.skip_indexing = True

    if not args.skip_indexing:
        if not args.skip_indexing_poc and args.poc_dir:
            logger.info('开始索引 POC ...')
            indexing_pocs(args.poc_dir, args.index_dir)
        if not args.skip_indexing_strategy and args.strategy_dir:
            logger.info('开始索引策略 ...')
            indexing_strategies(args.strategy_dir, args.index_dir)

    if args.vuln_detail_dir or not args.skip_syncing:
        cnx = mysql.connector.connect(user=args.user,
                                      password=args.passwd,
                                      host=args.host,
                                      database=args.db,
                                      port=args.port,
                                      charset='utf8')
        cscan_db = CScanDb(cnx, args.index_dir, args.update)
        if args.vuln_detail_dir:
            logger.info('同步漏洞详情...')
            cscan_db.sync_vuln_detail(args.vuln_detail_dir,
                                      args.vuln_detail_static_dir,
                                      args.vuln_ids)
        else:
            logger.info('开始同步数据...')
            cscan_db.sync_poc()
            cscan_db.sync_strategy()
Beispiel #6
0
    def insert_pocs(self, poc_id_set):
        if not poc_id_set:
            return
        logger.info('开始插入 POC [count={}]'.format(len(poc_id_set)))

        self.sync_vuln(
            set([self.poc_vuln_ind[poc_id] for poc_id in poc_id_set]))

        poc_insert_sql = '''INSERT INTO poc
            (poc_id, poc_name, author, vuln_id, create_time, created_at, updated_at, args)
            VALUES(%s, %s, %s, %s, %s, %s, %s, %s)'''

        logger.info('准备要插入的 POC 数据')
        now = datetime.datetime.now()
        poc_infos = [
            x for x in [self.poc_ind[x] for x in poc_id_set] if x is not None
        ]
        count = 0
        cursor = self.cnx.cursor()

        for poc_info in poc_infos:
            progress(count, len(poc_infos), '插入 POC')
            count += 1
            vuln_id = self.poc_vuln_ind[poc_info['poc_id']]
            if vuln_id not in self.synced_vuln_ids_in_db:
                poc_info['vuln_id'] = None
            else:
                poc_info['vuln_id'] = vuln_id
            poc_info['created_at'] = now
            poc_info['updated_at'] = now
            poc_info['args'] = poc_info.get('option_schema', None)
            poc_info['create_date'] = poc_info.get('create_date', now)

            try:
                cursor.execute(poc_insert_sql, [
                    poc_info.get(k) for k in [
                        'poc_id', 'name', 'author', 'vuln_id', 'create_date',
                        'created_at', 'updated_at', 'args'
                    ]
                ])
            except Exception as err:
                logger.warning('POC 插入失败: {}\n{}'.format(poc_info, err))

        self.cnx.commit()
        logger.info('成功插入 POC [count={}]'.format(len(poc_id_set)))
Beispiel #7
0
def parse_properties(args,
                     set_option=None,
                     set_component_property=None,
                     default_component=None,
                     components_properties=None):
    '''解析参数中的执行参数和组件属性

    :param args: 解析后的参数
    :param set_option: 设定 --exec-option/--exec-option-file 定义的执行参数
    :param set_component_property:
        设定 --component-property/--component-property-file 设定的组件属性
    :param default_component: 属性所属组件未指定时默认组件
    :param components_properties:
        组件属性 dict,如果 set_component_property 为空,设定属性到该 dict
    '''

    if components_properties is not None:

        def _set_component_property(component_name, key, val):
            if component_name not in components_properties:
                components_properties[component_name] = {}
            Component.get_component(
                component_name).property_schema_handle.set_val(
                    components_properties[component_name], key, val)

        set_component_property = _set_component_property

    if set_component_property is None:

        def _noop_set_component_property(c, k, v):
            pass

        set_component_property = _noop_set_component_property

    if set_option is None:

        def _noop_set_option(k, v):
            pass

        set_option = _noop_set_option

    # 执行参数解析
    for opt in args.exec_option or []:
        (key, val) = (opt, True)
        if '=' in opt:
            (key, val) = opt.split('=', 1)
        try:
            set_option(key, val)
        except SchemaException as err:
            logger.warning('执行参数设定错误: %s', err)

    if args.exec_option_file:
        if not os.path.exists(args.exec_option_file):
            raise Exception('执行参数文件 {} 不存在'.format(args.exec_option_file))
        options = None
        try:
            with open(args.exec_option_file) as fh:
                options = json.load(fh)
        except Exception as err:
            raise Exception('执行参数文件 {} 解析错误'.format(args.exec_option_file),
                            err)
        for k in options:
            set_option(k, options[k])

    if args.component_property_file:
        if not os.path.exists(args.component_property_file):
            raise Exception('属性文件 {} 不存在'.format(args.component_property_file))
        properties = None
        try:
            with open(args.component_property_file) as fh:
                properties = json.load(fh)
        except Exception as err:
            raise Exception(
                '属性文件 {} 解析错误'.format(args.component_property_file), err)
        for component_name in properties:
            for prop in properties[component_name]:
                try:
                    set_component_property(component_name, prop,
                                           properties[component_name][prop])
                except SchemaException as err:
                    logger.warning('组件属性设定错误: %s [%s]', err,
                                   args.component_property_file)

    # 组件属性解析
    for opt in args.component_properties or []:
        (key, val) = (opt, True)
        if '=' in opt:
            (key, val) = opt.split('=', 1)
        (component_name, prop) = (default_component, key)
        if '.' in key:
            (component_name, prop) = key.split('.', 1)
        try:
            set_component_property(component_name, prop, val)
            logger.debug('解析设定组件 %s 属性:%s=%s', component_name, prop, val)
        except SchemaException as err:
            logger.warning('组件属性设定错误: %s', err)