How to fix cve-2021-43890

Microsoft recently published the following vulnerability cve-2021-43890 that is currently exploited by malware like Emotet/Trickbot/Bazaloader.

If your computer doesn’t have access to the store, it may not be that straightforward to install the fixed universal app to all users of a Windows 10 computer.

If the computer is not vulnerable, it’ll tell you the above message.

If it installed the required patched universal app, it’ll say “Successfully provisionned Microsoft.DesktopAppInstaller”.

You can run the code in a scheduled tasked running under the System account. Any user that has an interactive session opened will get the new Appx in his account.

If there’s a local user profile but the user is not logged on, it’ll automatically get the updated appx after an interactive logon.

#Requires -RunAsAdministrator
[CmdletBinding()]
Param()
Begin {}
Process {
if ([version]'1.16.13405.0' -gt [version](Get-AppxPackage Name 'Microsoft.DesktopAppInstaller' ErrorAction SilentlyContinue).Version) {
$zip = (Join-Path Path $env:TEMP ChildPath 'Microsoft.DesktopAppInstaller_1.16.13405.0_8wekyb3d8bbwe.zip')
$zipFolder = "$($zip -replace '\.zip','')"
if (-not(Test-Path Path $zip)) {
$HT = @{
Uri = 'https://download.microsoft.com/download/6/6/8/6680c5b1-3fbe-4b70-8189-90ea08609563/Microsoft.DesktopAppInstaller_1.16.13405.0_8wekyb3d8bbwe.zip'
UseBasicParsing = $true
ErrorAction = 'Stop'
OutFile = $zip
}
try {
Invoke-WebRequest @HT
} catch {
Write-Warning Message "Failed to download zip because $($_.Exception.Message)"
}
}
if (Test-Path Path $zip) {
if ((Get-FileHash Path $zip).Hash -eq 'e79cea914ba04b953cdeab38489b3190fcc88e566a43696aaefc0eddba1af6ab' ) {
try {
Expand-Archive Path $zip DestinationPath (Split-Path $zipFolder Parent) Force ErrorAction Stop
} catch {
Write-Warning Message "Failed to unzip because $($_.Exception.Message)"
}
if ('Valid' -in (Get-ChildItem Path "$($zipFolder)\*" Include * Recurse Exclude '*.xml' | Get-AuthenticodeSignature |
Select-Object ExpandProperty Status | Sort-Object Unique)
) {
$HT = @{
Online = $true
PackagePath = Join-Path Path $zipFolder ChildPath 'Microsoft.DesktopAppInstaller_1.16.13405.0_8wekyb3d8bbwe.msixbundle'
SkipLicense = $true
ErrorAction = 'Stop'
}
try {
$r = Add-AppxProvisionedPackage @HT
if ($r.Online) {
Write-Verbose 'Successfully provisionned Microsoft.DesktopAppInstaller' Verbose
}
} catch {
Write-Warning Message "Failed to install Appx because $($_.Exception.Message)"
}
}
} else {
Write-Warning Message "Downloaded zip file thumbprint (SHA256) doesn't match"
}
} else {
Write-Warning Message "Zip file $($zip) not found"
}
} else {
Write-Verbose Message 'Current Microsoft.DesktopAppInstaller appx version is not vulnerable' Verbose
}
}
End {}

Update of Windows Defender Attack Surface Reduction (ASR) Rules module

Following the announcement of a new rule in this blog post about blocking vulnerable drivers, I’ve added it to the module 🙂

Get-ASRRuleConfig | Select Name,Action | ft -AutoSize
Get-ASRRuleData | ogv -PassThru | fl *
Get-ASRRuleData -Name 'Block abuse of exploited vulnerable signed drivers' | Get-ASRRuleConfig
Get-ASRRuleData -Name 'Block abuse of exploited vulnerable signed drivers' | Set-ASRRuleConfig -Mode AuditMode -WhatIf 
Get-ASRRuleData -Name 'Block abuse of exploited vulnerable signed drivers' | Set-ASRRuleConfig -Mode AuditMode -Verbose
Get-ASRRuleData -Name 'Block abuse of exploited vulnerable signed drivers' | Get-ASRRuleConfig     

That’all folks, have fun 😎

Install Windows 11 in a Hyper-V VM

Context

I wanted to test the new Windows 11 released on Hyper-V

The readiness script reported that both storage and TPM are missing 😥

Here’s what I did to get a PASS on all the hardware prerequisites on the VM:

~\Downloads\HardwareReadiness.ps1|Out-String | ConvertFrom-Json

Solution

$VMName = 'MyVMName'

