regscale-cli 6.16.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of regscale-cli might be problematic. Click here for more details.
- regscale/__init__.py +1 -0
- regscale/airflow/__init__.py +9 -0
- regscale/airflow/azure/__init__.py +9 -0
- regscale/airflow/azure/cli.py +89 -0
- regscale/airflow/azure/upload_dags.py +116 -0
- regscale/airflow/click_dags.py +127 -0
- regscale/airflow/click_mixins.py +82 -0
- regscale/airflow/config.py +25 -0
- regscale/airflow/factories/__init__.py +0 -0
- regscale/airflow/factories/connections.py +58 -0
- regscale/airflow/factories/workflows.py +78 -0
- regscale/airflow/hierarchy.py +88 -0
- regscale/airflow/operators/__init__.py +0 -0
- regscale/airflow/operators/click.py +36 -0
- regscale/airflow/sensors/__init__.py +0 -0
- regscale/airflow/sensors/sql.py +107 -0
- regscale/airflow/sessions/__init__.py +0 -0
- regscale/airflow/sessions/sql/__init__.py +3 -0
- regscale/airflow/sessions/sql/queries.py +64 -0
- regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
- regscale/airflow/tasks/__init__.py +0 -0
- regscale/airflow/tasks/branches.py +22 -0
- regscale/airflow/tasks/cli.py +116 -0
- regscale/airflow/tasks/click.py +73 -0
- regscale/airflow/tasks/debugging.py +9 -0
- regscale/airflow/tasks/groups.py +116 -0
- regscale/airflow/tasks/init.py +60 -0
- regscale/airflow/tasks/states.py +47 -0
- regscale/airflow/tasks/workflows.py +36 -0
- regscale/ansible/__init__.py +9 -0
- regscale/core/__init__.py +0 -0
- regscale/core/app/__init__.py +3 -0
- regscale/core/app/api.py +571 -0
- regscale/core/app/application.py +665 -0
- regscale/core/app/internal/__init__.py +136 -0
- regscale/core/app/internal/admin_actions.py +230 -0
- regscale/core/app/internal/assessments_editor.py +873 -0
- regscale/core/app/internal/catalog.py +316 -0
- regscale/core/app/internal/comparison.py +459 -0
- regscale/core/app/internal/control_editor.py +571 -0
- regscale/core/app/internal/encrypt.py +79 -0
- regscale/core/app/internal/evidence.py +1240 -0
- regscale/core/app/internal/file_uploads.py +151 -0
- regscale/core/app/internal/healthcheck.py +66 -0
- regscale/core/app/internal/login.py +305 -0
- regscale/core/app/internal/migrations.py +240 -0
- regscale/core/app/internal/model_editor.py +1701 -0
- regscale/core/app/internal/poam_editor.py +632 -0
- regscale/core/app/internal/workflow.py +105 -0
- regscale/core/app/logz.py +74 -0
- regscale/core/app/utils/XMLIR.py +258 -0
- regscale/core/app/utils/__init__.py +0 -0
- regscale/core/app/utils/api_handler.py +358 -0
- regscale/core/app/utils/app_utils.py +1110 -0
- regscale/core/app/utils/catalog_utils/__init__.py +0 -0
- regscale/core/app/utils/catalog_utils/common.py +91 -0
- regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
- regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
- regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
- regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
- regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
- regscale/core/app/utils/file_utils.py +238 -0
- regscale/core/app/utils/parser_utils.py +81 -0
- regscale/core/app/utils/pickle_file_handler.py +57 -0
- regscale/core/app/utils/regscale_utils.py +319 -0
- regscale/core/app/utils/report_utils.py +119 -0
- regscale/core/app/utils/variables.py +226 -0
- regscale/core/decorators.py +31 -0
- regscale/core/lazy_group.py +65 -0
- regscale/core/login.py +63 -0
- regscale/core/server/__init__.py +0 -0
- regscale/core/server/flask_api.py +473 -0
- regscale/core/server/helpers.py +373 -0
- regscale/core/server/rest.py +64 -0
- regscale/core/server/static/css/bootstrap.css +6030 -0
- regscale/core/server/static/css/bootstrap.min.css +6 -0
- regscale/core/server/static/css/main.css +176 -0
- regscale/core/server/static/images/regscale-cli.svg +49 -0
- regscale/core/server/static/images/regscale.svg +38 -0
- regscale/core/server/templates/base.html +74 -0
- regscale/core/server/templates/index.html +43 -0
- regscale/core/server/templates/login.html +28 -0
- regscale/core/server/templates/make_base64.html +22 -0
- regscale/core/server/templates/upload_STIG.html +109 -0
- regscale/core/server/templates/upload_STIG_result.html +26 -0
- regscale/core/server/templates/upload_ssp.html +144 -0
- regscale/core/server/templates/upload_ssp_result.html +128 -0
- regscale/core/static/__init__.py +0 -0
- regscale/core/static/regex.py +14 -0
- regscale/core/utils/__init__.py +117 -0
- regscale/core/utils/click_utils.py +13 -0
- regscale/core/utils/date.py +238 -0
- regscale/core/utils/graphql.py +254 -0
- regscale/core/utils/urls.py +23 -0
- regscale/dev/__init__.py +6 -0
- regscale/dev/analysis.py +454 -0
- regscale/dev/cli.py +235 -0
- regscale/dev/code_gen.py +492 -0
- regscale/dev/dirs.py +69 -0
- regscale/dev/docs.py +384 -0
- regscale/dev/monitoring.py +26 -0
- regscale/dev/profiling.py +216 -0
- regscale/exceptions/__init__.py +4 -0
- regscale/exceptions/license_exception.py +7 -0
- regscale/exceptions/validation_exception.py +9 -0
- regscale/integrations/__init__.py +1 -0
- regscale/integrations/commercial/__init__.py +486 -0
- regscale/integrations/commercial/ad.py +433 -0
- regscale/integrations/commercial/amazon/__init__.py +0 -0
- regscale/integrations/commercial/amazon/common.py +106 -0
- regscale/integrations/commercial/aqua/__init__.py +0 -0
- regscale/integrations/commercial/aqua/aqua.py +91 -0
- regscale/integrations/commercial/aws/__init__.py +6 -0
- regscale/integrations/commercial/aws/cli.py +322 -0
- regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
- regscale/integrations/commercial/aws/inventory/base.py +64 -0
- regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
- regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
- regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
- regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
- regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
- regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
- regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
- regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
- regscale/integrations/commercial/aws/scanner.py +823 -0
- regscale/integrations/commercial/azure/__init__.py +0 -0
- regscale/integrations/commercial/azure/common.py +32 -0
- regscale/integrations/commercial/azure/intune.py +488 -0
- regscale/integrations/commercial/azure/scanner.py +49 -0
- regscale/integrations/commercial/burp.py +78 -0
- regscale/integrations/commercial/cpe.py +144 -0
- regscale/integrations/commercial/crowdstrike.py +1117 -0
- regscale/integrations/commercial/defender.py +1511 -0
- regscale/integrations/commercial/dependabot.py +210 -0
- regscale/integrations/commercial/durosuite/__init__.py +0 -0
- regscale/integrations/commercial/durosuite/api.py +1546 -0
- regscale/integrations/commercial/durosuite/process_devices.py +101 -0
- regscale/integrations/commercial/durosuite/scanner.py +637 -0
- regscale/integrations/commercial/durosuite/variables.py +21 -0
- regscale/integrations/commercial/ecr.py +90 -0
- regscale/integrations/commercial/gcp/__init__.py +237 -0
- regscale/integrations/commercial/gcp/auth.py +96 -0
- regscale/integrations/commercial/gcp/control_tests.py +238 -0
- regscale/integrations/commercial/gcp/variables.py +18 -0
- regscale/integrations/commercial/gitlab.py +332 -0
- regscale/integrations/commercial/grype.py +165 -0
- regscale/integrations/commercial/ibm.py +90 -0
- regscale/integrations/commercial/import_all/__init__.py +0 -0
- regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
- regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
- regscale/integrations/commercial/jira.py +1046 -0
- regscale/integrations/commercial/mappings/__init__.py +0 -0
- regscale/integrations/commercial/mappings/csf_controls.json +713 -0
- regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
- regscale/integrations/commercial/nessus/__init__.py +0 -0
- regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
- regscale/integrations/commercial/nessus/scanner.py +416 -0
- regscale/integrations/commercial/nexpose.py +90 -0
- regscale/integrations/commercial/okta.py +798 -0
- regscale/integrations/commercial/opentext/__init__.py +0 -0
- regscale/integrations/commercial/opentext/click.py +99 -0
- regscale/integrations/commercial/opentext/scanner.py +143 -0
- regscale/integrations/commercial/prisma.py +91 -0
- regscale/integrations/commercial/qualys.py +1462 -0
- regscale/integrations/commercial/salesforce.py +980 -0
- regscale/integrations/commercial/sap/__init__.py +0 -0
- regscale/integrations/commercial/sap/click.py +31 -0
- regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
- regscale/integrations/commercial/sap/sysdig/click.py +57 -0
- regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
- regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
- regscale/integrations/commercial/sap/tenable/click.py +49 -0
- regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
- regscale/integrations/commercial/servicenow.py +1756 -0
- regscale/integrations/commercial/sicura/__init__.py +0 -0
- regscale/integrations/commercial/sicura/api.py +855 -0
- regscale/integrations/commercial/sicura/commands.py +73 -0
- regscale/integrations/commercial/sicura/scanner.py +481 -0
- regscale/integrations/commercial/sicura/variables.py +16 -0
- regscale/integrations/commercial/snyk.py +90 -0
- regscale/integrations/commercial/sonarcloud.py +260 -0
- regscale/integrations/commercial/sqlserver.py +369 -0
- regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
- regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
- regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
- regscale/integrations/commercial/stigv2/__init__.py +0 -0
- regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
- regscale/integrations/commercial/stigv2/click_commands.py +95 -0
- regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
- regscale/integrations/commercial/synqly/__init__.py +0 -0
- regscale/integrations/commercial/synqly/assets.py +46 -0
- regscale/integrations/commercial/synqly/ticketing.py +132 -0
- regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
- regscale/integrations/commercial/synqly_jira.py +840 -0
- regscale/integrations/commercial/tenablev2/__init__.py +0 -0
- regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
- regscale/integrations/commercial/tenablev2/click.py +1584 -0
- regscale/integrations/commercial/tenablev2/scanner.py +504 -0
- regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
- regscale/integrations/commercial/tenablev2/utils.py +78 -0
- regscale/integrations/commercial/tenablev2/variables.py +17 -0
- regscale/integrations/commercial/trivy.py +162 -0
- regscale/integrations/commercial/veracode.py +96 -0
- regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
- regscale/integrations/commercial/wizv2/__init__.py +0 -0
- regscale/integrations/commercial/wizv2/click.py +429 -0
- regscale/integrations/commercial/wizv2/constants.py +1001 -0
- regscale/integrations/commercial/wizv2/issue.py +361 -0
- regscale/integrations/commercial/wizv2/models.py +112 -0
- regscale/integrations/commercial/wizv2/parsers.py +339 -0
- regscale/integrations/commercial/wizv2/sbom.py +115 -0
- regscale/integrations/commercial/wizv2/scanner.py +416 -0
- regscale/integrations/commercial/wizv2/utils.py +796 -0
- regscale/integrations/commercial/wizv2/variables.py +39 -0
- regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
- regscale/integrations/commercial/xray.py +91 -0
- regscale/integrations/integration/__init__.py +2 -0
- regscale/integrations/integration/integration.py +26 -0
- regscale/integrations/integration/inventory.py +17 -0
- regscale/integrations/integration/issue.py +100 -0
- regscale/integrations/integration_override.py +149 -0
- regscale/integrations/public/__init__.py +103 -0
- regscale/integrations/public/cisa.py +641 -0
- regscale/integrations/public/criticality_updater.py +70 -0
- regscale/integrations/public/emass.py +411 -0
- regscale/integrations/public/emass_slcm_import.py +697 -0
- regscale/integrations/public/fedramp/__init__.py +0 -0
- regscale/integrations/public/fedramp/appendix_parser.py +548 -0
- regscale/integrations/public/fedramp/click.py +479 -0
- regscale/integrations/public/fedramp/components.py +714 -0
- regscale/integrations/public/fedramp/docx_parser.py +259 -0
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
- regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
- regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
- regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
- regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
- regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
- regscale/integrations/public/fedramp/import_workbook.py +495 -0
- regscale/integrations/public/fedramp/inventory_items.py +244 -0
- regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
- regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
- regscale/integrations/public/fedramp/mappings/user.py +175 -0
- regscale/integrations/public/fedramp/mappings/values.py +141 -0
- regscale/integrations/public/fedramp/markdown_parser.py +150 -0
- regscale/integrations/public/fedramp/metadata.py +689 -0
- regscale/integrations/public/fedramp/models/__init__.py +59 -0
- regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
- regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
- regscale/integrations/public/fedramp/parts_mapper.py +107 -0
- regscale/integrations/public/fedramp/poam/__init__.py +0 -0
- regscale/integrations/public/fedramp/poam/scanner.py +851 -0
- regscale/integrations/public/fedramp/properties.py +201 -0
- regscale/integrations/public/fedramp/reporting.py +84 -0
- regscale/integrations/public/fedramp/resources.py +496 -0
- regscale/integrations/public/fedramp/rosetta.py +110 -0
- regscale/integrations/public/fedramp/ssp_logger.py +87 -0
- regscale/integrations/public/fedramp/system_characteristics.py +922 -0
- regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
- regscale/integrations/public/fedramp/system_implementation.py +190 -0
- regscale/integrations/public/fedramp/xml_utils.py +87 -0
- regscale/integrations/public/nist_catalog.py +275 -0
- regscale/integrations/public/oscal.py +1946 -0
- regscale/integrations/public/otx.py +169 -0
- regscale/integrations/scanner_integration.py +2692 -0
- regscale/integrations/variables.py +25 -0
- regscale/models/__init__.py +7 -0
- regscale/models/app_models/__init__.py +5 -0
- regscale/models/app_models/catalog_compare.py +213 -0
- regscale/models/app_models/click.py +252 -0
- regscale/models/app_models/datetime_encoder.py +21 -0
- regscale/models/app_models/import_validater.py +321 -0
- regscale/models/app_models/mapping.py +260 -0
- regscale/models/app_models/pipeline.py +37 -0
- regscale/models/click_models.py +413 -0
- regscale/models/config.py +154 -0
- regscale/models/email_style.css +67 -0
- regscale/models/hierarchy.py +8 -0
- regscale/models/inspect_models.py +79 -0
- regscale/models/integration_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/inspector.py +262 -0
- regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
- regscale/models/integration_models/aqua.py +247 -0
- regscale/models/integration_models/azure_alerts.py +255 -0
- regscale/models/integration_models/base64.py +23 -0
- regscale/models/integration_models/burp.py +433 -0
- regscale/models/integration_models/burp_models.py +128 -0
- regscale/models/integration_models/cisa_kev_data.json +19333 -0
- regscale/models/integration_models/defender_data.py +93 -0
- regscale/models/integration_models/defenderimport.py +143 -0
- regscale/models/integration_models/drf.py +443 -0
- regscale/models/integration_models/ecr_models/__init__.py +0 -0
- regscale/models/integration_models/ecr_models/data.py +69 -0
- regscale/models/integration_models/ecr_models/ecr.py +239 -0
- regscale/models/integration_models/flat_file_importer.py +1079 -0
- regscale/models/integration_models/grype_import.py +247 -0
- regscale/models/integration_models/ibm.py +126 -0
- regscale/models/integration_models/implementation_results.py +85 -0
- regscale/models/integration_models/nexpose.py +140 -0
- regscale/models/integration_models/prisma.py +202 -0
- regscale/models/integration_models/qualys.py +720 -0
- regscale/models/integration_models/qualys_scanner.py +160 -0
- regscale/models/integration_models/sbom/__init__.py +0 -0
- regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
- regscale/models/integration_models/send_reminders.py +620 -0
- regscale/models/integration_models/snyk.py +155 -0
- regscale/models/integration_models/synqly_models/__init__.py +0 -0
- regscale/models/integration_models/synqly_models/capabilities.json +1 -0
- regscale/models/integration_models/synqly_models/connector_types.py +22 -0
- regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
- regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
- regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
- regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
- regscale/models/integration_models/synqly_models/param.py +72 -0
- regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
- regscale/models/integration_models/synqly_models/tenants.py +39 -0
- regscale/models/integration_models/tenable_models/__init__.py +0 -0
- regscale/models/integration_models/tenable_models/integration.py +187 -0
- regscale/models/integration_models/tenable_models/models.py +513 -0
- regscale/models/integration_models/trivy_import.py +231 -0
- regscale/models/integration_models/veracode.py +217 -0
- regscale/models/integration_models/xray.py +135 -0
- regscale/models/locking.py +100 -0
- regscale/models/platform.py +110 -0
- regscale/models/regscale_models/__init__.py +67 -0
- regscale/models/regscale_models/assessment.py +570 -0
- regscale/models/regscale_models/assessment_plan.py +52 -0
- regscale/models/regscale_models/asset.py +567 -0
- regscale/models/regscale_models/asset_mapping.py +190 -0
- regscale/models/regscale_models/case.py +42 -0
- regscale/models/regscale_models/catalog.py +261 -0
- regscale/models/regscale_models/cci.py +46 -0
- regscale/models/regscale_models/change.py +167 -0
- regscale/models/regscale_models/checklist.py +372 -0
- regscale/models/regscale_models/comment.py +49 -0
- regscale/models/regscale_models/compliance_settings.py +112 -0
- regscale/models/regscale_models/component.py +412 -0
- regscale/models/regscale_models/component_mapping.py +65 -0
- regscale/models/regscale_models/control.py +38 -0
- regscale/models/regscale_models/control_implementation.py +1128 -0
- regscale/models/regscale_models/control_objective.py +261 -0
- regscale/models/regscale_models/control_parameter.py +100 -0
- regscale/models/regscale_models/control_test.py +34 -0
- regscale/models/regscale_models/control_test_plan.py +75 -0
- regscale/models/regscale_models/control_test_result.py +52 -0
- regscale/models/regscale_models/custom_field.py +245 -0
- regscale/models/regscale_models/data.py +109 -0
- regscale/models/regscale_models/data_center.py +40 -0
- regscale/models/regscale_models/deviation.py +203 -0
- regscale/models/regscale_models/email.py +97 -0
- regscale/models/regscale_models/evidence.py +47 -0
- regscale/models/regscale_models/evidence_mapping.py +40 -0
- regscale/models/regscale_models/facility.py +59 -0
- regscale/models/regscale_models/file.py +382 -0
- regscale/models/regscale_models/filetag.py +37 -0
- regscale/models/regscale_models/form_field_value.py +94 -0
- regscale/models/regscale_models/group.py +169 -0
- regscale/models/regscale_models/implementation_objective.py +335 -0
- regscale/models/regscale_models/implementation_option.py +275 -0
- regscale/models/regscale_models/implementation_role.py +33 -0
- regscale/models/regscale_models/incident.py +177 -0
- regscale/models/regscale_models/interconnection.py +43 -0
- regscale/models/regscale_models/issue.py +1176 -0
- regscale/models/regscale_models/leveraged_authorization.py +125 -0
- regscale/models/regscale_models/line_of_inquiry.py +52 -0
- regscale/models/regscale_models/link.py +205 -0
- regscale/models/regscale_models/meta_data.py +64 -0
- regscale/models/regscale_models/mixins/__init__.py +0 -0
- regscale/models/regscale_models/mixins/parent_cache.py +124 -0
- regscale/models/regscale_models/module.py +224 -0
- regscale/models/regscale_models/modules.py +191 -0
- regscale/models/regscale_models/objective.py +14 -0
- regscale/models/regscale_models/parameter.py +87 -0
- regscale/models/regscale_models/ports_protocol.py +81 -0
- regscale/models/regscale_models/privacy.py +89 -0
- regscale/models/regscale_models/profile.py +50 -0
- regscale/models/regscale_models/profile_link.py +68 -0
- regscale/models/regscale_models/profile_mapping.py +124 -0
- regscale/models/regscale_models/project.py +63 -0
- regscale/models/regscale_models/property.py +278 -0
- regscale/models/regscale_models/question.py +85 -0
- regscale/models/regscale_models/questionnaire.py +87 -0
- regscale/models/regscale_models/questionnaire_instance.py +177 -0
- regscale/models/regscale_models/rbac.py +132 -0
- regscale/models/regscale_models/reference.py +86 -0
- regscale/models/regscale_models/regscale_model.py +1643 -0
- regscale/models/regscale_models/requirement.py +29 -0
- regscale/models/regscale_models/risk.py +274 -0
- regscale/models/regscale_models/sbom.py +54 -0
- regscale/models/regscale_models/scan_history.py +436 -0
- regscale/models/regscale_models/search.py +53 -0
- regscale/models/regscale_models/security_control.py +132 -0
- regscale/models/regscale_models/security_plan.py +204 -0
- regscale/models/regscale_models/software_inventory.py +159 -0
- regscale/models/regscale_models/stake_holder.py +64 -0
- regscale/models/regscale_models/stig.py +647 -0
- regscale/models/regscale_models/supply_chain.py +152 -0
- regscale/models/regscale_models/system_role.py +188 -0
- regscale/models/regscale_models/system_role_external_assignment.py +40 -0
- regscale/models/regscale_models/tag.py +37 -0
- regscale/models/regscale_models/tag_mapping.py +19 -0
- regscale/models/regscale_models/task.py +133 -0
- regscale/models/regscale_models/threat.py +196 -0
- regscale/models/regscale_models/user.py +175 -0
- regscale/models/regscale_models/user_group.py +55 -0
- regscale/models/regscale_models/vulnerability.py +242 -0
- regscale/models/regscale_models/vulnerability_mapping.py +162 -0
- regscale/models/regscale_models/workflow.py +55 -0
- regscale/models/regscale_models/workflow_action.py +34 -0
- regscale/models/regscale_models/workflow_instance.py +269 -0
- regscale/models/regscale_models/workflow_instance_step.py +114 -0
- regscale/models/regscale_models/workflow_template.py +58 -0
- regscale/models/regscale_models/workflow_template_step.py +45 -0
- regscale/regscale.py +815 -0
- regscale/utils/__init__.py +7 -0
- regscale/utils/b64conversion.py +14 -0
- regscale/utils/click_utils.py +118 -0
- regscale/utils/decorators.py +48 -0
- regscale/utils/dict_utils.py +59 -0
- regscale/utils/files.py +79 -0
- regscale/utils/fxns.py +30 -0
- regscale/utils/graphql_client.py +113 -0
- regscale/utils/lists.py +16 -0
- regscale/utils/numbers.py +12 -0
- regscale/utils/shell.py +148 -0
- regscale/utils/string.py +121 -0
- regscale/utils/synqly_utils.py +165 -0
- regscale/utils/threading/__init__.py +8 -0
- regscale/utils/threading/threadhandler.py +131 -0
- regscale/utils/threading/threadsafe_counter.py +47 -0
- regscale/utils/threading/threadsafe_dict.py +242 -0
- regscale/utils/threading/threadsafe_list.py +83 -0
- regscale/utils/version.py +104 -0
- regscale/validation/__init__.py +0 -0
- regscale/validation/address.py +37 -0
- regscale/validation/record.py +48 -0
- regscale/visualization/__init__.py +5 -0
- regscale/visualization/click.py +34 -0
- regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
- regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
- regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
- regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
- regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
- regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
- tests/fixtures/__init__.py +2 -0
- tests/fixtures/api.py +87 -0
- tests/fixtures/models.py +91 -0
- tests/fixtures/test_fixture.py +144 -0
- tests/mocks/__init__.py +0 -0
- tests/mocks/objects.py +3 -0
- tests/mocks/response.py +32 -0
- tests/mocks/xml.py +13 -0
- tests/regscale/__init__.py +0 -0
- tests/regscale/core/__init__.py +0 -0
- tests/regscale/core/test_api.py +232 -0
- tests/regscale/core/test_app.py +406 -0
- tests/regscale/core/test_login.py +37 -0
- tests/regscale/core/test_logz.py +66 -0
- tests/regscale/core/test_sbom_generator.py +87 -0
- tests/regscale/core/test_validation_utils.py +163 -0
- tests/regscale/core/test_version.py +78 -0
- tests/regscale/models/__init__.py +0 -0
- tests/regscale/models/test_asset.py +71 -0
- tests/regscale/models/test_config.py +26 -0
- tests/regscale/models/test_control_implementation.py +27 -0
- tests/regscale/models/test_import.py +97 -0
- tests/regscale/models/test_issue.py +36 -0
- tests/regscale/models/test_mapping.py +52 -0
- tests/regscale/models/test_platform.py +31 -0
- tests/regscale/models/test_regscale_model.py +346 -0
- tests/regscale/models/test_report.py +32 -0
- tests/regscale/models/test_tenable_integrations.py +118 -0
- tests/regscale/models/test_user_model.py +121 -0
- tests/regscale/test_about.py +19 -0
- tests/regscale/test_authorization.py +65 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Scanner integration for Nessus vulnerability scanning.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import sys
|
|
7
|
+
import tempfile
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Dict, Iterator, List, Optional, Tuple, Union, cast
|
|
10
|
+
from xml.etree import ElementTree as ET
|
|
11
|
+
from xml.etree.ElementTree import ElementTree
|
|
12
|
+
|
|
13
|
+
import nessus_file_reader as nfr # type: ignore
|
|
14
|
+
|
|
15
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
16
|
+
from regscale.core.app.utils.file_utils import find_files, get_processed_file_path, iterate_files, move_file, read_file
|
|
17
|
+
from regscale.core.app.utils.parser_utils import safe_float
|
|
18
|
+
from regscale.core.utils.date import date_str
|
|
19
|
+
from regscale.integrations.commercial.nessus.nessus_utils import cpe_xml_to_dict, software
|
|
20
|
+
from regscale.integrations.scanner_integration import IntegrationAsset, IntegrationFinding, ScannerIntegration
|
|
21
|
+
from regscale.integrations.variables import ScannerVariables
|
|
22
|
+
from regscale.models import ImportValidater, regscale_models
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger("regscale")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class NessusIntegration(ScannerIntegration):
|
|
28
|
+
"""Integration class for Nessus vulnerability scanning."""
|
|
29
|
+
|
|
30
|
+
title = "Nessus"
|
|
31
|
+
asset_identifier_field = "tenableId"
|
|
32
|
+
finding_severity_map = {
|
|
33
|
+
"4": regscale_models.IssueSeverity.Critical,
|
|
34
|
+
"3": regscale_models.IssueSeverity.High,
|
|
35
|
+
"2": regscale_models.IssueSeverity.Moderate,
|
|
36
|
+
"1": regscale_models.IssueSeverity.Low,
|
|
37
|
+
"critical": regscale_models.IssueSeverity.Critical,
|
|
38
|
+
"high": regscale_models.IssueSeverity.High,
|
|
39
|
+
"medium": regscale_models.IssueSeverity.Moderate,
|
|
40
|
+
"low": regscale_models.IssueSeverity.Low,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def log_file_warning_and_exit(path: str, exit_app: bool = True) -> None:
|
|
45
|
+
"""
|
|
46
|
+
Log a warning message stating that the Nessus file was not found.
|
|
47
|
+
|
|
48
|
+
:param str path: The path to the Nessus file that was not found
|
|
49
|
+
:param bool exit_app: Whether to exit the program after logging the warning, defaults to True
|
|
50
|
+
:rtype: None
|
|
51
|
+
"""
|
|
52
|
+
logger.warning("No Nessus files found in path %s", path)
|
|
53
|
+
if exit_app:
|
|
54
|
+
sys.exit(0)
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _check_path(path: Optional[str] = None) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Check if the path is a valid Nessus file path.
|
|
60
|
+
|
|
61
|
+
:param Optional[str] path: The path to check, defaults to None
|
|
62
|
+
:raises ValueError: If the path is provided path is not provided
|
|
63
|
+
:rtype: None
|
|
64
|
+
"""
|
|
65
|
+
if not path:
|
|
66
|
+
raise ValueError("Nessus file path must end with .nessus")
|
|
67
|
+
|
|
68
|
+
def fetch_findings(self, *args: Tuple, **kwargs: dict) -> Iterator[IntegrationFinding]:
|
|
69
|
+
"""
|
|
70
|
+
Fetches Nessus findings from the processed Nessus files.
|
|
71
|
+
|
|
72
|
+
:return: Iterator of IntegrationFinding objects
|
|
73
|
+
:rtype: Iterator[IntegrationFinding]
|
|
74
|
+
"""
|
|
75
|
+
path: Optional[str] = cast(Optional[str], kwargs.get("path"))
|
|
76
|
+
self._check_path(path)
|
|
77
|
+
file_collection = find_files(path, "*.nessus")
|
|
78
|
+
if not file_collection:
|
|
79
|
+
self.log_file_warning_and_exit(path)
|
|
80
|
+
if not self.check_collection(file_collection, path):
|
|
81
|
+
return
|
|
82
|
+
for file in iterate_files(file_collection):
|
|
83
|
+
content = read_file(file)
|
|
84
|
+
root = ET.fromstring(content)
|
|
85
|
+
for nessus_asset in nfr.scan.report_hosts(root):
|
|
86
|
+
asset_name = nfr.host.report_host_name(nessus_asset)
|
|
87
|
+
for nessus_vulnerability in root.iterfind(f"./Report/ReportHost[@name='{asset_name}']/ReportItem"):
|
|
88
|
+
parsed_vulnerability = self.parse_finding(nessus_vulnerability, asset_name)
|
|
89
|
+
if parsed_vulnerability:
|
|
90
|
+
yield parsed_vulnerability
|
|
91
|
+
self.move_files(file_collection)
|
|
92
|
+
|
|
93
|
+
def parse_finding(self, vuln: Any, asset_id: str) -> Optional[IntegrationFinding]:
|
|
94
|
+
"""
|
|
95
|
+
Parses a Nessus vulnerability or informational item into an IntegrationFinding object.
|
|
96
|
+
|
|
97
|
+
:param Any vuln: The Nessus vulnerability or informational item to parse
|
|
98
|
+
:param str asset_id: The asset identifier
|
|
99
|
+
:return: The parsed IntegrationFinding or None if parsing fails
|
|
100
|
+
:rtype: Optional[IntegrationFinding]
|
|
101
|
+
"""
|
|
102
|
+
try:
|
|
103
|
+
vulnerability_data = self.get_vulnerability_data(vuln)
|
|
104
|
+
if hasattr(vuln, "attrib"):
|
|
105
|
+
vuln = vuln.attrib
|
|
106
|
+
vuln.update(vulnerability_data)
|
|
107
|
+
|
|
108
|
+
# Determine if this is an informational item or a vulnerability
|
|
109
|
+
is_informational = vuln.get("severity") == "0" and vuln.get("risk_factor", "").lower() == "none"
|
|
110
|
+
|
|
111
|
+
if is_informational:
|
|
112
|
+
category = f"Nessus Information: {vuln.get('pluginFamily', 'General')}"
|
|
113
|
+
issue_type = "Information"
|
|
114
|
+
severity = None
|
|
115
|
+
status = regscale_models.IssueStatus.Closed
|
|
116
|
+
else:
|
|
117
|
+
category = f"Nessus Vulnerability: {vuln.get('pluginFamily', 'General')}"
|
|
118
|
+
issue_type = "Vulnerability"
|
|
119
|
+
severity = self.finding_severity_map.get(vuln["severity"].lower(), regscale_models.IssueSeverity.Low)
|
|
120
|
+
status = regscale_models.IssueStatus.Open
|
|
121
|
+
|
|
122
|
+
synopsis = vuln.get("synopsis", "")
|
|
123
|
+
plugin_name = vuln.get("pluginName", "Unknown Plugin")
|
|
124
|
+
|
|
125
|
+
# Get severity_int, defaulting to 0 if not found
|
|
126
|
+
severity_int = int(vuln.get("severity", "0"))
|
|
127
|
+
identifier = vuln.get("cve") or plugin_name
|
|
128
|
+
|
|
129
|
+
if is_informational:
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
return IntegrationFinding(
|
|
133
|
+
control_labels=[],
|
|
134
|
+
category=category,
|
|
135
|
+
title=f"{identifier}: {synopsis}",
|
|
136
|
+
issue_title=f"{identifier}: {synopsis}",
|
|
137
|
+
description=vuln.get("description"),
|
|
138
|
+
severity=severity or regscale_models.IssueSeverity.Low,
|
|
139
|
+
status=status,
|
|
140
|
+
asset_identifier=asset_id,
|
|
141
|
+
external_id=vuln.get("pluginID", "Unknown"),
|
|
142
|
+
first_seen=vuln.get("firstSeen") or get_current_datetime(),
|
|
143
|
+
last_seen=vuln.get("lastSeen") or get_current_datetime(),
|
|
144
|
+
remediation=vuln.get("solution", ""),
|
|
145
|
+
cvss_score=float(vuln.get("cvss_base_score") or 0),
|
|
146
|
+
cve=vuln.get("cve"),
|
|
147
|
+
vulnerability_type=self.title,
|
|
148
|
+
plugin_id=vuln.get("pluginID"),
|
|
149
|
+
plugin_name=identifier,
|
|
150
|
+
ip_address=asset_id,
|
|
151
|
+
dns=None,
|
|
152
|
+
severity_int=severity_int,
|
|
153
|
+
issue_type=issue_type,
|
|
154
|
+
date_created=get_current_datetime(),
|
|
155
|
+
date_last_updated=get_current_datetime(),
|
|
156
|
+
gaps="",
|
|
157
|
+
observations=vuln.get("plugin_output", ""),
|
|
158
|
+
evidence=vuln.get("plugin_output", ""),
|
|
159
|
+
identified_risk=vuln.get("risk_factor", ""),
|
|
160
|
+
impact="",
|
|
161
|
+
recommendation_for_mitigation=vuln.get("solution", ""),
|
|
162
|
+
rule_id=vuln.get("pluginID"),
|
|
163
|
+
rule_version=vuln.get("script_version"),
|
|
164
|
+
results=vuln.get("plugin_output", ""),
|
|
165
|
+
comments=None,
|
|
166
|
+
baseline="",
|
|
167
|
+
poam_comments=None,
|
|
168
|
+
vulnerable_asset=asset_id,
|
|
169
|
+
source_rule_id=vuln.get("fname"),
|
|
170
|
+
)
|
|
171
|
+
except Exception as e:
|
|
172
|
+
logger.error("Error parsing Nessus finding: %s", str(e), exc_info=True)
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
def check_collection(self, file_collection: List[Union[Path, str]], path: str) -> bool:
|
|
176
|
+
"""
|
|
177
|
+
Check if any Nessus files were found in the given path.
|
|
178
|
+
|
|
179
|
+
:param List[Union[Path, str]] file_collection: List of Path objects for .nessus files or S3 URIs
|
|
180
|
+
:param str path: Path to a .nessus file or a folder containing Nessus files
|
|
181
|
+
:return: boolean indicating if any Nessus files were found
|
|
182
|
+
:rtype: bool
|
|
183
|
+
"""
|
|
184
|
+
res = True
|
|
185
|
+
if len(file_collection) == 0:
|
|
186
|
+
self.log_file_warning_and_exit(path, exit_app=False)
|
|
187
|
+
res = False
|
|
188
|
+
return res
|
|
189
|
+
|
|
190
|
+
def fetch_assets(self, *args: Any, **kwargs: dict) -> Iterator[IntegrationAsset]: # type: ignore
|
|
191
|
+
"""
|
|
192
|
+
Fetches Nessus assets from the processed Nessus files.
|
|
193
|
+
|
|
194
|
+
:param str path: Path to the Nessus files
|
|
195
|
+
:yields: Iterator[IntegrationAsset]
|
|
196
|
+
"""
|
|
197
|
+
path: Optional[str] = cast(Optional[str], kwargs.get("path"))
|
|
198
|
+
|
|
199
|
+
file_collection = find_files(path, "*.nessus")
|
|
200
|
+
if not file_collection:
|
|
201
|
+
self.log_file_warning_and_exit(path)
|
|
202
|
+
if self.check_collection(file_collection, path):
|
|
203
|
+
for file in iterate_files(file_collection):
|
|
204
|
+
ImportValidater(
|
|
205
|
+
file_path=file,
|
|
206
|
+
disable_mapping=True,
|
|
207
|
+
required_headers=["Policy", "Report"],
|
|
208
|
+
mapping_file_path=tempfile.gettempdir(),
|
|
209
|
+
xml_tag="NessusClientData_v2",
|
|
210
|
+
prompt=False,
|
|
211
|
+
)
|
|
212
|
+
content = read_file(file)
|
|
213
|
+
root = ET.fromstring(content)
|
|
214
|
+
tree = ElementTree(root)
|
|
215
|
+
assets = nfr.scan.report_hosts(root)
|
|
216
|
+
cpe_items = cpe_xml_to_dict(tree) # type: ignore
|
|
217
|
+
for asset in assets:
|
|
218
|
+
asset_properties = self.get_asset_properties(root, cpe_items, asset)
|
|
219
|
+
parsed_asset = self.parse_asset(asset_properties)
|
|
220
|
+
yield parsed_asset
|
|
221
|
+
|
|
222
|
+
def parse_asset(self, asset: Dict[str, Any]) -> IntegrationAsset:
|
|
223
|
+
"""
|
|
224
|
+
Parses Nessus assets.
|
|
225
|
+
|
|
226
|
+
:param Dict[str, Any] asset: The Nessus asset to parse
|
|
227
|
+
:return: The parsed IntegrationAsset
|
|
228
|
+
:rtype: IntegrationAsset
|
|
229
|
+
"""
|
|
230
|
+
software_inventory = [
|
|
231
|
+
{
|
|
232
|
+
"name": software_obj.get("title"),
|
|
233
|
+
"version": software_obj.get("version"),
|
|
234
|
+
"references": software_obj.get("references", []),
|
|
235
|
+
}
|
|
236
|
+
for software_obj in asset.get("software_inventory", [])
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
return IntegrationAsset(
|
|
240
|
+
name=asset.get("name", ""),
|
|
241
|
+
identifier=asset.get("name")
|
|
242
|
+
or asset.get("host_ip", "")
|
|
243
|
+
or asset.get("fqdn", "")
|
|
244
|
+
or asset.get("tenable_id", ""),
|
|
245
|
+
asset_type=asset.get("asset_type", "Other"),
|
|
246
|
+
asset_category=regscale_models.AssetCategory.Hardware,
|
|
247
|
+
asset_owner_id=ScannerVariables.userId,
|
|
248
|
+
parent_id=self.plan_id,
|
|
249
|
+
parent_module=regscale_models.SecurityPlan.get_module_slug(),
|
|
250
|
+
status=asset.get("status", "Active (On Network)"),
|
|
251
|
+
date_last_updated=date_str(asset.get("last_scan") or get_current_datetime()),
|
|
252
|
+
mac_address=asset.get("mac_address", ""),
|
|
253
|
+
fqdn=asset.get("fqdn", ""),
|
|
254
|
+
ip_address=asset.get("host_ip", ""),
|
|
255
|
+
operating_system=asset.get("operating_system", ""),
|
|
256
|
+
aws_identifier=asset.get("aws_identifier", ""),
|
|
257
|
+
vlan_id=asset.get("vlan_id", ""),
|
|
258
|
+
location=asset.get("location", ""),
|
|
259
|
+
software_inventory=software_inventory,
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
@staticmethod
|
|
263
|
+
def get_asset_properties(root, cpe_items, file_asset) -> dict:
|
|
264
|
+
"""
|
|
265
|
+
Get the asset properties
|
|
266
|
+
|
|
267
|
+
:param root: The Nessus root element
|
|
268
|
+
:param cpe_items: The CPE items
|
|
269
|
+
:param file_asset: The file asset
|
|
270
|
+
:return: dict of asset properties
|
|
271
|
+
:rtype: dict
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
nessus_report_uuid = nfr.scan.server_preference_value(root, "report_task_id")
|
|
275
|
+
asset_name = nfr.host.report_host_name(file_asset)
|
|
276
|
+
temp = f"./Report/ReportHost[@name='{asset_name}']/HostProperties/tag"
|
|
277
|
+
operating_system = nfr.host.detected_os(file_asset)
|
|
278
|
+
netbios = nfr.host.netbios_network_name(root, file_asset)
|
|
279
|
+
resolved_ip = nfr.host.resolved_ip(file_asset)
|
|
280
|
+
scanner_ip = nfr.host.scanner_ip(root, file_asset)
|
|
281
|
+
software_inventory = software(cpe_items, file_asset) # Placeholder for CPE lookup,
|
|
282
|
+
tag_map = {
|
|
283
|
+
"id": "tenable_id",
|
|
284
|
+
"host-ip": "host_ip",
|
|
285
|
+
"host-fqdn": "fqdn",
|
|
286
|
+
"mac-address": "macaddress",
|
|
287
|
+
"HOST_START_TIMESTAMP": "begin_scan",
|
|
288
|
+
"HOST_END_TIMESTAMP": "last_scan",
|
|
289
|
+
"aws-instance-instanceId": "aws_instance_id",
|
|
290
|
+
"aws-instance-vpc-id": "vlan_id",
|
|
291
|
+
"aws-instance-region": "location",
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
tag_values = {value: "" for key, value in tag_map.items()}
|
|
295
|
+
|
|
296
|
+
for file_asset_tag in root.iterfind(temp):
|
|
297
|
+
tag_name = file_asset_tag.attrib.get("name")
|
|
298
|
+
tag_value = file_asset_tag.text
|
|
299
|
+
if tag_name in tag_map:
|
|
300
|
+
variable_name = tag_map[tag_name]
|
|
301
|
+
tag_values[variable_name] = tag_value
|
|
302
|
+
return {
|
|
303
|
+
"name": asset_name,
|
|
304
|
+
"operating_system": operating_system,
|
|
305
|
+
"tenable_id": (tag_values["tenable_id"] if "tenable_id" in tag_values else ""),
|
|
306
|
+
"netbios_name": netbios["netbios_computer_name"],
|
|
307
|
+
"all_tags": [{"name": attrib.attrib["name"], "val": attrib.text} for attrib in root.iterfind(temp)],
|
|
308
|
+
"mac_address": tag_values["macaddress"],
|
|
309
|
+
"last_scan": tag_values["last_scan"],
|
|
310
|
+
"resolved_ip": resolved_ip,
|
|
311
|
+
"asset_count": len(list(root.iter("ReportHost"))),
|
|
312
|
+
"scanner_ip": scanner_ip,
|
|
313
|
+
"host_ip": tag_values["host_ip"],
|
|
314
|
+
"fqdn": tag_values["fqdn"],
|
|
315
|
+
"software_inventory": software_inventory,
|
|
316
|
+
"nessus_report_uuid": nessus_report_uuid,
|
|
317
|
+
"aws_identifier": tag_values["aws_instance_id"],
|
|
318
|
+
"vlan_id": tag_values["vlan_id"],
|
|
319
|
+
"location": tag_values["location"],
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
@classmethod
|
|
323
|
+
def all_element_data(cls, element: Any, indent: str = "") -> str:
|
|
324
|
+
"""
|
|
325
|
+
Recursively walk down the XML element and return a string representation.
|
|
326
|
+
|
|
327
|
+
:param Any element: A file vulnerability XML element
|
|
328
|
+
:param str indent: Current indentation level (for pretty printing)
|
|
329
|
+
:return: String representation of the vulnerability data
|
|
330
|
+
:rtype: str
|
|
331
|
+
"""
|
|
332
|
+
result = []
|
|
333
|
+
|
|
334
|
+
if element.text and element.text.strip():
|
|
335
|
+
result.append(f"{indent}{element.tag}: {element.text.strip()}")
|
|
336
|
+
|
|
337
|
+
for attr, value in element.attrib.items():
|
|
338
|
+
result.append(f"{indent}{element.tag}.{attr}: {value}")
|
|
339
|
+
|
|
340
|
+
for child in element:
|
|
341
|
+
result.append(cls.all_element_data(child, indent + " "))
|
|
342
|
+
|
|
343
|
+
return "\n".join(result)
|
|
344
|
+
|
|
345
|
+
@classmethod
|
|
346
|
+
def get_vulnerability_data(cls, file_vuln: Any) -> dict:
|
|
347
|
+
"""
|
|
348
|
+
Get the vulnerability data from a Nessus XML element.
|
|
349
|
+
|
|
350
|
+
:param Any file_vuln: A file vulnerability XML element
|
|
351
|
+
:return: dict of vulnerability data
|
|
352
|
+
:rtype: dict
|
|
353
|
+
"""
|
|
354
|
+
|
|
355
|
+
def get(field_name: str) -> Optional[str]:
|
|
356
|
+
"""
|
|
357
|
+
Get the field value from the XML element.
|
|
358
|
+
|
|
359
|
+
:param str field_name: The field name to get
|
|
360
|
+
:return: Field value
|
|
361
|
+
:rtype: Optional[str]
|
|
362
|
+
"""
|
|
363
|
+
element = file_vuln.find(field_name)
|
|
364
|
+
return element.text if element is not None else None
|
|
365
|
+
|
|
366
|
+
def get_attrib(attr_name: str) -> Optional[str]:
|
|
367
|
+
"""
|
|
368
|
+
Get the attribute value from the XML element.
|
|
369
|
+
|
|
370
|
+
:param str attr_name: The attribute name to get
|
|
371
|
+
:return: Attribute value
|
|
372
|
+
:rtype: Optional[str]
|
|
373
|
+
"""
|
|
374
|
+
return file_vuln.get(attr_name)
|
|
375
|
+
|
|
376
|
+
description = get("description")
|
|
377
|
+
plugin_output = get("plugin_output")
|
|
378
|
+
cvss_base_score = safe_float(get("cvss3_base_score"))
|
|
379
|
+
cve = get("cve")
|
|
380
|
+
synopsis = get("synopsis")
|
|
381
|
+
solution = get("solution")
|
|
382
|
+
severity = get_attrib("severity")
|
|
383
|
+
plugin_id = get_attrib("pluginID")
|
|
384
|
+
plugin_name = get_attrib("pluginName")
|
|
385
|
+
risk_factor = get("risk_factor")
|
|
386
|
+
script_version = get("script_version")
|
|
387
|
+
fname = get("fname")
|
|
388
|
+
|
|
389
|
+
return {
|
|
390
|
+
"description": description,
|
|
391
|
+
"synopsis": synopsis,
|
|
392
|
+
"plugin_output": plugin_output,
|
|
393
|
+
"cve": cve,
|
|
394
|
+
"cvss_base_score": cvss_base_score,
|
|
395
|
+
"severity": severity,
|
|
396
|
+
"solution": solution,
|
|
397
|
+
"pluginID": plugin_id,
|
|
398
|
+
"pluginName": plugin_name,
|
|
399
|
+
"risk_factor": risk_factor,
|
|
400
|
+
"script_version": script_version,
|
|
401
|
+
"fname": fname,
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
@staticmethod
|
|
405
|
+
def move_files(file_collection: List[Union[Path, str]]) -> None:
|
|
406
|
+
"""
|
|
407
|
+
Move the list of files to a folder called 'processed' in the same directory.
|
|
408
|
+
|
|
409
|
+
:param List[Union[Path, str]] file_collection: List of file paths or S3 URIs
|
|
410
|
+
:return: None
|
|
411
|
+
:rtype: None
|
|
412
|
+
"""
|
|
413
|
+
for file in file_collection:
|
|
414
|
+
new_file = get_processed_file_path(file)
|
|
415
|
+
move_file(file, new_file)
|
|
416
|
+
logger.info("Moved Nessus file %s to %s", file, new_file)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Nexpose RegScale integration"""
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from os import PathLike
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
|
|
10
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
11
|
+
from regscale.models.integration_models.nexpose import Nexpose
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.group()
|
|
15
|
+
def nexpose():
|
|
16
|
+
"""Performs actions on Nexpose files."""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@nexpose.command(name="import_nexpose")
|
|
20
|
+
@FlatFileImporter.common_scanner_options(
|
|
21
|
+
message="File path to the folder containing Nexpose .csv files to process to RegScale.",
|
|
22
|
+
prompt="File path for Nexpose files:",
|
|
23
|
+
import_name="nexpose",
|
|
24
|
+
)
|
|
25
|
+
def import_nexpose(
|
|
26
|
+
folder_path: PathLike[str],
|
|
27
|
+
regscale_ssp_id: int,
|
|
28
|
+
scan_date: datetime,
|
|
29
|
+
mappings_path: PathLike[str],
|
|
30
|
+
disable_mapping: bool,
|
|
31
|
+
s3_bucket: str,
|
|
32
|
+
s3_prefix: str,
|
|
33
|
+
aws_profile: str,
|
|
34
|
+
upload_file: bool,
|
|
35
|
+
) -> None:
|
|
36
|
+
"""
|
|
37
|
+
Import Nexpose scans, vulnerabilities and assets to RegScale from Nexpose files
|
|
38
|
+
"""
|
|
39
|
+
import_nexpose_files(
|
|
40
|
+
folder_path=folder_path,
|
|
41
|
+
regscale_ssp_id=regscale_ssp_id,
|
|
42
|
+
scan_date=scan_date,
|
|
43
|
+
mappings_path=mappings_path,
|
|
44
|
+
disable_mapping=disable_mapping,
|
|
45
|
+
s3_bucket=s3_bucket,
|
|
46
|
+
s3_prefix=s3_prefix,
|
|
47
|
+
aws_profile=aws_profile,
|
|
48
|
+
upload_file=upload_file,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def import_nexpose_files(
|
|
53
|
+
folder_path: PathLike[str],
|
|
54
|
+
regscale_ssp_id: int,
|
|
55
|
+
scan_date: datetime,
|
|
56
|
+
mappings_path: PathLike[str],
|
|
57
|
+
disable_mapping: bool,
|
|
58
|
+
s3_bucket: str,
|
|
59
|
+
s3_prefix: str,
|
|
60
|
+
aws_profile: str,
|
|
61
|
+
upload_file: Optional[bool] = True,
|
|
62
|
+
) -> None:
|
|
63
|
+
"""
|
|
64
|
+
Import Nexpose scans, vulnerabilities and assets to RegScale from Nexpose files
|
|
65
|
+
|
|
66
|
+
:param PathLike[str] folder_path: File path to the folder containing Nexpose .csv files to process to RegScale
|
|
67
|
+
:param int regscale_ssp_id: The RegScale SSP ID
|
|
68
|
+
:param datetime scan_date: The date of the scan
|
|
69
|
+
:param PathLike[str] mappings_path: The path to the mappings file
|
|
70
|
+
:param bool disable_mapping: Whether to disable custom mappings
|
|
71
|
+
:param str s3_bucket: The S3 bucket to download the files from
|
|
72
|
+
:param str s3_prefix: The S3 prefix to download the files from
|
|
73
|
+
:param str aws_profile: The AWS profile to use for S3 access
|
|
74
|
+
:param Optional[bool] upload_file: Whether to upload the file to RegScale after processing, defaults to True
|
|
75
|
+
:rtype: None
|
|
76
|
+
"""
|
|
77
|
+
FlatFileImporter.import_files(
|
|
78
|
+
import_type=Nexpose,
|
|
79
|
+
import_name="Nexpose",
|
|
80
|
+
file_types=".csv",
|
|
81
|
+
folder_path=folder_path,
|
|
82
|
+
regscale_ssp_id=regscale_ssp_id,
|
|
83
|
+
scan_date=scan_date,
|
|
84
|
+
mappings_path=mappings_path,
|
|
85
|
+
disable_mapping=disable_mapping,
|
|
86
|
+
s3_bucket=s3_bucket,
|
|
87
|
+
s3_prefix=s3_prefix,
|
|
88
|
+
aws_profile=aws_profile,
|
|
89
|
+
upload_file=upload_file,
|
|
90
|
+
)
|