Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temp changes for SDN Express WDAC #569

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added SDNExpress/scripts/RefreshPolicy.exe
Binary file not shown.
2 changes: 1 addition & 1 deletion SDNExpress/scripts/SDNExpress.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ try {
New-SDNExpressNetworkController @params

write-SDNExpressLog "STAGE 2.0.1: Sleeping 5 minutes after NC install."
Start-Sleep -seconds 300
#Start-Sleep -seconds 300

write-SDNExpressLog "STAGE 2.1: Getting REST cert thumbprint in order to find it in local root store."
$NCHostCertThumb = invoke-command -ComputerName $NCNodes[0] -Credential $credential {
Expand Down
95 changes: 57 additions & 38 deletions SDNExpress/scripts/SDNExpressModule.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -1215,44 +1215,9 @@ Function Add-SDNExpressHost {
function private:write-verbose { param([String] $Message) write-output "[V]"; write-output $Message}
function private:write-output { param([PSObject[]] $InputObject) write-output "$($InputObject.count)"; write-output $InputObject}

$NodeFQDN = (get-ciminstance win32_computersystem).DNSHostName+"."+(get-ciminstance win32_computersystem).Domain

$cert = get-childitem "cert:\localmachine\my" | where-object {$_.Subject.ToUpper() -eq "CN=$NodeFQDN".ToUpper()}
if ($Cert -eq $Null) {
write-verbose "Creating new host certificate."
$Cert = New-SelfSignedCertificate -Type Custom -KeySpec KeyExchange -Subject "CN=$NodeFQDN" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\LocalMachine\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2")
} else {
write-verbose "Found existing host certficate."
$HasServerEku = ($cert.EnhancedKeyUsageList | where-object {$_.ObjectId -eq "1.3.6.1.5.5.7.3.1"}) -ne $null
$HasClientEku = ($cert.EnhancedKeyUsageList | where-object {$_.ObjectId -eq "1.3.6.1.5.5.7.3.2"}) -ne $null

if (!$HasServerEku) {
throw "Host cert exists on $(hostname) but is missing the EnhancedKeyUsage for Server Authentication."
}
if (!$HasClientEku) {
throw "Host cert exists but $(hostname) is missing the EnhancedKeyUsage for Client Authentication."
}
write-verbose "Existing certificate meets criteria. Exporting."
}
Import-Module "C:\ClusterStorage\disk1\sdn\sdnexpress\scripts\SdnExpressModule.psm1"
New-SdnExpressHostCertificate

write-verbose "Setting cert permissions."
$targetCertPrivKey = $Cert.PrivateKey
$privKeyCertFile = Get-Item -path "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\*" | where-object {$_.Name -eq $targetCertPrivKey.CspKeyContainerInfo.UniqueKeyContainerName}
$privKeyAcl = Get-Acl $privKeyCertFile
$permission = "NT AUTHORITY\NETWORK SERVICE","Read","Allow"
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission
$privKeyAcl.AddAccessRule($accessRule) | out-null
Set-Acl $privKeyCertFile.FullName $privKeyAcl | out-null

write-verbose "Exporting certificate."
$TempFile = New-TemporaryFile
Remove-Item $TempFile.FullName -Force | out-null
Export-Certificate -Type CERT -FilePath $TempFile.FullName -cert $cert | out-null

$CertData = Get-Content $TempFile.FullName -Encoding Byte
Remove-Item $TempFile.FullName -Force | out-null

write-output $CertData
} | parse-remoteoutput
} catch {
write-logerror -OperationId $operationId -Source $MyInvocation.MyCommand.Name -ErrorCode $Errors["INVALIDKEYUSAGE"].Code -LogMessage $_.Exception.Message #No errormessage because SDN Express generates error
Expand Down Expand Up @@ -3012,6 +2977,9 @@ function New-SDNExpressVM
$dnssection = ""

foreach ($nic in $Nics) {

write-host "NIC: $nic"

$vmMacAddress = invoke-command -ComputerName $ComputerName @CredentialParam -ScriptBlock {
param(
[String] $VMName,
Expand All @@ -3025,6 +2993,9 @@ function New-SDNExpressVM
write-output ($vnic.macaddress)
} -ArgumentList $VMName, $Nic.Name | Parse-RemoteOutput

write-sdnexpresslog "Done nic processing"
write-sdnexpresslog "MAC: $vmMacAddress"

$MacAddress = [regex]::matches($vmMacAddress.ToUpper().Replace(":", "").Replace("-", ""), '..').groups.value -join "-"

write-verbose "Formatted Mac Address is: $macaddress"
Expand Down Expand Up @@ -3494,6 +3465,52 @@ function Test-SDNExpressHealth
write-sdnexpresslog "$($gateway.ResourceId) status: $($gateway.properties.State), $($gateway.properties.HealthState)"
}
}
function New-SdnExpressHostCertificate
{
param()

function private:write-verbose { param([String] $Message) write-output "[V]"; write-output $Message}
function private:write-output { param([PSObject[]] $InputObject) write-output "$($InputObject.count)"; write-output $InputObject}

$NodeFQDN = (get-ciminstance win32_computersystem).DNSHostName+"."+(get-ciminstance win32_computersystem).Domain

$cert = get-childitem "cert:\localmachine\my" | where-object {$_.Subject.ToUpper() -eq "CN=$NodeFQDN".ToUpper()}
if ($Cert -eq $Null) {
write-verbose "Creating new host certificate."
$Cert = New-SelfSignedCertificate -Type Custom -KeySpec KeyExchange -Subject "CN=$NodeFQDN" -KeyExportPolicy Exportable -HashAlgorithm sha256 -KeyLength 2048 -CertStoreLocation "Cert:\LocalMachine\My" -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1,1.3.6.1.5.5.7.3.2")
} else {
write-verbose "Found existing host certficate."
$HasServerEku = ($cert.EnhancedKeyUsageList | where-object {$_.ObjectId -eq "1.3.6.1.5.5.7.3.1"}) -ne $null
$HasClientEku = ($cert.EnhancedKeyUsageList | where-object {$_.ObjectId -eq "1.3.6.1.5.5.7.3.2"}) -ne $null

if (!$HasServerEku) {
throw "Host cert exists on $(hostname) but is missing the EnhancedKeyUsage for Server Authentication."
}
if (!$HasClientEku) {
throw "Host cert exists but $(hostname) is missing the EnhancedKeyUsage for Client Authentication."
}
write-verbose "Existing certificate meets criteria. Exporting."
}

write-verbose "Setting cert permissions."
$targetCertPrivKey = $Cert.PrivateKey
$privKeyCertFile = Get-Item -path "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\*" | where-object {$_.Name -eq $targetCertPrivKey.CspKeyContainerInfo.UniqueKeyContainerName}
$privKeyAcl = Get-Acl $privKeyCertFile
$permission = "NT AUTHORITY\NETWORK SERVICE","Read","Allow"
$accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission
$privKeyAcl.AddAccessRule($accessRule) | out-null
Set-Acl $privKeyCertFile.FullName $privKeyAcl | out-null

write-verbose "Exporting certificate."
$TempFile = New-TemporaryFile
Remove-Item $TempFile.FullName -Force | out-null
Export-Certificate -Type CERT -FilePath $TempFile.FullName -cert $cert | out-null

$CertData = Get-Content $TempFile.FullName -Encoding Byte
Remove-Item $TempFile.FullName -Force | out-null

write-output $CertData
}

Export-ModuleMember -Function New-SDNExpressVM
Export-ModuleMember -Function New-SDNExpressNetworkController
Expand All @@ -3513,5 +3530,7 @@ Export-ModuleMember -Function Test-SDNExpressHealth
Export-ModuleMember -Function Enable-SDNExpressVMPort

Export-ModuleMember -Function WaitForComputerToBeReady
Export-ModuleMember -Function write-SDNExpressLog
Export-ModuleMember -Function Write-SDNExpressLog
Export-ModuleMember -Function Get-IPAddressInSubnet
Export-ModuleMember -Function Parse-RemoteOutput
Export-ModuleMember -Function New-SdnExpressHostCertificate
29 changes: 29 additions & 0 deletions SDNExpress/scripts/SDNExpressTest.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function New-ASLocalSupplementalPolicy
{
param
(
[string]
[Parameter(Mandatory=$true)]
$ScanPath,

[string]
[Parameter(Mandatory=$true)]
$PolicyGuid
)
Write-Verbose "Create supplemental policy for $ScanPath" -Verbose
if (Test-Path "$PSScriptRoot\policy.xml")
{
Get-Item "$PSScriptRoot\policy.xml" | Remove-Item -Recurse
}
New-CIPolicy -MultiplePolicyFormat -ScanPath $ScanPath -UserPEs -FilePath "$PSScriptRoot\policy.xml" -Level Publisher -Fallback Hash
Set-CIPolicyIdInfo -FilePath "$PSScriptRoot\policy.xml" -SupplementsBasePolicyID '{A6368F66-E2C9-4AA2-AB79-8743F6597683}'
$policyContent = Get-Content "$PSScriptRoot\policy.xml"
$policyXml = [xml]$policyContent
$policyContent -Replace $policyXml.SiPolicy.PolicyID,$PolicyGuid | Out-File "$PSScriptRoot\policy.xml" -encoding "UTF8"
ConvertFrom-CIPolicy -XmlFilePath "$PSScriptRoot\policy.xml" -BinaryFilePath "$PSScriptRoot\$PolicyGuid.cip" | Out-Null
Write-Verbose -Verbose "Generate supplemental policy $PolicyGuid"
Copy-Item -Path "$PSScriptRoot\$PolicyGuid.cip" -Destination "$env:SystemRoot\System32\CodeIntegrity\CiPolicies\Active"
}

Export-ModuleMember -Function New-ASLocalSupplementalPolicy
#New-ASLocalSupplementalPolicy -ScanPath "C:\Windows\System32" -PolicyGuid '{9A438E45-7865-4848-8AA1-F1D6D0A1BDA8}'