# 1. Add Secure boot
Get-VM -Name $VMName | 
Set-VMFirmware -EnableSecureBoot:On -SecureBootTemplate 'MicrosoftWindows'

# 2. Add a TPM
Set-VMKeyProtector -VMName $VMName -NewLocalKeyProtector
Enable-VMTPM -VMName $VMName

# 3. Resize VHDX
Get-VMHardDiskDrive -VMName $VMName |
Select -First 1 -ExpandProperty Path | Get-VHD | 
Resize-VHD -SizeBytes 65GB

Inside the VM, I had to extend the C: drive

# Remove the offending 5th partition
$null = Remove-Partition -DiskNumber 0 -PartitionNumber 5 -Confirm:$false

# Resize C: to the maximum
Resize-Partition -DiskNumber 0 -PartitionNumber 4 -Size (Get-PartitionSupportedSize -DiskNumber 0 -PartitionNumber 4).SizeMax

A return code of 0 means the VM is Windows 11 capable 😎

About CVE-2021-40444

Microsoft has recently published a security bulletin about the Microsoft MSHTML Remote Code Execution Vulnerability https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-40444
Others urge anybody to apply the only workaround against this 0day because it has been publicly disclosed.

How would you do that by Group Policy on a domain joined device.

#Requires -RunasAdministrator
#Requires -Modules ActiveDirectory,GroupPolicy
[CmdletBinding()]
Param()
Begin{}
Process {
# Make sure we can reach the PDC
$PDC = (Get-ADDomainController Service 1 Discover ErrorAction SilentlyContinue).Hostname
if ($PDC) {
# Get the domain name
$DomainName = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
# Create the GPO
try {
$GPO = New-GPO Name 'Workaround for CVE-2021-40444' Domain "$($DomainName)" ErrorAction Stop
} catch {
Write-Warning Message "Failed to create GPO because $($_.Exception.Message)"
}
if ($GPO) {
# Don't need user settings
$GPO.GpoStatus = [Microsoft.GroupPolicy.GpoStatus]::UserSettingsDisabled
$HT = @{ GUID = ($GPO).Id ; ErrorAction = 'Stop' }
# Zones
0..3 |
ForEach-Object {
$ZoneId = $_
1, # URLACTION_DOWNLOAD_SIGNED_ACTIVEX (0x1001)
4 | # URLACTION_DOWNLOAD_UNSIGNED_ACTIVEX (0x1004)
ForEach-Object {
$Value = $_
$reg = @{
Key = 'HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\{0}' -f $ZoneId
ValueName = '100{0}' -f $Value
Type = 'DWORD'
Value = 3
}
try {
Set-GPRegistryValue @HT @reg
} catch {
Write-Warning Message "Faile to set GPO setting because $($_.Exception.Message)"
}
}
}
}
}
}
End{}

If you look in the GPMC snap-in it looks like this:

Next steps are:
– you may need to add a filter if you want
– you may want to change the permissions, delegation…if required in your environement
– you need to link it on a OU or at another level so that the GPO actually applies to vulnerable computers
– wait for Microsoft. They will release a patch as soon as it’s ready

Direct Access tunnel stuck

When you’ve Direct Access configured on Windows 10 using IPHTTPS, your Tunnel adapter Microsoft IP-HTTPS Platform Interface starts to get an IPv6 address when the network stack connection state changes and all pre-requisites are met.

I had actually a very strange issue where my tunnel still had an Ipv6 no matter what the connection state changes. I mean that I could still see its Ipv6 set even after a reboot 😦

This was totally unexpected and I didn’t know what to do to force the computer to release this Ipv6, start over and take into account normal connection state changes.

Gpupdate.exe isn’t available because the tunnel was down, of course.

I used the following process to recover the normal functioning state of the tunnel.

I found the inspiration on this blog post. It’s 10 years old and applied to Windows 7. In my case, I have a Windows 10 and I nonetheless decided to give it a try. Thanks to Ronny and anyone else involved in providing support and help to fix this issue.

I added HKLM\Software\Policies\Microsoft\Windows NT\DNSClient\EnableDAForAllNetworks set to 0x2 and did a restart.
After the restart, the tunnel was recovered. It started to act normally and was mounted. Corporate resources were unavailable but that was expected.

I set it back to 0 (didn’t delete it) and did a restart. The tunnel mounted normally and corporate resources were available.

Happy Days 😎

How to create a VSS snapshot

I recently needed to quickly create a volume shadow copy (VSS) snapshot on Windows 10.
Using Get-CimInstance -ClassName Win32_ShadowCopy returned nothing.
Let’s inspect what methods are available:

Get-CimClass -ClassName Win32_ShadowCopy|
Select -ExpandProperty CimClassMethods

