feat(azure): add new check related with Public IPs in Shodan.io (#3433)

Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com>
This commit is contained in:
Pedro Martín
2024-02-27 13:33:38 +01:00
committed by GitHub
parent ab14efa329
commit bd05aaa4f9
63 changed files with 315 additions and 98 deletions

View File

@@ -51,6 +51,8 @@ config_aws = {
"organizations_trusted_delegated_administrators": [],
}
config_azure = {"shodan_api_key": None}
class Test_Config:
def test_get_aws_available_regions(self):
@@ -184,7 +186,7 @@ class Test_Config:
config_test_file = f"{path}/fixtures/config.yaml"
provider = "azure"
assert load_and_validate_config_file(provider, config_test_file) is None
assert load_and_validate_config_file(provider, config_test_file) == config_azure
def test_load_and_validate_config_file_old_format(self):
path = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))

View File

@@ -56,6 +56,9 @@ aws:
# Azure Configuration
azure:
# Azure Network Configuration
# azure.network_public_ip_shodan
shodan_api_key: null
# GCP Configuration
gcp:

View File

@@ -122,6 +122,7 @@ class Test_Parser:
assert not parsed.sp_env_auth
assert not parsed.browser_auth
assert not parsed.managed_identity_auth
assert not parsed.shodan
def test_default_parser_no_arguments_gcp(self):
provider = "gcp"
@@ -1052,6 +1053,20 @@ class Test_Parser:
assert parsed.provider == "azure"
assert parsed.az_cli_auth
def test_azure_parser_shodan_short(self):
argument = "-N"
shodan_api_key = str(uuid.uuid4())
command = [prowler_command, "azure", argument, shodan_api_key]
parsed = self.parser.parse(command)
assert parsed.shodan == shodan_api_key
def test_azure_parser_shodan_long(self):
argument = "--shodan"
shodan_api_key = str(uuid.uuid4())
command = [prowler_command, "azure", argument, shodan_api_key]
parsed = self.parser.parse(command)
assert parsed.shodan == shodan_api_key
def test_parser_azure_auth_managed_identity(self):
argument = "--managed-identity-auth"
command = [prowler_command, "azure", argument]

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.cosmosdb.cosmosdb_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_cosmosdb_account_firewall_use_selected_networks:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.cosmosdb.cosmosdb_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_cosmosdb_account_use_aad_and_rbac:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.cosmosdb.models import PrivateEndpointConnection
from prowler.providers.azure.services.cosmosdb.cosmosdb_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_cosmosdb_account_use_private_endpoints:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_app_services_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_arm_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_azure_sql_databases_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_containers_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_cosmosdb_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_databases_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_dns_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_keyvault_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_os_relational_databases_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_server_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_sql_servers_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.defender.defender_service import Pricing
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_defender_ensure_defender_for_storage_is_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.network.network_service import BastionHost
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_bastion_host_exists:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.network.models._models import FlowLog, RetentionPolicyParameters
from prowler.providers.azure.services.network.network_service import NetworkWatcher
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_flow_log_more_than_90_days:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.network.models._models import SecurityRule
from prowler.providers.azure.services.network.network_service import SecurityGroup
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_http_internet_access_restricted:

View File

