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,247 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for processing Grype scan results and loading them into RegScale as assets, issues, and vulnerabilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import traceback
|
|
7
|
+
from typing import Any, Iterator, List, Optional
|
|
8
|
+
|
|
9
|
+
from regscale.core.app.utils.parser_utils import safe_datetime_str
|
|
10
|
+
from regscale.exceptions import ValidationException
|
|
11
|
+
from regscale.integrations.scanner_integration import IntegrationAsset, IntegrationFinding
|
|
12
|
+
from regscale.models import ImportValidater
|
|
13
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
14
|
+
from regscale.models.regscale_models import AssetStatus, IssueSeverity, IssueStatus
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GrypeImport(FlatFileImporter):
|
|
20
|
+
"""Class for handling Grype scanner integration."""
|
|
21
|
+
|
|
22
|
+
asset_identifier_field = "otherTrackingNumber"
|
|
23
|
+
finding_severity_map = {
|
|
24
|
+
"CRITICAL": IssueSeverity.Critical.value,
|
|
25
|
+
"HIGH": IssueSeverity.High.value,
|
|
26
|
+
"MEDIUM": IssueSeverity.Moderate.value,
|
|
27
|
+
"LOW": IssueSeverity.Low.value,
|
|
28
|
+
"UNKNOWN": IssueSeverity.High.value,
|
|
29
|
+
"NEGLIGIBLE": IssueSeverity.High.value,
|
|
30
|
+
}
|
|
31
|
+
identifier: Optional[str] = None
|
|
32
|
+
|
|
33
|
+
def __init__(self, **kwargs: Any):
|
|
34
|
+
self.name = kwargs.get("name", "Grype")
|
|
35
|
+
self.required_headers = [
|
|
36
|
+
"matches",
|
|
37
|
+
]
|
|
38
|
+
self.mapping_file = kwargs.get("mappings_path")
|
|
39
|
+
self.disable_mapping = kwargs.get("disable_mapping")
|
|
40
|
+
self.validater = ImportValidater(
|
|
41
|
+
self.required_headers,
|
|
42
|
+
kwargs.get("file_path"),
|
|
43
|
+
self.mapping_file,
|
|
44
|
+
self.disable_mapping,
|
|
45
|
+
)
|
|
46
|
+
self.headers = self.validater.parsed_headers
|
|
47
|
+
self.mapping = self.validater.mapping
|
|
48
|
+
if kwargs.get("scan_date"):
|
|
49
|
+
self.scan_date = kwargs.pop("scan_date")
|
|
50
|
+
else:
|
|
51
|
+
self.scan_date = safe_datetime_str(self.mapping.get_value(self.validater.data, "timestamp", warnings=False))
|
|
52
|
+
# even if a user doesn't specify a scan_date, we want to remove it from the kwargs and use the scan_date from
|
|
53
|
+
# the attributes after the scan_date is set in the previous logic
|
|
54
|
+
if "scan_date" in kwargs:
|
|
55
|
+
kwargs.pop("scan_date")
|
|
56
|
+
source_target_data = self.mapping.get_value(self.validater.data, "source", {}, warnings=False).get("target", {})
|
|
57
|
+
|
|
58
|
+
if "sha256-" in kwargs["file_name"]:
|
|
59
|
+
logger.debug("found sha256 in file name %s", kwargs["file_name"])
|
|
60
|
+
self.identifier = "sha256-" + kwargs["file_name"].split("sha256-")[1].split(".json")[0]
|
|
61
|
+
else:
|
|
62
|
+
logger.debug("using imageID for identifier")
|
|
63
|
+
self.identifier = source_target_data.get("imageID", "Unknown")
|
|
64
|
+
logger.debug("self.identifier: %s", self.identifier)
|
|
65
|
+
self.integration_name = self.identifier
|
|
66
|
+
self.other_tracking_number = source_target_data.get("userInput", "Unknown")
|
|
67
|
+
self.os = source_target_data.get("os", "Linux")
|
|
68
|
+
self.notes = f"{kwargs['file_name']}"
|
|
69
|
+
vuln_count = len(self.mapping.get_value(self.validater.data, "matches", [], warnings=False))
|
|
70
|
+
super().__init__(
|
|
71
|
+
logger=logger,
|
|
72
|
+
headers=self.headers,
|
|
73
|
+
extra_headers_allowed=True,
|
|
74
|
+
finding_severity_map=self.finding_severity_map,
|
|
75
|
+
vuln_func=self.create_vuln,
|
|
76
|
+
asset_func=self.create_asset,
|
|
77
|
+
scan_date=self.scan_date,
|
|
78
|
+
asset_identifier_field=self.asset_identifier_field,
|
|
79
|
+
vuln_count=vuln_count,
|
|
80
|
+
asset_count=1,
|
|
81
|
+
**kwargs,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def create_asset(self, *args, **kwargs) -> Iterator[IntegrationAsset]:
|
|
85
|
+
"""
|
|
86
|
+
Fetches assets from the processed json files
|
|
87
|
+
|
|
88
|
+
:yields: Iterator[IntegrationAsset]
|
|
89
|
+
"""
|
|
90
|
+
# Get a list of issues from xml node Issues
|
|
91
|
+
if assets := self.fetch_assets(**kwargs):
|
|
92
|
+
for asset in assets:
|
|
93
|
+
yield asset
|
|
94
|
+
|
|
95
|
+
def create_vuln(self, *args, **kwargs) -> Iterator[IntegrationFinding]:
|
|
96
|
+
"""
|
|
97
|
+
Fetches findings from the processed json files
|
|
98
|
+
|
|
99
|
+
:return: A list of findings
|
|
100
|
+
:rtype: List[IntegrationFinding]
|
|
101
|
+
"""
|
|
102
|
+
if findings := self.fetch_findings(**kwargs):
|
|
103
|
+
for finding in findings:
|
|
104
|
+
yield finding
|
|
105
|
+
|
|
106
|
+
def fetch_findings(self, **_) -> List[IntegrationFinding]:
|
|
107
|
+
"""
|
|
108
|
+
Fetch findings from Grype scan data.
|
|
109
|
+
|
|
110
|
+
:raises ValidationException: If there is an error fetching/parsing findings
|
|
111
|
+
:return: List of IntegrationFinding
|
|
112
|
+
:rtype: List[IntegrationFinding]
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
findings = []
|
|
116
|
+
try:
|
|
117
|
+
for item in self.mapping.get_value(self.validater.data, "matches", []):
|
|
118
|
+
finding = item.get("vulnerability", {})
|
|
119
|
+
cve_id = finding.get("id")
|
|
120
|
+
artifact = item.get("artifact", {})
|
|
121
|
+
cvss = finding.get("cvss", [])
|
|
122
|
+
related_vulns = item.get("relatedVulnerabilities", [])
|
|
123
|
+
description = "No description available"
|
|
124
|
+
if related_vulns:
|
|
125
|
+
for v in related_vulns:
|
|
126
|
+
if v.get("id") == cve_id:
|
|
127
|
+
description = v.get("description", "No description available")
|
|
128
|
+
cvss = v.get("cvss", [])
|
|
129
|
+
break
|
|
130
|
+
|
|
131
|
+
findings.append(
|
|
132
|
+
IntegrationFinding(
|
|
133
|
+
title=artifact.get("name", "unknown"),
|
|
134
|
+
description=description,
|
|
135
|
+
severity=(
|
|
136
|
+
self.process_severity(finding.get("severity"))
|
|
137
|
+
if finding.get("severity")
|
|
138
|
+
else IssueSeverity.NotAssigned.value
|
|
139
|
+
),
|
|
140
|
+
status=IssueStatus.Open.value,
|
|
141
|
+
cvss_v3_score=self.get_cvss_score(cvss_list=cvss),
|
|
142
|
+
cvss_v3_base_score=self.get_cvss_base_score(cvss_list=cvss),
|
|
143
|
+
plugin_name=self.name,
|
|
144
|
+
asset_identifier=self.identifier,
|
|
145
|
+
cve=finding.get("id"),
|
|
146
|
+
first_seen=self.scan_date,
|
|
147
|
+
last_seen=self.scan_date,
|
|
148
|
+
scan_date=self.scan_date,
|
|
149
|
+
category="Software",
|
|
150
|
+
control_labels=[],
|
|
151
|
+
)
|
|
152
|
+
)
|
|
153
|
+
return findings
|
|
154
|
+
except Exception:
|
|
155
|
+
error_message = traceback.format_exc()
|
|
156
|
+
logger.error(f"Error fetching findings: {error_message}")
|
|
157
|
+
raise ValidationException(f"Error fetching findings: {error_message}")
|
|
158
|
+
|
|
159
|
+
def process_severity(self, severity: str) -> str:
|
|
160
|
+
"""
|
|
161
|
+
Process the severity of a finding.
|
|
162
|
+
|
|
163
|
+
:param str severity: The severity of the finding
|
|
164
|
+
:return: IssueSeverity corresponding to the severity
|
|
165
|
+
:rtype: str
|
|
166
|
+
"""
|
|
167
|
+
from regscale.core.app.application import Application
|
|
168
|
+
|
|
169
|
+
app = Application()
|
|
170
|
+
severity_default = app.config.get("vulnerabilityMappingDefault", IssueSeverity.NotAssigned.value)
|
|
171
|
+
return self.finding_severity_map.get(severity.upper(), severity_default)
|
|
172
|
+
|
|
173
|
+
@staticmethod
|
|
174
|
+
def process_status(status: str) -> str:
|
|
175
|
+
"""
|
|
176
|
+
Process the status of a finding.
|
|
177
|
+
|
|
178
|
+
:param str status: The status of the finding
|
|
179
|
+
:return: The corresponding Issue status
|
|
180
|
+
:rtype: str
|
|
181
|
+
"""
|
|
182
|
+
if status.lower() == "fixed":
|
|
183
|
+
return IssueStatus.Closed.value
|
|
184
|
+
else:
|
|
185
|
+
return IssueStatus.Open.value
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def get_cvss_base_score(cvss_list: List) -> float:
|
|
189
|
+
"""
|
|
190
|
+
Get the CVSS base score from the vulnerability data.
|
|
191
|
+
:param List cvss_list: List of CVSS objects
|
|
192
|
+
:return: The CVSS base score
|
|
193
|
+
:rtype: float
|
|
194
|
+
"""
|
|
195
|
+
v3_base_score = 0.0
|
|
196
|
+
for cvss in cvss_list:
|
|
197
|
+
if cvss.get("type") == "Primary":
|
|
198
|
+
if cvs := cvss.get("metrics"):
|
|
199
|
+
v3_base_score = cvs.get("baseScore")
|
|
200
|
+
break
|
|
201
|
+
return v3_base_score
|
|
202
|
+
|
|
203
|
+
@staticmethod
|
|
204
|
+
def get_cvss_score(cvss_list: List) -> float:
|
|
205
|
+
"""
|
|
206
|
+
Get the CVSS score from the finding data.
|
|
207
|
+
:param List cvss_list: List of CVSS objects
|
|
208
|
+
:return: The CVSS score
|
|
209
|
+
:rtype: float
|
|
210
|
+
"""
|
|
211
|
+
value = 0.0
|
|
212
|
+
for cvss in cvss_list:
|
|
213
|
+
if cvss.get("type") == "Primary":
|
|
214
|
+
if cvs := cvss.get("metrics"):
|
|
215
|
+
if impact_score := cvs.get("impactScore"):
|
|
216
|
+
value = impact_score
|
|
217
|
+
return value
|
|
218
|
+
|
|
219
|
+
def fetch_assets(self, **_) -> List[IntegrationAsset]:
|
|
220
|
+
"""
|
|
221
|
+
Fetch assets from Grype scan data.
|
|
222
|
+
|
|
223
|
+
:return: List of IntegrationAsset
|
|
224
|
+
:rtype: List[IntegrationAsset]
|
|
225
|
+
"""
|
|
226
|
+
assets: List[IntegrationAsset] = []
|
|
227
|
+
try:
|
|
228
|
+
assets.append(
|
|
229
|
+
IntegrationAsset(
|
|
230
|
+
identifier=self.identifier,
|
|
231
|
+
name=self.integration_name,
|
|
232
|
+
ip_address="0.0.0.0",
|
|
233
|
+
cpu=0,
|
|
234
|
+
ram=0,
|
|
235
|
+
status=AssetStatus.Active.value,
|
|
236
|
+
asset_type="Other",
|
|
237
|
+
asset_category="Software",
|
|
238
|
+
operating_system=self.os,
|
|
239
|
+
notes=self.notes,
|
|
240
|
+
other_tracking_number=self.other_tracking_number,
|
|
241
|
+
)
|
|
242
|
+
)
|
|
243
|
+
return assets
|
|
244
|
+
except Exception:
|
|
245
|
+
error_message = traceback.format_exc()
|
|
246
|
+
logger.error(f"Error fetching assets: {error_message}")
|
|
247
|
+
raise ValidationException(f"Error fetching assets: {error_message}")
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
IBM Scan information
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from urllib.parse import urlparse
|
|
7
|
+
|
|
8
|
+
from regscale.core.app.application import Application
|
|
9
|
+
from regscale.core.app.logz import create_logger
|
|
10
|
+
from regscale.core.app.utils.app_utils import epoch_to_datetime, get_current_datetime, is_valid_fqdn
|
|
11
|
+
from regscale.models import ImportValidater, Mapping
|
|
12
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
13
|
+
from regscale.models.regscale_models import Asset, Vulnerability
|
|
14
|
+
|
|
15
|
+
ISSUE_TYPE = "Issue Type"
|
|
16
|
+
VULNERABILITY_TITLE = ISSUE_TYPE
|
|
17
|
+
VULNERABILITY_ID = ISSUE_TYPE
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class AppScan(FlatFileImporter):
|
|
21
|
+
"""
|
|
22
|
+
IBM Scan information
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
severity_map = {
|
|
26
|
+
"Critical": "critical",
|
|
27
|
+
"High": "high",
|
|
28
|
+
"Medium": "medium",
|
|
29
|
+
"Low": "low",
|
|
30
|
+
"Informational": "low",
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
def __init__(self, **kwargs):
|
|
34
|
+
self.name = kwargs.get("name")
|
|
35
|
+
self.vuln_title = VULNERABILITY_TITLE
|
|
36
|
+
self.vuln_id = VULNERABILITY_ID
|
|
37
|
+
logger = create_logger()
|
|
38
|
+
self.required_headers = ["URL"]
|
|
39
|
+
self.mapping_file = kwargs.get("mappings_path")
|
|
40
|
+
self.disable_mapping = kwargs.get("disable_mapping")
|
|
41
|
+
self.validater = ImportValidater(
|
|
42
|
+
self.required_headers, kwargs.get("file_path"), self.mapping_file, self.disable_mapping, ignore_unnamed=True
|
|
43
|
+
)
|
|
44
|
+
self.headers = self.validater.parsed_headers
|
|
45
|
+
self.mapping = self.validater.mapping
|
|
46
|
+
super().__init__(
|
|
47
|
+
logger=logger,
|
|
48
|
+
app=Application(),
|
|
49
|
+
headers=self.headers,
|
|
50
|
+
asset_func=self.create_asset,
|
|
51
|
+
vuln_func=self.create_vuln,
|
|
52
|
+
extra_headers_allowed=True,
|
|
53
|
+
**kwargs,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def create_asset(self, dat: Optional[dict] = None) -> Asset:
|
|
57
|
+
"""
|
|
58
|
+
Create an asset from a row in the IBM csv file
|
|
59
|
+
|
|
60
|
+
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
61
|
+
:return: RegScale Asset object
|
|
62
|
+
:rtype: Asset
|
|
63
|
+
"""
|
|
64
|
+
parsed_url = urlparse(self.mapping.get_value(dat, "URL"))
|
|
65
|
+
hostname: str = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
|
66
|
+
return Asset(
|
|
67
|
+
**{
|
|
68
|
+
"id": 0,
|
|
69
|
+
"name": hostname,
|
|
70
|
+
"isPublic": True,
|
|
71
|
+
"status": "Active (On Network)",
|
|
72
|
+
"assetCategory": "Software",
|
|
73
|
+
"bLatestScan": True,
|
|
74
|
+
"bAuthenticatedScan": True,
|
|
75
|
+
"scanningTool": self.name,
|
|
76
|
+
"assetOwnerId": self.config["userId"],
|
|
77
|
+
"assetType": "Other",
|
|
78
|
+
"fqdn": hostname if is_valid_fqdn(hostname) else None,
|
|
79
|
+
"systemAdministratorId": self.config["userId"],
|
|
80
|
+
"parentId": self.attributes.parent_id,
|
|
81
|
+
"parentModule": self.attributes.parent_module,
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def create_vuln(self, dat: Optional[dict] = None, **kwargs) -> Optional[Vulnerability]:
|
|
86
|
+
"""
|
|
87
|
+
Create a vulnerability from a row in the IBM csv file
|
|
88
|
+
|
|
89
|
+
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
90
|
+
:return: RegScale Vulnerability object or None
|
|
91
|
+
:rtype: Optional[Vulnerability]
|
|
92
|
+
"""
|
|
93
|
+
regscale_vuln = None
|
|
94
|
+
parsed_url = urlparse(self.mapping.get_value(dat, "URL"))
|
|
95
|
+
hostname: str = f"{parsed_url.scheme}://{parsed_url.netloc}"
|
|
96
|
+
description: str = self.mapping.get_value(dat, ISSUE_TYPE)
|
|
97
|
+
app_scan_severity = self.mapping.get_value(dat, "Severity")
|
|
98
|
+
severity = self.severity_map.get(app_scan_severity, "Informational")
|
|
99
|
+
config = self.attributes.app.config
|
|
100
|
+
asset_match = [asset for asset in self.data["assets"] if asset.name == hostname]
|
|
101
|
+
asset = asset_match[0] if asset_match else None
|
|
102
|
+
if dat and asset_match:
|
|
103
|
+
regscale_vuln = Vulnerability(
|
|
104
|
+
id=0,
|
|
105
|
+
scanId=0, # set later
|
|
106
|
+
parentId=asset.id,
|
|
107
|
+
parentModule="assets",
|
|
108
|
+
ipAddress="0.0.0.0", # No ip address available
|
|
109
|
+
lastSeen=get_current_datetime(),
|
|
110
|
+
firstSeen=epoch_to_datetime(self.create_epoch),
|
|
111
|
+
daysOpen=None,
|
|
112
|
+
dns=hostname,
|
|
113
|
+
mitigated=None,
|
|
114
|
+
severity=severity,
|
|
115
|
+
plugInName=description,
|
|
116
|
+
cve="",
|
|
117
|
+
vprScore=None,
|
|
118
|
+
tenantsId=0,
|
|
119
|
+
title=description[:255] if description else "No Title",
|
|
120
|
+
description=description,
|
|
121
|
+
plugInText=description,
|
|
122
|
+
createdById=config["userId"],
|
|
123
|
+
lastUpdatedById=config["userId"],
|
|
124
|
+
dateCreated=get_current_datetime(),
|
|
125
|
+
)
|
|
126
|
+
return regscale_vuln
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""standard python imports"""
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.table import Table
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ImplementationResults:
|
|
9
|
+
"""
|
|
10
|
+
Stores results related to STIG (Security Technical Implementation Guide) files.
|
|
11
|
+
|
|
12
|
+
:param str stig_file_name: The name of the STIG file.
|
|
13
|
+
:param Console console: The console object to print with.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, stig_file_name: str, console: Console):
|
|
17
|
+
self.stig_file_name = stig_file_name
|
|
18
|
+
self.failed_implementations = 0
|
|
19
|
+
self.passed_implementations = 0
|
|
20
|
+
self.console = console
|
|
21
|
+
|
|
22
|
+
def add_result(self, status: str):
|
|
23
|
+
"""
|
|
24
|
+
Adds a result to the STIG file.
|
|
25
|
+
|
|
26
|
+
:param str status: The status of the implementation.
|
|
27
|
+
"""
|
|
28
|
+
if status == "Fully Implemented":
|
|
29
|
+
self.record_passed_implementation()
|
|
30
|
+
else:
|
|
31
|
+
self.record_failed_implementation()
|
|
32
|
+
|
|
33
|
+
def record_failed_implementation(self):
|
|
34
|
+
"""
|
|
35
|
+
Records a failed implementation in the STIG file.
|
|
36
|
+
"""
|
|
37
|
+
self.failed_implementations += 1
|
|
38
|
+
|
|
39
|
+
def record_passed_implementation(self):
|
|
40
|
+
"""
|
|
41
|
+
Records a passed implementation in the STIG file.
|
|
42
|
+
"""
|
|
43
|
+
self.passed_implementations += 1
|
|
44
|
+
|
|
45
|
+
def get_total_implementations(self) -> int:
|
|
46
|
+
"""
|
|
47
|
+
Get the total number of implementations (both passed and failed).
|
|
48
|
+
|
|
49
|
+
:return: The total number of implementations.
|
|
50
|
+
:rtype: int
|
|
51
|
+
"""
|
|
52
|
+
return self.failed_implementations + self.passed_implementations
|
|
53
|
+
|
|
54
|
+
def report_log(self) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Log report of the results with colors and formatting.
|
|
57
|
+
|
|
58
|
+
:rtype: None
|
|
59
|
+
"""
|
|
60
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
61
|
+
table.add_column("STIG File", style="cyan")
|
|
62
|
+
table.add_column("Total Implementations")
|
|
63
|
+
table.add_column("Passed Implementations", style="green")
|
|
64
|
+
table.add_column("Failed Implementations", style="red")
|
|
65
|
+
table.add_column("Success Rate (%)")
|
|
66
|
+
table.add_row(
|
|
67
|
+
self.stig_file_name,
|
|
68
|
+
str(self.get_total_implementations()),
|
|
69
|
+
str(self.passed_implementations),
|
|
70
|
+
str(self.failed_implementations),
|
|
71
|
+
f"{self.get_success_rate() * 100:.2f}",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
self.console.print(table)
|
|
75
|
+
|
|
76
|
+
def get_success_rate(self) -> float:
|
|
77
|
+
"""
|
|
78
|
+
Calculate the success rate of implementations in the STIG file.
|
|
79
|
+
|
|
80
|
+
:return: The success rate as a percentage.
|
|
81
|
+
:rtype: float
|
|
82
|
+
"""
|
|
83
|
+
if self.get_total_implementations() > 0:
|
|
84
|
+
return self.passed_implementations / self.get_total_implementations()
|
|
85
|
+
return 0.0
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Nexpose Scan information
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from regscale.core.app.application import Application
|
|
9
|
+
from regscale.core.app.logz import create_logger
|
|
10
|
+
from regscale.core.app.utils.app_utils import epoch_to_datetime, get_current_datetime, is_valid_fqdn
|
|
11
|
+
from regscale.models import ImportValidater
|
|
12
|
+
from regscale.models.app_models.mapping import Mapping
|
|
13
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
14
|
+
from regscale.models.regscale_models import Asset, Issue, Vulnerability
|
|
15
|
+
|
|
16
|
+
VULNERABILITY_TITLE = "Vulnerability Title"
|
|
17
|
+
VULNERABILITY_ID = "Vulnerability ID"
|
|
18
|
+
CVSS3_SCORE = "CVSSv3 Score"
|
|
19
|
+
IP_ADDRESS = "IP Address"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Nexpose(FlatFileImporter):
|
|
23
|
+
"""
|
|
24
|
+
Prisma/Nexpose Scan information
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, **kwargs):
|
|
28
|
+
self.name = kwargs.get("name")
|
|
29
|
+
self.vuln_title = VULNERABILITY_TITLE
|
|
30
|
+
self.vuln_id = VULNERABILITY_ID
|
|
31
|
+
self.cvss3_score = CVSS3_SCORE
|
|
32
|
+
self.required_headers = [
|
|
33
|
+
"IP Address",
|
|
34
|
+
"Hostname",
|
|
35
|
+
"OS",
|
|
36
|
+
"Vulnerability Title",
|
|
37
|
+
"Vulnerability ID",
|
|
38
|
+
"CVSSv2 Score",
|
|
39
|
+
"CVSSv3 Score",
|
|
40
|
+
"Description",
|
|
41
|
+
"Proof",
|
|
42
|
+
"Solution",
|
|
43
|
+
"CVEs",
|
|
44
|
+
]
|
|
45
|
+
self.mapping_file = kwargs.get("mappings_path")
|
|
46
|
+
self.disable_mapping = kwargs.get("disable_mapping")
|
|
47
|
+
self.validater = ImportValidater(
|
|
48
|
+
self.required_headers, kwargs.get("file_path"), self.mapping_file, self.disable_mapping
|
|
49
|
+
)
|
|
50
|
+
self.headers = self.validater.parsed_headers
|
|
51
|
+
self.mapping = self.validater.mapping
|
|
52
|
+
logger = create_logger()
|
|
53
|
+
super().__init__(
|
|
54
|
+
logger=logger,
|
|
55
|
+
app=Application(),
|
|
56
|
+
headers=self.mapping.to_header(),
|
|
57
|
+
asset_func=self.create_asset,
|
|
58
|
+
vuln_func=self.create_vuln,
|
|
59
|
+
extra_headers_allowed=True,
|
|
60
|
+
**kwargs,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def create_asset(self, dat: Optional[dict] = None) -> Optional[Asset]:
|
|
64
|
+
"""
|
|
65
|
+
Create an asset from a row in the Nexpose csv file
|
|
66
|
+
|
|
67
|
+
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
68
|
+
:return: RegScale Asset object, if it has a hostname
|
|
69
|
+
:rtype: Optional[Asset]
|
|
70
|
+
"""
|
|
71
|
+
if hostname := self.mapping.get_value(dat, "Hostname"):
|
|
72
|
+
return Asset(
|
|
73
|
+
**{
|
|
74
|
+
"id": 0,
|
|
75
|
+
"name": hostname,
|
|
76
|
+
"ipAddress": self.mapping.get_value(dat, IP_ADDRESS),
|
|
77
|
+
"isPublic": True,
|
|
78
|
+
"status": "Active (On Network)",
|
|
79
|
+
"assetCategory": "Hardware",
|
|
80
|
+
"bLatestScan": True,
|
|
81
|
+
"bAuthenticatedScan": True,
|
|
82
|
+
"scanningTool": self.name,
|
|
83
|
+
"assetOwnerId": self.config["userId"],
|
|
84
|
+
"assetType": "Other",
|
|
85
|
+
"fqdn": hostname if is_valid_fqdn(hostname) else None,
|
|
86
|
+
"operatingSystem": Asset.find_os(self.mapping.get_value(dat, "OS")),
|
|
87
|
+
"systemAdministratorId": self.config["userId"],
|
|
88
|
+
"parentId": self.attributes.parent_id,
|
|
89
|
+
"parentModule": self.attributes.parent_module,
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def create_vuln(self, dat: Optional[dict] = None, **kwargs) -> Optional[Vulnerability]:
|
|
94
|
+
"""
|
|
95
|
+
Create a vulnerability from a row in the Prisma/Nexpose csv file
|
|
96
|
+
|
|
97
|
+
:param Optional[dict] dat: Data row from CSV file, defaults to None
|
|
98
|
+
:return: RegScale Vulnerability object or None
|
|
99
|
+
:rtype: Optional[Vulnerability]
|
|
100
|
+
"""
|
|
101
|
+
regscale_vuln = None
|
|
102
|
+
cvss3_score = self.mapping.get_value(dat, self.cvss3_score)
|
|
103
|
+
hostname: str = self.mapping.get_value(dat, "Hostname")
|
|
104
|
+
os: str = self.mapping.get_value(dat, "OS")
|
|
105
|
+
description: str = self.mapping.get_value(dat, "Description")
|
|
106
|
+
severity = Vulnerability.determine_cvss3_severity_text(float(cvss3_score)) if cvss3_score else "low"
|
|
107
|
+
config = self.attributes.app.config
|
|
108
|
+
asset_match = [asset for asset in self.data["assets"] if asset.name == hostname]
|
|
109
|
+
asset = asset_match[0] if asset_match else None
|
|
110
|
+
if dat and asset_match:
|
|
111
|
+
return Vulnerability(
|
|
112
|
+
id=0,
|
|
113
|
+
scanId=0, # set later
|
|
114
|
+
parentId=asset.id,
|
|
115
|
+
parentModule="assets",
|
|
116
|
+
ipAddress="0.0.0.0", # No ip address available
|
|
117
|
+
lastSeen=get_current_datetime(),
|
|
118
|
+
firstSeen=epoch_to_datetime(self.create_epoch),
|
|
119
|
+
daysOpen=None,
|
|
120
|
+
dns=hostname,
|
|
121
|
+
mitigated=None,
|
|
122
|
+
operatingSystem=(Asset.find_os(os) if Asset.find_os(os) else None),
|
|
123
|
+
severity=severity,
|
|
124
|
+
plugInName=self.mapping.get_value(dat, self.vuln_title),
|
|
125
|
+
plugInId=self.mapping.get_value(dat, self.vuln_id),
|
|
126
|
+
cve=self.mapping.get_value(dat, "CVEs"),
|
|
127
|
+
vprScore=None,
|
|
128
|
+
tenantsId=0,
|
|
129
|
+
title=description[:255],
|
|
130
|
+
description=description,
|
|
131
|
+
plugInText=self.mapping.get_value(dat, self.vuln_title),
|
|
132
|
+
createdById=config["userId"],
|
|
133
|
+
lastUpdatedById=config["userId"],
|
|
134
|
+
dateCreated=get_current_datetime(),
|
|
135
|
+
extra_data={
|
|
136
|
+
"solution": self.mapping.get_value(dat, "Solution"),
|
|
137
|
+
"proof": self.mapping.get_value(dat, "Proof"),
|
|
138
|
+
},
|
|
139
|
+
)
|
|
140
|
+
return regscale_vuln
|