Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(azure): New check related with trusted launch in vm (#3616)
- Loading branch information
Showing
7 changed files
with
251 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
30 changes: 30 additions & 0 deletions
30
...iders/azure/services/vm/vm_trusted_launch_enabled/vm_trusted_launch_enabled.metadata.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"Provider": "azure", | ||
"CheckID": "vm_trusted_launch_enabled", | ||
"CheckTitle": "Ensure Trusted Launch is enabled on Virtual Machines", | ||
"CheckType": [], | ||
"ServiceName": "vm", | ||
"SubServiceName": "", | ||
"ResourceIdTemplate": "", | ||
"Severity": "high", | ||
"ResourceType": "Microsoft.Compute/virtualMachines", | ||
"Description": "When Secure Boot and vTPM are enabled together, they provide a strong foundation for protecting your VM from boot attacks. For example, if an attacker attempts to replace the bootloader with a malicious version, Secure Boot will prevent the VM from booting. If the attacker is able to bypass Secure Boot and install a malicious bootloader, vTPM can be used to detect the intrusion and alert you.", | ||
"Risk": "Secure Boot and vTPM work together to protect your VM from a variety of boot attacks, including bootkits, rootkits, and firmware rootkits. Not enabling Trusted Launch in Azure VM can lead to increased vulnerability to rootkits and boot-level malware, reduced ability to detect and prevent unauthorized changes to the boot process, and a potential compromise of system integrity and data security.", | ||
"RelatedUrl": "https://learn.microsoft.com/en-us/azure/virtual-machines/trusted-launch-existing-vm?tabs=portal", | ||
"Remediation": { | ||
"Code": { | ||
"CLI": "", | ||
"NativeIaC": "", | ||
"Other": "", | ||
"Terraform": "" | ||
}, | ||
"Recommendation": { | ||
"Text": "1. Go to Virtual Machines 2. For each VM, under Settings, click on Configuration on the left blade 3. Under Security Type, select 'Trusted Launch Virtual Machines' 4. Make sure Enable Secure Boot & Enable vTPM are checked 5. Click on Apply.", | ||
"Url": "https://learn.microsoft.com/en-us/azure/virtual-machines/trusted-launch-existing-vm?tabs=portal#enable-trusted-launch-on-existing-vm" | ||
} | ||
}, | ||
"Categories": [], | ||
"DependsOn": [], | ||
"RelatedTo": [], | ||
"Notes": "Secure Boot and vTPM are not currently supported for Azure Generation 1 VMs. IMPORTANT: Before enabling Secure Boot and vTPM on a Generation 2 VM which does not already have both enabled, it is highly recommended to create a restore point of the VM prior to remediation." | ||
} |
28 changes: 28 additions & 0 deletions
28
prowler/providers/azure/services/vm/vm_trusted_launch_enabled/vm_trusted_launch_enabled.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from prowler.lib.check.models import Check, Check_Report_Azure | ||
from prowler.providers.azure.services.vm.vm_client import vm_client | ||
|
||
|
||
class vm_trusted_launch_enabled(Check): | ||
def execute(self) -> Check_Report_Azure: | ||
findings = [] | ||
|
||
for subscription_name, vms in vm_client.virtual_machines.items(): | ||
for vm_id, vm in vms.items(): | ||
report = Check_Report_Azure(self.metadata()) | ||
report.status = "FAIL" | ||
report.subscription = subscription_name | ||
report.resource_name = vm.resource_name | ||
report.resource_id = vm_id | ||
report.status_extended = f"VM {vm.resource_name} has trusted launch disabled in subscription {subscription_name}" | ||
|
||
if ( | ||
vm.security_profile.security_type == "TrustedLaunch" | ||
and vm.security_profile.uefi_settings.secure_boot_enabled | ||
and vm.security_profile.uefi_settings.v_tpm_enabled | ||
): | ||
report.status = "PASS" | ||
report.status_extended = f"VM {vm.resource_name} has trusted launch enabled in subscription {subscription_name}" | ||
|
||
findings.append(report) | ||
|
||
return findings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
...s/providers/azure/services/vm/vm_trusted_launch_enabled/vm_trusted_launch_enabled_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
from unittest import mock | ||
from uuid import uuid4 | ||
|
||
from prowler.providers.azure.services.vm.vm_service import VirtualMachine | ||
from tests.providers.azure.azure_fixtures import AZURE_SUBSCRIPTION | ||
|
||
|
||
class Test_vm_trusted_launch_enabled: | ||
def test_vm_no_subscriptions(self): | ||
vm_client = mock.MagicMock | ||
vm_client.virtual_machines = {} | ||
|
||
with mock.patch( | ||
"prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled.vm_client", | ||
new=vm_client, | ||
): | ||
from prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled import ( | ||
vm_trusted_launch_enabled, | ||
) | ||
|
||
check = vm_trusted_launch_enabled() | ||
result = check.execute() | ||
assert len(result) == 0 | ||
|
||
def test_vm_no_vm(self): | ||
vm_client = mock.MagicMock | ||
vm_client.virtual_machines = {AZURE_SUBSCRIPTION: {}} | ||
|
||
with mock.patch( | ||
"prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled.vm_client", | ||
new=vm_client, | ||
): | ||
from prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled import ( | ||
vm_trusted_launch_enabled, | ||
) | ||
|
||
check = vm_trusted_launch_enabled() | ||
result = check.execute() | ||
assert len(result) == 0 | ||
|
||
def test_vm_trusted_launch_enabled(self): | ||
vm_id = str(uuid4()) | ||
vm_client = mock.MagicMock | ||
vm_client.virtual_machines = { | ||
AZURE_SUBSCRIPTION: { | ||
vm_id: VirtualMachine( | ||
resource_id="/subscriptions/resource_id", | ||
resource_name="VMTest", | ||
security_profile=mock.MagicMock( | ||
security_type="TrustedLaunch", | ||
uefi_settings=mock.MagicMock( | ||
secure_boot_enabled=True, | ||
v_tpm_enabled=True, | ||
), | ||
), | ||
storage_profile=mock.MagicMock( | ||
os_disk=mock.MagicMock( | ||
create_option="FromImage", | ||
managed_disk=mock.MagicMock(id="managed_disk_id"), | ||
), | ||
data_disks=[], | ||
), | ||
) | ||
} | ||
} | ||
|
||
with mock.patch( | ||
"prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled.vm_client", | ||
new=vm_client, | ||
): | ||
from prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled import ( | ||
vm_trusted_launch_enabled, | ||
) | ||
|
||
check = vm_trusted_launch_enabled() | ||
result = check.execute() | ||
assert len(result) == 1 | ||
assert result[0].status == "PASS" | ||
assert result[0].subscription == AZURE_SUBSCRIPTION | ||
assert result[0].resource_name == "VMTest" | ||
assert result[0].resource_id == vm_id | ||
assert ( | ||
result[0].status_extended | ||
== f"VM VMTest has trusted launch enabled in subscription {AZURE_SUBSCRIPTION}" | ||
) | ||
|
||
def test_vm_trusted_launch_disabled(self): | ||
vm_id = str(uuid4()) | ||
vm_client = mock.MagicMock | ||
vm_client.virtual_machines = { | ||
AZURE_SUBSCRIPTION: { | ||
vm_id: VirtualMachine( | ||
resource_id="/subscriptions/resource_id", | ||
resource_name="VMTest", | ||
security_profile=mock.MagicMock( | ||
security_type="TrustedLaunch", | ||
uefi_settings=mock.MagicMock( | ||
secure_boot_enabled=False, | ||
v_tpm_enabled=False, | ||
), | ||
), | ||
storage_profile=mock.MagicMock( | ||
os_disk=mock.MagicMock( | ||
create_option="FromImage", | ||
managed_disk=mock.MagicMock(id="managed_disk_id"), | ||
), | ||
data_disks=[], | ||
), | ||
) | ||
} | ||
} | ||
|
||
with mock.patch( | ||
"prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled.vm_client", | ||
new=vm_client, | ||
): | ||
from prowler.providers.azure.services.vm.vm_trusted_launch_enabled.vm_trusted_launch_enabled import ( | ||
vm_trusted_launch_enabled, | ||
) | ||
|
||
check = vm_trusted_launch_enabled() | ||
result = check.execute() | ||
assert len(result) == 1 | ||
assert result[0].status == "FAIL" | ||
assert result[0].subscription == AZURE_SUBSCRIPTION | ||
assert result[0].resource_name == "VMTest" | ||
assert result[0].resource_id == vm_id | ||
assert ( | ||
result[0].status_extended | ||
== f"VM VMTest has trusted launch disabled in subscription {AZURE_SUBSCRIPTION}" | ||
) |