@@ -0,0 +1,78 @@
from unittest import mock
from prowler.providers.azure.services.network.network_service import PublicIp
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_public_ip_shodan:
def test_no_public_ip_addresses(self):
network_client = mock.MagicMock
network_client.public_ip_addresses = {}
network_client.audit_info = mock.MagicMock
with mock.patch(
"prowler.providers.azure.services.network.network_service.Network",
new=network_client,
) as service_client, mock.patch(
"prowler.providers.azure.services.network.network_client.network_client",
new=service_client,
):
from prowler.providers.azure.services.network.network_public_ip_shodan.network_public_ip_shodan import (
network_public_ip_shodan,
)
network_client.audit_config = {"shodan_api_key": "api_key"}
check = network_public_ip_shodan()
result = check.execute()
assert len(result) == 0
def test_network_ip_in_shodan(self):
network_client = mock.MagicMock
public_ip_id = "id"
public_ip_name = "name"
ip_address = "ip_address"
shodan_info = {
"ports": [80, 443],
"isp": "Microsoft Corporation",
"country_name": "country_name",
}
network_client.audit_info = mock.MagicMock
network_client.public_ip_addresses = {
AZURE_SUBSCRIPTION: [
PublicIp(
id=public_ip_id,
name=public_ip_name,
location=None,
ip_address=ip_address,
)
]
}
with mock.patch(
"prowler.providers.azure.services.network.network_service.Network",
new=network_client,
) as service_client, mock.patch(
"prowler.providers.azure.services.network.network_client.network_client",
new=service_client,
), mock.patch(
"prowler.providers.azure.services.network.network_public_ip_shodan.network_public_ip_shodan.shodan.Shodan.host",
return_value=shodan_info,
):
from prowler.providers.azure.services.network.network_public_ip_shodan.network_public_ip_shodan import (
network_public_ip_shodan,
)
network_client.audit_config = {"shodan_api_key": "api_key"}
check = network_public_ip_shodan()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Public IP {ip_address} listed in Shodan with open ports {str(shodan_info['ports'])} and ISP {shodan_info['isp']} in {shodan_info['country_name']}. More info at https://www.shodan.io/host/{ip_address}."
)
assert result[0].subscription == AZURE_SUBSCRIPTION
assert result[0].resource_name == public_ip_name
assert result[0].resource_id == public_ip_id

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.network.models._models import SecurityRule
from prowler.providers.azure.services.network.network_service import SecurityGroup
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_rdp_internet_access_restricted:

View File

@@ -6,6 +6,7 @@ from prowler.providers.azure.services.network.network_service import (
BastionHost,
Network,
NetworkWatcher,
PublicIp,
SecurityGroup,
)
from tests.providers.azure.azure_fixtures import (
@@ -52,6 +53,19 @@ def mock_network_get_network_watchers(_):
}
def mock_network_get_public_ip_addresses(_):
return {
AZURE_SUBSCRIPTION: [
PublicIp(
id="id",
name="name",
location="location",
ip_address="ip_address",
)
]
}
@patch(
"prowler.providers.azure.services.network.network_service.Network.__get_security_groups__",
new=mock_network_get_security_groups,
@@ -64,6 +78,10 @@ def mock_network_get_network_watchers(_):
"prowler.providers.azure.services.network.network_service.Network.__get_network_watchers__",
new=mock_network_get_network_watchers,
)
@patch(
"prowler.providers.azure.services.network.network_service.Network.__get_public_ip_addresses__",
new=mock_network_get_public_ip_addresses,
)
class Test_Network_Service:
def test__get_client__(self):
network = Network(set_mocked_azure_audit_info())
@@ -127,3 +145,17 @@ class Test_Network_Service:
assert network.bastion_hosts[AZURE_SUBSCRIPTION][0].id == "id"
assert network.bastion_hosts[AZURE_SUBSCRIPTION][0].name == "name"
assert network.bastion_hosts[AZURE_SUBSCRIPTION][0].location == "location"
def __get_public_ip_addresses__(self):
network = Network(set_mocked_azure_audit_info())
assert (
network.public_ip_addresses[AZURE_SUBSCRIPTION][0].__class__.__name__
== "PublicIp"
)
assert network.public_ip_addresses[AZURE_SUBSCRIPTION][0].id == "id"
assert network.public_ip_addresses[AZURE_SUBSCRIPTION][0].name == "name"
assert network.public_ip_addresses[AZURE_SUBSCRIPTION][0].location == "location"
assert (
network.public_ip_addresses[AZURE_SUBSCRIPTION][0].ip_address
== "ip_address"
)

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.network.models._models import SecurityRule
from prowler.providers.azure.services.network.network_service import SecurityGroup
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_ssh_internet_access_restricted:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.network.models._models import SecurityRule
from prowler.providers.azure.services.network.network_service import SecurityGroup
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_udp_internet_access_restricted:

View File

