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 main(): '''策略执行入口''' args = None parser = create_parser() try: args = parser.parse_args() except: return if not args.strategy_id: parser.print_usage() sys.exit(1) setup_cscan_poc_logger(verbose=args.verbose, very_verbose=args.very_verbose) (strategy_id, index_dir) = (args.strategy_id, args.index_dir) strategy = None try: logger.debug('查找 Strategy[id=%s] index_dir=%s', strategy_id, index_dir) strategy = find_strategy(strategy_id, index_dir) except: logger.exception('Strategy[id=%s, index_dir=%s]加载失败,退出执行', strategy_id, index_dir) raise try: if args.component: strategy.component_name = args.component strategy.run(args=args) except: logger.exception('%s执行异常', strategy)
def main(): args = None parser = create_cmd_parser() try: args = parser.parse_args() except: logger.exception('解析错误') raise setup_cscan_poc_logger(verbose=args.verbose, very_verbose=args.very_verbose) logger.debug('解析组件属性') components_properties = {} parse_properties(args, components_properties=components_properties) logger.info('开始尝试推荐任务') recommend(components_properties)
def load_poc_file_as_module(dir_or_file, filename=None): '''加载 POC 文件为 Python module :return: imp.load_source 的结果 ''' if filename is None: (dir, name) = (os.path.dirname(dir_or_file), os.path.basename(dir_or_file)) else: (dir, name) = (dir_or_file, filename) mod_name = '{}-{}'.format( os.path.basename(name).rstrip('.py'), str(uuid.uuid4()) ).replace('.', '_') poc_file = os.path.join(dir, name) try: logger.debug('Loading {}'.format(poc_file)) return imp.load_source( 'CScanPoc.{}'.format(mod_name), poc_file) except Exception as e: logger.error('Error loading {} {}'.format(poc_file, e)) raise e
def load_file_as_module(dir_or_file, filename=None): '''加载 POC 文件为 Python module :param dir_or_file: @param{filename} 为空时,将该参数当作文件路径加载 :param filename: 不为空时,加载 @param{dir_or_file} 目录下的该文件 :return: imp.load_source 的结果 ''' if filename is None: (dirpath, name) = (path.dirname(dir_or_file), path.basename(dir_or_file)) else: (dirpath, name) = (dir_or_file, filename) mod_name = '{}-{}'.format( path.basename(name).rstrip('.py'), str(uuid.uuid4())).replace('.', '_') poc_file = path.join(dirpath, name) try: logger.debug('Loading %s', poc_file) return imp.load_source('CScanPoc.{}'.format(mod_name), poc_file) except Exception as err: logger.error('Error loading %s %s', poc_file, err) raise
def sync_vuln_detail(self, vuln_detail_dir, vuln_detail_static_dir, vuln_ids=None): ''' :param vuln_detail_dir: 漏洞详情存放目录 - htmls/... - imgs/... :param vuln_detail_static_dir: Cscan 站点漏洞静态资源目录 :param vuln_ids: 为空/空列表时同步所有,为列表时只同步列表中指定的漏洞 ID ''' logger.info('同步漏洞详情') vuln_update_sql = '''UPDATE vuln SET exploit=%s WHERE vuln_id=%s''' cursor = self.cnx.cursor() for f in Path(path.join(vuln_detail_dir, 'htmls')).glob('**/*.html'): vuln_id = f.name.rstrip('.html') if vuln_ids and vuln_id not in vuln_ids: continue logger.info('同步 %s' % f) try: cursor.execute(vuln_update_sql, (f.read_text(), vuln_id)) except Exception as e: logger.error('更新失败 %s' % f, e) self.cnx.commit() if vuln_detail_static_dir: logger.info('同步静态资源') src_path = path.join(vuln_detail_dir, 'imgs') img_path = path.join(vuln_detail_static_dir, 'imgs') if not path.exists(img_path): os.makedirs(img_path) for i in os.listdir(src_path): fp = path.join(src_path, i) if not path.isfile(fp): continue logger.debug('同步 %s' % i) copyfile(fp, path.join(img_path, i))
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)