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)
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)
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)
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)
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()
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)))
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)