@@ -1,9 +1,7 @@
from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.network.network_service import NetworkWatcher
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_network_watcher_enabled:

View File

@@ -5,8 +5,7 @@ from prowler.providers.azure.services.postgresql.postgresql_service import (
Firewall,
Server,
)
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_postgresql_flexible_server_allow_access_services_disabled:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.postgresql.postgresql_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_postgresql_flexible_server_connection_throttling_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.postgresql.postgresql_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_postgresql_flexible_server_enforce_ssl_enabled:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.postgresql.postgresql_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_postgresql_flexible_server_log_checkpoints_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.postgresql.postgresql_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_postgresql_flexible_server_log_connections_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.postgresql.postgresql_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_postgresql_flexible_server_log_disconnections_on:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.postgresql.postgresql_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_postgresql_flexible_server_log_retention_days_greater_3:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.sql.models import ServerExternalAdministrator
from prowler.providers.azure.services.sqlserver.sqlserver_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_azuread_administrator_enabled:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.sql.models import ServerSecurityAlertPolicy
from prowler.providers.azure.services.sqlserver.sqlserver_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_microsoft_defender_enabled:

View File

@@ -7,8 +7,7 @@ from prowler.providers.azure.services.sqlserver.sqlserver_service import (
Database,
Server,
)
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_tde_encrypted_with_cmk:

View File

@@ -7,8 +7,7 @@ from prowler.providers.azure.services.sqlserver.sqlserver_service import (
Database,
Server,
)
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_tde_encryption_enabled:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.sql.models import FirewallRule
from prowler.providers.azure.services.sqlserver.sqlserver_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_unrestricted_inbound_access:

View File

@@ -7,8 +7,7 @@ from azure.mgmt.sql.models import (
)
from prowler.providers.azure.services.sqlserver.sqlserver_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_va_emails_notifications_admins_enabled:

View File

@@ -7,8 +7,7 @@ from azure.mgmt.sql.models import (
)
from prowler.providers.azure.services.sqlserver.sqlserver_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_va_periodic_recurring_scans_enabled:

View File

@@ -7,8 +7,7 @@ from azure.mgmt.sql.models import (
)
from prowler.providers.azure.services.sqlserver.sqlserver_service import Server
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_va_scan_reports_configured:

View File

@@ -11,8 +11,7 @@ from prowler.providers.azure.services.sqlserver.sqlserver_service import (
Database,
Server,
)
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_sqlserver_vulnerability_assessment_enabled:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_blob_public_access_level_is_disabled:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.storage.v2022_09_01.models import NetworkRuleSet
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_default_network_access_rule_is_denied:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.storage.v2022_09_01.models import NetworkRuleSet
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_ensure_azure_services_are_trusted_to_access_is_enabled:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_ensure_encryption_with_customer_managed_keys:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_ensure_minimum_tls_version_12:

View File

@@ -4,8 +4,7 @@ from uuid import uuid4
from azure.mgmt.storage.v2023_01_01.models import PrivateEndpointConnection
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_ensure_private_endpoints_in_storage_accounts:

View File

@@ -7,8 +7,7 @@ from prowler.providers.azure.services.storage.storage_service import (
Account,
BlobProperties,
)
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_ensure_soft_delete_is_enabled:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_infrastructure_encryption_is_enabled:

View File

@@ -2,8 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.azure.services.storage.storage_service import Account
AZURE_SUBSCRIPTION = str(uuid4())
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION
class Test_storage_secure_transfer_required_is_enabled:

View File

@@ -201,6 +201,7 @@ class Test_Common_Output_Options:
arguments.verbose = True
arguments.only_logs = False
arguments.unix_timestamp = False
arguments.shodan = "test-api-key"
# Mock Azure Audit Info
audit_info = self.set_mocked_azure_audit_info()
@@ -241,6 +242,7 @@ class Test_Common_Output_Options:
arguments.verbose = True
arguments.only_logs = False
arguments.unix_timestamp = False
arguments.shodan = "test-api-key"
# Mock Azure Audit Info
audit_info = self.set_mocked_azure_audit_info()