1
+ # ----------------------------------------------------------------------------------
2
+ #
3
+ # Copyright Microsoft Corporation
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ # ----------------------------------------------------------------------------------
14
+
15
+ <#
16
+ . SYNOPSIS
17
+ Tests end to end scenario for SQL vulnerability assessment on SQL VM.
18
+ This test is live only because it cannot be recorded.
19
+ New-AzMonitorLogAnalyticsSolution cmdlet depends on Az.MonitoringSolution
20
+ which is a generated module and is not currently supported by the testing framework
21
+ #>
22
+ function Test-AzSecuritySqlVulnerabilityAssessment
23
+ {
24
+ # Setup
25
+ $testPrefix = " pssqlva"
26
+ $testParams = Get-SecuritySqlVulnerabilityAssessmentTestEnvironmentParameters $testPrefix
27
+ $vmResourceId = " /subscriptions/" + $testParams.subscriptionId + " /resourceGroups/" + $testParams.rgName + " /providers/Microsoft.Compute/VirtualMachines/" + $testParams.sqlVmNamePrefix
28
+ Create- TestEnvironmentWithParams $testParams
29
+
30
+ $vaScanRecord = Get-AzSecuritySqlVulnerabilityAssessmentScanRecord - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - ScanId latest
31
+ $resultsOnMaster = Get-AzSecuritySqlVulnerabilityAssessmentScanResult - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master
32
+ $resultsWithFindingsOnMaster = $resultsOnMaster | where { $_.Status -eq " Finding" }
33
+
34
+ Assert-True { $resultsOnMaster.Count -eq $vaScanRecord.TotalRulesCount }
35
+ Assert-True { $resultsWithFindingsOnMaster.Count -eq $vaScanRecord.TotalFailedRulesCount }
36
+
37
+ $finding = $resultsWithFindingsOnMaster | select - first 1
38
+ $ruleResult = Get-AzSecuritySqlVulnerabilityAssessmentScanResult - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - ScanId $vaScanRecord.Name - RuleId $finding.Name
39
+
40
+ Assert-True { $finding.Name -eq $ruleResult.Name }
41
+
42
+ # check add baseline with latest.
43
+ Add-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - RuleId $finding.Name
44
+
45
+ $baseline = Get-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - RuleId $finding.Name
46
+
47
+ Assert-NotNull $baseline
48
+
49
+ $baseline | Remove-AzSecuritySqlVulnerabilityAssessmentBaseline - Force
50
+
51
+ Assert-Throws { Get-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - RuleId $finding.Name }
52
+
53
+ # check Add baseline with result
54
+ Add-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - RuleId $finding.Name - Baseline $finding.QueryResults
55
+
56
+ $baseline = Get-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - RuleId $finding.Name
57
+ Assert-NotNull $baseline
58
+
59
+ $baseline | Remove-AzSecuritySqlVulnerabilityAssessmentBaseline - Force
60
+
61
+ # ## Check piping
62
+
63
+ $resultsOnMsdb = Get-AzSecuritySqlVulnerabilityAssessmentScanResult - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database msdb
64
+ $resultsWithFindingsOnMsdb = $resultsOnMsdb | where { $_.Status -eq " Finding" }
65
+ $rulesNamesOnMsdb = $resultsWithFindingsOnMsdb | select - ExpandProperty Name
66
+ $rulesNamesOnMaster = $resultsWithFindingsOnMaster | select - ExpandProperty Name
67
+
68
+ # get rules intersection between master and msdb
69
+ $ruleWithFindingsOnBothDbs = $rulesNamesOnMaster | ? {$rulesNamesOnMsdb -contains $_ }
70
+
71
+ if ($ruleWithFindingsOnBothDbs.Count -gt 0 )
72
+ {
73
+ # add baseline on master
74
+ Add-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - RuleId $ruleWithFindingsOnBothDbs [0 ]
75
+
76
+ # bypass it to msdb
77
+ Get-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - RuleId $ruleWithFindingsOnBothDbs [0 ] `
78
+ | Add-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database msdb
79
+
80
+ $baseline = Get-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database msdb - RuleId $ruleWithFindingsOnBothDbs [0 ]
81
+ Assert-NotNull $baseline
82
+ }
83
+
84
+ # Set all latest results as Baseline
85
+ Set-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - Force
86
+ $vaScanRecord = Get-AzSecuritySqlVulnerabilityAssessmentScanRecord - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - ScanId latest
87
+
88
+ Assert-True { $vaScanRecord.State -eq " Passed" }
89
+ Assert-True { $vaScanRecord.TotalFailedRulesCount -eq 0 }
90
+
91
+ Get-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master | Remove-AzSecuritySqlVulnerabilityAssessmentBaseline - Force
92
+
93
+ $baselineSet = @ {}
94
+ $resultsWithFindingsOnMaster | select - skip 3 | ForEach-Object { $baselineSet.Add ($_.RuleId , $_.QueryResults )}
95
+
96
+ Set-AzSecuritySqlVulnerabilityAssessmentBaseline - ResourceId $vmResourceId - WorkspaceId $testParams.workspaceId - Server $testParams.sqlServerName - Database master - BaselineSet $baselineSet - Force
97
+
98
+ Delete- TestEnvironments ($testParams )
99
+ }
100
+
101
+ <#
102
+ . SYNOPSIS
103
+ Gets the values of the parameters used at the tests
104
+ #>
105
+ function Get-SecuritySqlVulnerabilityAssessmentTestEnvironmentParameters ($testPrefix )
106
+ {
107
+ $location = Get-Location " Microsoft.Compute" " virtualMachines" " East Us 2 Euap" ;
108
+ $sqlVmName = getAssetName ($testPrefix + ' vm' );
109
+
110
+ return @ { subscriptionId = (Get-AzContext ).Subscription.Id;
111
+ rgName = getAssetName ($testPrefix );
112
+ sqlVmNamePrefix = $sqlVmName ;
113
+ sqlVmDomain_prefix = ' domainvm' ;
114
+ sqlVmMaxLength = 15 ;
115
+ sqlVmUserName = ' testuser' ;
116
+ sqlVmPassword = Generate- RandomVmPassword;
117
+ sqlServerImage = ' MicrosoftSQLServer:SQL2017-WS2016:Enterprise:latest' ;
118
+ sqlServerVmSize = ' Standard_DS2_v2' ;
119
+ sqlServerName = " MSSQLSERVER"
120
+ operationalInsightsWorkspaceName = getAssetName ($testPrefix + " psWorkspace" );
121
+ workspaceId = " " ;
122
+ location = location;
123
+ vmLocation = $location.Replace (' ' , ' ' );
124
+ vmDomainNameLabel = (getAssetName ($sqlVmName + ' -' )).ToLower();
125
+ }
126
+
127
+ }
128
+
129
+ <#
130
+ . SYNOPSIS
131
+ Creates the basic test environment needed to perform the sql vulnerability assessment tests - resource group, VM, workspace,... etc
132
+ #>
133
+ function Create-TestEnvironmentWithParams ($testParams )
134
+ {
135
+ # Create a new resource group.
136
+ New-AzResourceGroup - Name $testParams.rgName - Location $testParams.location
137
+
138
+ $passWord = ConvertTo-SecureString - String $testParams.sqlVmPassword - AsPlainText - Force
139
+ $cred = New-Object - TypeName System.Management.Automation.PSCredential - ArgumentList $testParams.sqlVmUserName , $passWord
140
+
141
+ # Create the sql virtual machine.
142
+ Write-Host " ResourceGroupName " + $testParams.rgName + " -Location " + $testParams.location " -Size " + $testParams.sqlServerVmSize + " -Image " + $testParams.sqlServerImage + " -Credential " + $cred " -Name " + $testParams.sqlVmNamePrefix
143
+
144
+ New-AzVm - ResourceGroupName $testParams.rgName - Location $testParams.vmLocation - Image $testParams.sqlServerImage - Credential $cred - Name $testParams.sqlVmNamePrefix - DomainNameLabel $testParams.vmDomainNameLabel
145
+
146
+ # Create the log analytics worskspace
147
+ $workspace = New-AzOperationalInsightsWorkspace - Location $testParams.location - Name $testParams.operationalInsightsWorkspaceName - ResourceGroupName $testParams.rgName
148
+ New-AzMonitorLogAnalyticsSolution - Type SQLVulnerabilityAssessment - ResourceGroupName $testParams.rgName - Location $testParams.location - WorkspaceResourceId $workspace.ResourceId
149
+
150
+ # Install microsoft Monitoring agent on the VM
151
+ $workspaceKeys = Get-AzOperationalInsightsWorkspaceSharedKey - Name $testParams.operationalInsightsWorkspaceName - ResourceGroupName $testParams.rgName
152
+ $publicSettings = @ {" workspaceId" = $workspace.CustomerId }
153
+ $protectedSettings = @ {" workspaceKey" = $workspaceKeys.PrimarySharedKey }
154
+
155
+ $testParams.workspaceId = $workspace.CustomerId ;
156
+
157
+ Set-AzVMExtension - ExtensionName " MicrosoftMonitoringAgent" `
158
+ - ResourceGroupName $testParams.rgName `
159
+ - VMName $testParams.sqlVmNamePrefix `
160
+ - Publisher " Microsoft.EnterpriseCloud.Monitoring" `
161
+ - ExtensionType " MicrosoftMonitoringAgent" `
162
+ - TypeHandlerVersion 1.0 `
163
+ - Settings $publicSettings `
164
+ - ProtectedSettings $protectedSettings `
165
+ - Location $testParams.vmLocation
166
+
167
+ # Update the registery and restart the Monitoring agent to force a scan.
168
+ Invoke-AzVMRunCommand - ResourceGroupName $testParams.rgName - Name $testParams.sqlVmNamePrefix - CommandId ' RunPowerShellScript' - ScriptPath ' SqlVulnerabilityAssessmentTestResources\SetUpVm.ps1'
169
+
170
+ Start-Sleep - Seconds 180
171
+ }
172
+
173
+ <#
174
+ . SYNOPSIS
175
+ Deletes the Test enviroment once the test passes.
176
+ #>
177
+ function Delete-TestEnvironments ($testParams )
178
+ {
179
+ New-AzResourceGroup - Name $testParams.rgName
180
+ }
181
+
182
+ <#
183
+ . SYNOPSIS
184
+ Generates a random password for vm that satisfies these conditions:
185
+ - At least 15 character long
186
+ - Contains at at least one number
187
+ - Contains at least one lower case letter
188
+ - Contains at least one upper case letter
189
+ #>
190
+ function Generate-RandomVmPassword ()
191
+ {
192
+ $password = (" abcdefghijklmnopqrstuvwxyz" .tochararray() | sort {Get-Random })[0 .. 4 ] -join ' '
193
+ $password += (" ABCDEFGHIJKLMNOPQRSTUVWXYZ" .tochararray() | sort {Get-Random })[0 .. 7 ] -join ' '
194
+ $password += (" 0123456789" .tochararray() | sort {Get-Random })[0 .. 4 ] -join ' '
195
+
196
+ return ($password.tochararray () | sort {Get-Random }) -join ' '
197
+ }
0 commit comments