Can we get more info about the parameters of the Create method?

Ok, it requires an Id as input and will return a ShadowID.

The Create method is documented here. In my case, I didn’t use a Context parameter on Windows 10 and it’s not complaining when it’s missing.

Invoke-CimMethod -ClassName Win32_ShadowCopy `
-MethodName Create -Arguments @{Volume='C:\' }

The return value equals 0 means it’s a success 🙂

Erratum on news and interests on the Windows taskbar

I’ve published a wrong information about the registry key in the following blog post. The path is incorrect and missing a ‘Windows’. Sorry, my bad 😦

Here’s how to remove the wrong path

# pick the appropriate GPO
$gpo = Get-GPO -All | Out-GridView -OutputMode Single

if ($gpo) { 
Remove-GPRegistryValue -Guid $gpo.Id -Key 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Feeds' -ValueName 'EnableFeeds' 
}

Here’s how to add the correct path 🙂

# pick the appropriate GPO
$gpo = Get-GPO -All | Out-GridView -OutputMode Single

if ($gpo) { 
Set-GPRegistryValue -Guid $gpo.Id -Key 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Windows Feeds' -ValueName 'EnableFeeds' -Type DWord -Value 0
}

Find the Parent path of an AD object

I recently needed to find the parent location of a computer, it’s parent distinguishedName. I wanted a function that would:
– work with a broader scope of AD objects, like users, OUs,…
– support piping objects from regular ActiveDirectory module or from itself
Here’s what I wanted to achieve visually

# Pipe an ADUser object
Get-ADUser 'Skywalker' | Get-ADObjectParentPath

# Pipe a DN string (you'd get the 'Users' OU)
'CN=Luc Skywalker,OU=Users,OU=Prod,DC=Star,DC=Wars,DC=com' | Get-ADObjectParentPath

# Do it twice, (you'd get the 'Prod' OU)
'CN=Luc Skywalker,OU=Users,OU=Prod,DC=Star,DC=Wars,DC=com' |
Get-ADObjectParentPath | Get-ADObjectParentPath


Here’s what I quickly wrote to meet my needs.

Function Get-ADObjectParentPath {
<#
.SYNOPSIS
Get the parent DN location of an AD object.
.DESCRIPTION
Get the parent DN location of an AD object.
.PARAMETER DistinguishedName
DistinghedNames objects passed as input (from AD cmdlets).
.PARAMETER DN
DistinghedNames strings passed as input
.EXAMPLE
Get-ADUser Skywalker | Get-ADObjectParentPath
.EXAMPLE
'CN=Luc Skywalker,OU=Users,OU=Prod,DC=Star,DC=Wars,DC=com' | Get-ADObjectParentPath
#>
[CmdletBinding(DefaultParameterSetName = 'String')]
Param(
[Parameter(ParameterSetName = 'Obj', Mandatory,ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
$DistinguishedName,
[Parameter(ParameterSetName = 'String', Mandatory,ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string[]]$DN
)
Begin {
if (-not(Test-Path Path 'AD:\' PathType Container)) {
Write-Warning Message 'Failed to find the AD drive, aborting'
break
}
}
Process {
if ($DistinguishedName) {
$DistinguishedName |
ForEach-Object Process {
$parent = ((Get-Item "AD:\$($_)" ErrorAction SilentlyContinue).PSParentPath | Split-Path NoQualifier ) -replace '//RootDSE/',''
if ($parent) {
$parent
}
}
}
if ($DN ) {
$DN |
ForEach-Object Process {
if (Test-Path Path "AD:\$($_)" ErrorAction SilentlyContinue) {
$parent = ((Get-Item "AD:\$($_)" ErrorAction SilentlyContinue).PSParentPath | Split-Path NoQualifier ) -replace '//RootDSE/',''
if ($parent) {
$parent
}
} else {
Write-Warning Message "Path AD:\$($_) not found"
}
}
}
}
End {}
}

Quick post: Remove a permission on a GPO

There’s no cmdlet named Remove-GPPermission. There’s only Get- GPPermission and Set- GPPermission. How do I remove a GPO permission?

# Choose a single GPO
$gpo = Get-GPO -All | Out-GridView -OutputMode Single
# Choose a single target
$target = Get-GPPermission -Guid $gpo.Id -All | Out-GridView -OutputMode Single
# Remove target from that GPO
Set-GPPermission -Guid $gpo.Id -PermissionLevel None -Replace -TargetName "$($target.Trustee.Name)" -TargetType "$($target.Trustee.SidType)"

The answer is to replace the existing permission with a level of “None”. This is equivalent of a removal.