-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnsg_audit.py
More file actions
93 lines (75 loc) · 4.21 KB
/
nsg_audit.py
File metadata and controls
93 lines (75 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import sys
from azure.identity import DefaultAzureCredential
from azure.mgmt.network import NetworkManagementClient
def check_nsgs_for_port_443_internet():
"""
Checks all NSGs in the specified subscription for inbound rules
allowing port 443 access from the internet.
"""
# --- ⚠️ REQUIRED: Specify your Azure Subscription ID here ⚠️ ---
# Replace this placeholder with the actual ID of the subscription you want to audit.
subscription_id = "xxxxxxx-xxxxxxx-xxxxxxx-xxxxxx-xxxxx"
if subscription_id == "YOUR_AZURE_SUBSCRIPTION_ID_HERE":
print("Error: Please replace 'YOUR_AZURE_SUBSCRIPTION_ID_HERE' with your actual Azure Subscription ID in the script.")
sys.exit(1)
# ------------------------------------------------------------------
# --- Configuration for the Audit ---
TARGET_PORT = "443"
INTERNET_SOURCES = ["*", "Internet", "0.0.0.0/0"]
INBOUND_DIRECTION = "Inbound"
ALLOW_ACCESS = "Allow"
# Authenticate using the currently logged-in Azure CLI/PowerShell user
try:
credential = DefaultAzureCredential()
except Exception as e:
print("Error acquiring Azure credentials. Ensure you are logged in via 'az login' or have environment variables set.")
print(f"Details: {e}")
sys.exit(1)
# Initialize the Network Management Client
network_client = NetworkManagementClient(
credential=credential,
subscription_id=subscription_id
)
print(f"--- Azure NSG Audit for Inbound Port {TARGET_PORT} from Internet (Subscription ID: {subscription_id}) ---")
print("-" * 80)
found_vulnerabilities = False
# List all NSGs in the subscription
# The list_all() method is used to retrieve NSGs across all resource groups in the subscription.
for nsg in network_client.network_security_groups.list_all():
# Safely extract the resource group name from the NSG's ID
resource_group_name = nsg.id.split('/resourceGroups/')[1].split('/')[0]
# Check each security rule in the NSG
for rule in nsg.security_rules:
# 1. Check for: Direction is Inbound and Access is Allow
if rule.direction == INBOUND_DIRECTION and rule.access == ALLOW_ACCESS:
# 2. Check for: Source is the Internet (e.g., *, Internet, 0.0.0.0/0)
is_internet_source = (
rule.source_address_prefix in INTERNET_SOURCES or
(rule.source_address_prefixes and any(p in INTERNET_SOURCES for p in rule.source_address_prefixes))
)
# 3. Check for: Destination port includes 443
port_range_match = False
# Check single port range property
if rule.destination_port_range and (rule.destination_port_range == TARGET_PORT or rule.destination_port_range == "*"):
port_range_match = True
# Check multiple port ranges property
if rule.destination_port_ranges:
for port_range in rule.destination_port_ranges:
# Checks for exact match "443" or wildcard "*"
if TARGET_PORT in port_range or port_range == "*":
port_range_match = True
break
if is_internet_source and port_range_match:
found_vulnerabilities = True
print(f"🚨 FOUND VULNERABILITY:")
print(f" NSG Name: {nsg.name}")
print(f" Resource Group: {resource_group_name}")
print(f" Rule Name: {rule.name}")
print(f" Priority: {rule.priority}")
print(f" Source: {rule.source_address_prefix or rule.source_address_prefixes}")
print(f" Destination Port: {rule.destination_port_range or rule.destination_port_ranges}")
print("-" * 80)
if not found_vulnerabilities:
print("✅ No NSGs found with inbound 'Allow' rules for port 443 from the general internet.")
if __name__ == "__main__":
check_nsgs_for_port_443_internet()