├── Audit_PostGre_Server_parameters.ps1 ├── Audit_sqlDB_audit_set_On.ps1 ├── Audit_webapp_TLs_version.ps1 ├── Audit_webapp_netframework.ps1 ├── Audit_webapps.ps1 ├── MySQL_'Enforce SSL connection'.ps1 ├── README.md ├── asc_contact_settings.ps1 ├── asc_storage_https_recs_report.ps1 ├── asc_vm_sshrdp_recs_report.ps1 ├── audit-webapp_httpsonly.ps1 ├── audit_sqldb_allow_ingress.ps1 ├── check_network_watcher_enabled.ps1 ├── check_sqlData_encryption_status.ps1 ├── check_storage_publicaccess.ps1 ├── diagnostics_for_keyvault.ps1 ├── logprofilesettings.ps1 └── remediation ├── Remediate _Retention is 'greater than 90 days'.ps1 ├── Remediate_ActivityLog_retention.ps1 ├── Remediate_MySQL_'Enforce SSL connection'.ps1 ├── Remediate_PostGre_SSLEnforcement.ps1 ├── Remediate_PostGre_con_throttling.ps1 ├── Remediate_PostGre_log_checkpoints.ps1 ├── Remediate_PostGre_log_connections.ps1 ├── Remediate_PostGre_log_disconnections.ps1 ├── Remediate_PostGre_log_duration.ps1 ├── Remediate_PostGre_log_retention_days.ps1 ├── Remediate_activity_audit.ps1 ├── Remediate_activity_locations.ps1 ├── Remediate_allow_ingress.ps1 ├── Remediate_logprofile.ps1 ├── Remediate_sqlDB_Action_groups.ps1 ├── Remediate_sqlDB_audit_set_On.ps1 ├── Remediate_sqlData_encryption.ps1 ├── Remediate_webapp_httpsonly.ps1 ├── Remediate_webapp_minTLsVersion.ps1 ├── Remediate_webapp_netframework.ps1 ├── readme.md ├── remediate_asc_contactinfo.ps1 ├── remediate_public_storage.ps1 └── remediate_storage_https.ps1 /Audit_PostGre_Server_parameters.ps1: -------------------------------------------------------------------------------- 1 |  2 | $shellOutFilePath = "~/clouddrive/PostGre_Parameters.csv" 3 | 4 | 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub -ErrorAction Ignore | Set-AzContext | foreach { 6 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre | select ` 7 | @{n='SubscriptionName';e={$AzureRMSub.Name}}, ` 8 | ResourceGroupName,Name, ` 9 | @{n='log_checkpoints'; 10 | e={(Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 11 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 12 | -ResourceName (-join $PostGre.Name + "/log_checkpoints") -ApiVersion 2017-12-01).Properties.value}}, ` 13 | @{n='SSL_Enforcement';e={$PostGre.Properties.sslEnforcement}}, ` 14 | @{n='log_connections';e={(Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 15 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 16 | -ResourceName (-join $PostGre.Name + "/log_connections") -ApiVersion 2017-12-01).Properties.value}}, ` 17 | @{n='log_disconnections';e={(Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 18 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 19 | -ResourceName (-join $PostGre.Name + "/log_disconnections") -ApiVersion 2017-12-01).Properties.value}}, ` 20 | @{n='log_duration';e={(Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 21 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 22 | -ResourceName (-join $PostGre.Name + "/log_duration") -ApiVersion 2017-12-01).Properties.value}}, ` 23 | @{n='connection_throttling';e={(Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 24 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 25 | -ResourceName (-join $PostGre.Name + "/connection_throttling") -ApiVersion 2017-12-01).Properties.value}}, ` 26 | @{n='log_retention_days';e={(Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 27 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 28 | -ResourceName (-join $PostGre.Name + "/log_retention_days") -ApiVersion 2017-12-01).Properties.value}} 29 | } | Export-CSV $shellOutFilePath -NoTypeInformation 30 | -------------------------------------------------------------------------------- /Audit_sqlDB_audit_set_On.ps1: -------------------------------------------------------------------------------- 1 | # Login-AzAccount 2 | 3 | $shellOutFilePath = "~/clouddrive/sqlaudit_status.csv" 4 | 5 | #loop through all subscriptions 6 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 7 | Get-AzSqlServer -ErrorAction Ignore | Get-AzSqlDatabase -pipelinevariable sqldb | Get-AzSqlDatabaseAuditing | Export-Csv $shellOutFilePath -Append -NoTypeInformation 8 | } -------------------------------------------------------------------------------- /Audit_webapp_TLs_version.ps1: -------------------------------------------------------------------------------- 1 | # Audit web app is using the latest version of TLS encryption 2 | 3 | $shellOutFilePath = "~/clouddrive/webapp_minTLs_version.csv" 4 | 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub -ErrorAction Ignore | Set-AzContext | foreach { 6 | Get-AzResource -ResourceType Microsoft.Web/sites -ErrorAction Ignore -PipelineVariable webapp | select ` 7 | @{n='SubscriptionName';e={$AzureRMSub.Name}}, ` 8 | ResourceGroupName,Name, ` 9 | @{n='minTlsVersion';e={(Get-AzResource -ResourceGroupName newscriptrg -ResourceType Microsoft.Web/sites/config -ResourceName (-join $webapp.Name + "/web") -ApiVersion 2018-02-01).Properties.minTlsVersion}} 10 | 11 | } | Export-CSV $shellOutFilePath -NoTypeInformation 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Audit_webapp_netframework.ps1: -------------------------------------------------------------------------------- 1 |  2 | # Audit web app is using the latest version of .Netframework 3 | $shellOutFilePath = "~/clouddrive/webapp_netframework.csv" 4 | 5 | #loop through all subscriptions 6 | $report = @() 7 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 8 | $webapps = Get-AzWebApp 9 | Foreach ($webapp in $Webapps){ 10 | $webappfull = $webapp| Get-AzWebApp 11 | $repwebapp = New-Object –TypeName PSObject 12 | $repwebapp | Add-Member –MemberType NoteProperty –Name SubscriptionName –Value $AzureRMSub.Name 13 | $repwebapp | Add-Member –MemberType NoteProperty –Name ResourceGroupName –Value $webappfull.ResourceGroup 14 | $repwebapp | Add-Member –MemberType NoteProperty –Name Name –Value $webappfull.Name 15 | $repwebapp | Add-Member –MemberType NoteProperty –Name NetFrameworkVersion –Value $webappfull.SiteConfig.NetFrameworkVersion 16 | $report += $repwebapp 17 | }} 18 | $report | Export-Csv $shellOutFilePath -------------------------------------------------------------------------------- /Audit_webapps.ps1: -------------------------------------------------------------------------------- 1 | $shellOutFilePath = "~/clouddrive/webapp_win_language_version.csv" 2 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach{ 3 | Get-AzResource -ResourceType microsoft.web/sites -ExpandProperties -PipelineVariable webapp| select ` 4 | @{n='SubscriptionName';e={$AzureRMSub.Name}}, ` 5 | ResourceGroupName,Name, ` 6 | @{n='Kind';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites -Name $webapp.Name -ApiVersion 2018-02-01).kind}}, ` 7 | @{n='linuxFxVersion';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites/config -Name $webapp.Name -ApiVersion 2018-02-01).Properties.linuxFxVersion}}, ` 8 | @{n='HTTPVersion';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites/config -Name $webapp.Name -ApiVersion 2018-02-01).Properties.http20Enabled}}, ` 9 | @{n='NetFrameworkVersion';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites/config -Name $webapp.Name -ApiVersion 2018-02-01).Properties.netFrameworkVersion}}, ` 10 | @{n='PhpVersion';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites/config -Name $webapp.Name -ApiVersion 2018-02-01).Properties.phpVersion}}, ` 11 | @{n='PythonVersion';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites/config -Name $webapp.Name -ApiVersion 2018-02-01).Properties.pythonVersion}}, ` 12 | @{n='JavaVersion';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites/config -Name $webapp.Name -ApiVersion 2018-02-01).Properties.javaVersion}}, ` 13 | @{n='MinTLsVersion';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites/config -Name $webapp.Name -ApiVersion 2018-02-01).Properties.minTlsVersion}}, ` 14 | @{n='HTTPSOnly';e={(Get-AzResource -ResourceGroupName $webapp.ResourceGroupName -ResourceType microsoft.web/sites -Name $webapp.Name -ApiVersion 2018-02-01).Properties.httpsOnly}} 15 | } | Export-Csv $shellOutFilePath -Append -NoTypeInformation 16 | 17 | 18 | -------------------------------------------------------------------------------- /MySQL_'Enforce SSL connection'.ps1: -------------------------------------------------------------------------------- 1 |  2 | $shellOutFilePath = "~/clouddrive/mysql_sslencryption.csv" 3 | 4 | #loop through all subscriptions 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 6 | 7 | $mysql = Get-AzResource -ResourceType Microsoft.DBforMySQL/servers -ErrorAction Ignore -ExpandProperties 8 | 9 | $Mysqlssl = New-Object –TypeName PSObject 10 | 11 | $Mysqlssl | Add-Member –MemberType NoteProperty –Name Name –Value $mysql.Name 12 | $Mysqlssl | Add-Member –MemberType NoteProperty –Name Subscription –Value $mysql.ResourceGroupName 13 | 14 | $Mysqlssl | Add-Member –MemberType NoteProperty –Name SSLConnection –Value $mysql.Properties.sslEnforcement 15 | 16 | 17 | $Mysqlssl | Export-CSV $shellOutFilePath } 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Azure CIS 2 | Powershell scripts to report and remediate on components from the CIS benchmarks for Azure. 3 | Scripts are intended to run in the Azure CloudShell using the AZ PowerShell module. Any outputs will be written to CloudDrive 4 | 5 | As of 6/12/19 the AZ.security module is not yet native in CloudShell. Run "Import-module Az.Security" into your cloudshell before executing. 6 | 7 | Scripts with names starting with "remediate" will make changes! Be sure to validate before executing. These are stored in the "Remediation" folder. 8 | 9 | Information about CIS Benchmarks for Azure can be found here: https://azure.microsoft.com/en-us/resources/cis-microsoft-azure-foundations-security-benchmark/ 10 | 11 | To enforce benchmarks to new deployments use Azure Policy. See this repo for some great examples: https://github.com/mrajess/Azure-Policy-CIS 12 | 13 | For information on making sure all VMs are protected by Azure Security Center, see here: https://techcommunity.microsoft.com/t5/Security-Identity/Identify-Azure-VMs-which-are-not-monitored-by-Security-Center/td-p/733672 14 | -------------------------------------------------------------------------------- /asc_contact_settings.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | $contact = get-azsecuritycontact 3 | if ($contact -eq $null -or $contact.email -eq $null -or $contact.phone -eq $null -or $contact.AlertNotifications -eq $null -or $contact.AlertstoAdmins -eq $null) 4 | {AzureRMsub | out-file ~/clouddrive/ASC_contacts_not_set.csv -append} 5 | } 6 | -------------------------------------------------------------------------------- /asc_storage_https_recs_report.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | $azsectask = get-azsecuritytask 3 | $azsectask | where RecommendationType -EQ "Require secure transfer to storage account" | foreach { 4 | Write-host "$($_.ResourceId)" 5 | $_ | select ` 6 | @{n='Sub';e={$_.ResourceId.split('/')[-7]}}, ` 7 | @{n='SAName';e={$_.ResourceId.split('/')[-1]}} 8 | } | export-csv ~/clouddrive/sahttps.csv -Append -NoTypeInformation 9 | } 10 | 11 | -------------------------------------------------------------------------------- /asc_vm_sshrdp_recs_report.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | $azsectask = get-azsecuritytask 3 | $azsectask | where RecommendationType -EQ "Close management ports on your Virtual Machines" | foreach { 4 | $_.ResourceId 5 | $info = $_.ResourceId 6 | $sub = $info.split('/')[-7] 7 | $saname = $info.split('/')[-1] 8 | $file = $sub + ',' + $saname 9 | $file | Out-File ~/clouddrive/openrdpssh.csv -Append 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /audit-webapp_httpsonly.ps1: -------------------------------------------------------------------------------- 1 | # Audit web app redirects all HTTP traffic to HTTPS in Azure App Service 2 | 3 | $shellOutFilePath = "~/clouddrive/webapp_redirect_status.csv" 4 | 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach{ 6 | Get-AzWebApp -ErrorAction Ignore -PipelineVariable webapp | select ` 7 | @{n='SubscriptionName';e={$AzureRMSub.Name}}, ` 8 | @{n='ResourceGroupName';e={$webapp.ResourceGroup}}, ` 9 | @{n='Name';e={$webapp.Name}}, ` 10 | @{n='HttptoHttpsOnly';e={$webapp.HttpsOnly}} 11 | } | Export-Csv $shellOutFilePath -Append -NoTypeInformation 12 | 13 | 14 | -------------------------------------------------------------------------------- /audit_sqldb_allow_ingress.ps1: -------------------------------------------------------------------------------- 1 | # Login-AzureRmAccount 2 | 3 | $shellOutFilePath = "~/clouddrive/sqlData_allow_ingress.csv" 4 | 5 | 6 | 7 | #loop through all subscriptions 8 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 9 | Get-AzSqlServer -ErrorAction Ignore -pipelinevariable sqlsvr | Get-AzSqlServerFirewallRule -FirewallRuleName AllowAllWindowsAzureIps | Export-Csv $shellOutFilePath -Append -NoTypeInformation 10 | } 11 | 12 | -------------------------------------------------------------------------------- /check_network_watcher_enabled.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | $watcher = get-aznetworkwatcher 3 | if ($watcher -eq $null) 4 | {$AzureRmsub | out-file ~/clouddrive/subs_watchernotenabled.csv -Append }} -------------------------------------------------------------------------------- /check_sqlData_encryption_status.ps1: -------------------------------------------------------------------------------- 1 |  2 | $shellOutFilePath = "~/clouddrive/sqlData_encryption_status.csv" 3 | 4 | #loop through all subscriptions 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 6 | Get-AzSqlServer -ErrorAction Ignore | Get-AzSqlDatabase -pipelinevariable sqldb | Get-AzSqlDatabaseTransparentDataEncryption | Export-Csv $shellOutFilePath -Append -NoTypeInformation 7 | } -------------------------------------------------------------------------------- /check_storage_publicaccess.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | Get-AzStorageAccount | Get-AzStorageContainer -pipelinevariable azstorcont | ` 3 | where {$azstorcont.PublicAccess -NE "Off" | Out-File ~/clouddrive/publicstorage.txt -append}} 4 | -------------------------------------------------------------------------------- /diagnostics_for_keyvault.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | 3 | $azsectask = get-azsecuritytask 4 | 5 | $azsectask | where RecommendationType -EQ "Diagnostics logs in Key Vault should be enabled" | foreach { 6 | 7 | Write-host "$($_.ResourceId)" 8 | 9 | $_ | select ` 10 | 11 | @{n='Sub';e={$_.ResourceId.split('/')[-7]}}, ` 12 | 13 | @{n='Kvname';e={$_.ResourceId.split('/')[-1]}} 14 | 15 | } | export-csv ~/clouddrive/kvdiags.csv -Append -NoTypeInformation 16 | 17 | } 18 | -------------------------------------------------------------------------------- /logprofilesettings.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | $lp = get-azlogprofile 3 | $count = $lp.locations | measure-object 4 | if ($count -lt '33') { $azurermsub | out-file ~/clouddrive/lp_not_all_regions.txt} 5 | if ($lp.id -eq $null) {$azurermsub | out-file ~/clouddrive/nologprofile.txt} 6 | if ($lp.retentionpolicy.enabled -eq 'False') {out-file ~/clouddrive/lP_no_retention.txt} 7 | elseif ($lp.retentionpolicy.days -lt'365') {out-file ~/clouddrive/lP_short_retention.txt}} -------------------------------------------------------------------------------- /remediation/Remediate _Retention is 'greater than 90 days'.ps1: -------------------------------------------------------------------------------- 1 |  2 | 3 | #loop through all subscriptions 4 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 5 | Get-AzSqlServer -ErrorAction Ignore | Get-AzSqlserverAuditing -ErrorAction Ignore -pipelinevariable dbaudit | ` 6 | where {$dbaudit.RetentionInDays -le 90} | foreach { 7 | If($dbaudit.RetentionInDays -le 90){ 8 | $dbaudit | Set-AzSqlServerAuditing -State Enabled -RetentionInDays 91 9 | 10 | } 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /remediation/Remediate_ActivityLog_retention.ps1: -------------------------------------------------------------------------------- 1 | # Remediate Log retention is 365 Days or more 2 | # 365 is the limit 3 | 4 | #loop through all subscriptions 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 6 | Get-AzLogProfile -ErrorAction Ignore -pipelinevariable log | ` 7 | where {$log.RetentionPolicy.Days -le 365} | foreach { 8 | If($log.RetentionPolicy.Days -le 365){ 9 | # $log.RetentionPolicy.Days = "366" 10 | $log | Add-AzLogProfile -Name $log.Name -StorageAccountId $log.StorageAccountId -Location $log.Locations -RetentionInDays 365 -Category Write,Delete,Action 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /remediation/Remediate_MySQL_'Enforce SSL connection'.ps1: -------------------------------------------------------------------------------- 1 |  2 | #loop through all subscriptions 3 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 4 | Get-AzResource -ResourceType Microsoft.DBforMySQL/servers -ErrorAction Ignore -ExpandProperties -pipelinevariable mysql | ` 5 | where {$mysql.properties.sslEnforcement -eq "Disabled"} | foreach { 6 | $mysql.Properties.sslEnforcement = 'Enabled' 7 | $mysql | Set-AzResource -Force 8 | 9 | } 10 | } 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /remediation/Remediate_PostGre_SSLEnforcement.ps1: -------------------------------------------------------------------------------- 1 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 2 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre | foreach{ 3 | If($PostGre.properties.sslEnforcement -eq "Disabled"){ 4 | $PostGre.Properties.sslEnforcement = 'Enabled'; 5 | $PostGre | Set-AzResource -Force; 6 | } 7 | } 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /remediation/Remediate_PostGre_con_throttling.ps1: -------------------------------------------------------------------------------- 1 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 2 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre | foreach{ 3 | $logcon = Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 4 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 5 | -ResourceName (-join $PostGre.Name + '/connection_throttling') -ApiVersion 2017-12-01; 6 | If($logcon.Properties.Value -eq "OFF"){ 7 | $logcon.Properties.Value = 'on'; 8 | $logcon | Set-AzResource -ApiVersion 2017-12-01 -Force; 9 | } 10 | } 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /remediation/Remediate_PostGre_log_checkpoints.ps1: -------------------------------------------------------------------------------- 1 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 2 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre | foreach{ 3 | $logcon = Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 4 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 5 | -ResourceName (-join $PostGre.Name + '/log_checkpoints') -ApiVersion 2017-12-01; 6 | If($logcon.Properties.Value -eq "OFF"){ 7 | $logcon.Properties.Value = 'on'; 8 | $logcon | Set-AzResource -ApiVersion 2017-12-01 -Force; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /remediation/Remediate_PostGre_log_connections.ps1: -------------------------------------------------------------------------------- 1 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 2 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre | foreach{ 3 | $logcon = Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 4 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 5 | -ResourceName (-join $PostGre.Name + '/log_connections') -ApiVersion 2017-12-01; 6 | If($logcon.Properties.Value -eq "OFF"){ 7 | $logcon.Properties.Value = 'on'; 8 | $logcon | Set-AzResource -ApiVersion 2017-12-01 -Force; 9 | } 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /remediation/Remediate_PostGre_log_disconnections.ps1: -------------------------------------------------------------------------------- 1 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 2 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre | foreach{ 3 | $logcon = Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 4 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 5 | -ResourceName (-join $PostGre.Name + '/log_disconnections') -ApiVersion 2017-12-01; 6 | If($logcon.Properties.Value -eq "OFF"){ 7 | $logcon.Properties.Value = 'on'; 8 | $logcon.Properties.source = 'user-override'; 9 | $logcon | Set-AzResource -ApiVersion 2017-12-01 -Force; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /remediation/Remediate_PostGre_log_duration.ps1: -------------------------------------------------------------------------------- 1 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 2 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre| foreach{ 3 | $logcon = Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 4 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 5 | -ResourceName (-join $PostGre.Name + '/log_duration') -ApiVersion 2017-12-01; 6 | If($logcon.Properties.Value -eq "OFF"){ 7 | $logcon.Properties.Value = 'on'; 8 | $logcon.Properties.source = 'user-override'; 9 | $logcon | Set-AzResource -ApiVersion 2017-12-01 -Force; 10 | } 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /remediation/Remediate_PostGre_log_retention_days.ps1: -------------------------------------------------------------------------------- 1 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 2 | Get-AzResource -ResourceType Microsoft.DBforPostgreSQL/servers -ExpandProperties -ErrorAction Ignore -PipelineVariable PostGre | foreach{ 3 | $logcon = Get-AzResource -ResourceGroupName $PostGre.ResourceGroupName ` 4 | -ResourceType Microsoft.DBforPostgreSQL/servers/configurations ` 5 | -ResourceName (-join $PostGre.Name + '/log_retention_days') -ApiVersion 2017-12-01; 6 | If($logcon.Properties.Value -le 3){ 7 | $logcon.Properties.Value = 4; 8 | $logcon | Set-AzResource -ApiVersion 2017-12-01 -Force; 9 | } 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /remediation/Remediate_activity_audit.ps1: -------------------------------------------------------------------------------- 1 | # Remediate Log retention is 365 Days or more 2 | 3 | #loop through all subscriptions 4 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 5 | Get-AzLogProfile -ErrorAction Ignore -pipelinevariable log | ` 6 | where {$log.Categories -notmatch "Write 7 | Delete 8 | Action" } | foreach { 9 | $log | Add-AzLogProfile -Name $log.Name -StorageAccountId $log.StorageAccountId -Location $log.Locations -RetentionInDays 365 -Category Write,Delete,Action 10 | } 11 | } -------------------------------------------------------------------------------- /remediation/Remediate_activity_locations.ps1: -------------------------------------------------------------------------------- 1 | # Remediate Locations 2 | 3 | 4 | $locations = (Get-AzLocation).Location 5 | $locations += "global" 6 | #loop through all subscriptions 7 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 8 | Get-AzLogProfile -ErrorAction Ignore -pipelinevariable log | ` 9 | where {$log.locations -notmatch $locations} | foreach { 10 | $log | Add-AzLogProfile -Name $log.Name -StorageAccountId $log.StorageAccountId -Location $locations -RetentionInDays 365 -Category Write,Delete,Action 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /remediation/Remediate_allow_ingress.ps1: -------------------------------------------------------------------------------- 1 | # remove sqlserverfirewallrul "allowallwindowsazureips" 2 | 3 | #loop through all subscriptions 4 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 5 | Get-AzSqlServer -ErrorAction Ignore | Get-AzSqlServerFirewallRule -pipelinevariable sqlfw | ` 6 | where {$sqlfw.FirewallRuleName -eq "AllowAllWindowsAzureIps"} | foreach { 7 | $sqlfw | remove-AzSqlServerFirewallRule -FirewallRuleName "AllowAllWindowsAzureIps" 8 | 9 | } 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /remediation/Remediate_logprofile.ps1: -------------------------------------------------------------------------------- 1 | #enable EH for a list of subscriptions 2 | 3 | # login to azure account 4 | Login-AzAccount 5 | 6 | # Settings needed for the new log profile 7 | $logProfileName = "default" 8 | $locations = (Get-AzLocation).Location 9 | $locations += "global" 10 | $subscriptionId = "bd8a379d-3838-4d9b-b7be-6e33d82a33de" 11 | $resourceGroupName = "Default-ActivityLogAlerts" 12 | $eventHubNamespace = "hwscevents" 13 | 14 | # Build the service bus rule Id from the settings above 15 | $serviceBusRuleId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.EventHub/namespaces/$eventHubNamespace/authorizationrules/RootManageSharedAccessKey" 16 | 17 | $path = 'C:\Temp\substoeh.txt' 18 | $sub = (Get-Content -Path $path) 19 | 20 | foreach ($s in $sub) { 21 | Select-AzSubscription -subscription $s 22 | Add-AzLogProfile -Name $logProfileName -Location $locations -ServiceBusRuleId $serviceBusRuleId 23 | } 24 | -------------------------------------------------------------------------------- /remediation/Remediate_sqlDB_Action_groups.ps1: -------------------------------------------------------------------------------- 1 |  #loop through all subscriptions 2 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 3 | Get-AzSqlServer -ErrorAction Ignore | Get-AzSqlserverAuditing -ErrorAction Ignore -pipelinevariable dbaudit | ` 4 | where {$dbaudit.AuditActionGroup -notmatch "SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP 5 | FAILED_DATABASE_AUTHENTICATION_GROUP 6 | BATCH_COMPLETED_GROUP"} | foreach { 7 | $dbaudit| Set-AzSqlServerAuditing -State Enabled -AuditActionGroup @('SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP', 'FAILED_DATABASE_AUTHENTICATION_GROUP', 'BATCH_COMPLETED_GROUP') 8 | 9 | } 10 | } 11 | 12 | ###### Informational#### 13 | # WARNING: NOTE : Go to https://aka.ms/azps-changewarnings for steps to suppress this breaking change warning, and other information on breaking changes in Azure PowerShell. 14 | # WARNING: Breaking changes in the cmdlet 'Get-AzSqlServerAuditing' : 15 | # WARNING: - The cmdlet 'GetAzSqlServerAudit' is replacing this cmdlet. -------------------------------------------------------------------------------- /remediation/Remediate_sqlDB_audit_set_On.ps1: -------------------------------------------------------------------------------- 1 | # Login-AzAccount 2 | 3 | 4 | $bloblstoragename = "dqlauditblob" 5 | 6 | #loop through all subscriptions 7 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 8 | Get-AzSqlServer -ErrorAction Ignore | Get-AzSqlserverAuditing -ErrorAction Ignore -pipelinevariable dbaudit | ` 9 | where {$dbaudit.AuditState -eq "Disabled"} | foreach { 10 | $dbaudit | Set-AzSqlServerAuditing -State Enabled -StorageAccountName "dqlauditblob" -RetentionInDays 91 11 | 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /remediation/Remediate_sqlData_encryption.ps1: -------------------------------------------------------------------------------- 1 |  2 | 3 | #loop through all subscriptions 4 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 5 | Get-AzSqlServer -ErrorAction Ignore | Get-AzSqlDatabase -pipelinevariable sqldb | Get-AzSqlDatabaseTransparentDataEncryption -ErrorAction Ignore -PipelineVariable sqltde | ` 6 | where {$sqltde.State -eq "Disabled"} | foreach { 7 | $sqltde | Set-AzSqlDatabaseTransparentDataEncryption -State Enabled -ErrorAction Ignore 8 | 9 | }} 10 | 11 | 12 | -------------------------------------------------------------------------------- /remediation/Remediate_webapp_httpsonly.ps1: -------------------------------------------------------------------------------- 1 | # Enforce web app redirects all HTTP traffic to HTTPS in Azure App Service 2 | 3 | 4 | #loop through all subscriptions 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 6 | Get-AzWebApp -ErrorAction Ignore -PipelineVariable webapp | ` 7 | where {$webapp.HttpsOnly -ne $true} | foreach { 8 | $webapp | Set-Azwebapp -ResourceGroupName $webapp.ResourceGroup -HttpsOnly $true 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /remediation/Remediate_webapp_minTLsVersion.ps1: -------------------------------------------------------------------------------- 1 |  2 | Get-AzContext -ListAvailable -PipelineVariable AzuremSub | Set-AzContext |foreach{ 3 | Get-AzResource -ResourceType Microsoft.Web/sites -ErrorAction Ignore -PipelineVariable webapp| foreach{ 4 | $mintls = Get-AzResource -ResourceGroupName $webapp.ResourceGroupName ` 5 | -ResourceType Microsoft.Web/sites/config ` 6 | -ResourceName (-join $webapp.Name + '/web') -ApiVersion 2018-02-01; 7 | If($mintls.Properties.minTlsVersion -ne "1.2"){ 8 | $mintls.Properties.minTlsVersion = '1.2'; 9 | $mintls | Set-AzResource -ApiVersion 2018-02-01 -Force; 10 | } 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /remediation/Remediate_webapp_netframework.ps1: -------------------------------------------------------------------------------- 1 |  # Remediate web app is using the latest version of .Netframework 2 | #latest version 3 | $latestversion = "v4.0" 4 | #loop through all subscriptions 5 | Get-AzContext -ListAvailable -PipelineVariable AzureRMSub | Set-AzContext | foreach { 6 | Get-AzWebApp -ErrorAction Ignore -PipelineVariable webapp | ` 7 | where {$webapp.SiteConfig.NetFrameworkVersion -ne $latestversion} | foreach { 8 | $webapp | Set-Azwebapp -ResourceGroupName $webapp.ResourceGroup -NetFrameworkVersion $latestversion 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /remediation/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /remediation/remediate_asc_contactinfo.ps1: -------------------------------------------------------------------------------- 1 | $contactemail = 'email@customer.com' 2 | $contactph = '555-555-5555' 3 | 4 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 5 | 6 | $contact = get-azsecuritycontact 7 | 8 | if ($contact -eq $null -or $contact.email -eq $null -or $contact.phone -eq $null -or $contact.AlertNotifications -eq $null -or $contact.AlertstoAdmins -eq $null) 9 | 10 | {Set-AzSecurityContact -Name "default1" -Email $contactemail -Phone $contactph -AlertAdmin -NotifyOnAlert}} 11 | -------------------------------------------------------------------------------- /remediation/remediate_public_storage.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | 3 | Get-AzStorageAccount | Get-AzStorageContainer -pipelinevariable azstorcont | ` 4 | 5 | where {$azstorcont.PublicAccess -NE "Off" }| Set-AzStorageContainerAcl -Permission "Off" -passthru} 6 | -------------------------------------------------------------------------------- /remediation/remediate_storage_https.ps1: -------------------------------------------------------------------------------- 1 | get-azcontext -listavailable -pipelinevariable AzureRMSub | set-azcontext | foreach { 2 | 3 | $azsectask = get-azsecuritytask 4 | 5 | $azsectask | where RecommendationType -EQ "Require secure transfer to storage account" | foreach { 6 | 7 | Set-AzStorageAccount -ResourceGroupName $_.resourceid.split('/')[-5] -accountname $_.resourceid.split('/')[-1] -EnableHttpsTrafficOnly $true 8 | 9 | } 10 | 11 | } 12 | --------------------------------------------------------------------------------