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{}
view raw CVE-2021-40444.ps1 hosted with ❤ by GitHub

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.

About news and interests on the Windows taskbar

Context

Microsoft is about to add a new feature “News and interests on the taskbar” to Windows 10.

“Devices running Windows 10, version 1909 (and later) who have installed the May 2021 Windows monthly update (or later) will be included in this phased rollout.”

While it may be welcome in the consumer space, it could be the opposite in a corporate environment.

Problem

They did not publish up-to-date ADMX templates and don’t tell you in their blog post what’s required in the registry to achieve the same as in the Endpoint Manager agent (a.k.a Intune), especially if you just rely on good old robust Group Policies for your fully managed devices.

Solution

Fortunately Michael Niehaus published the following two posts on this subject and addresses the above shortcoming.

  1. https://oofhours.com/2021/02/07/turn-off-the-insider-news-interests-page/
  2. https://oofhours.com/2021/04/22/turn-off-news-interests-page-via-policy/

That said, you don’t really need to grab the ADMX files from an Insider build or wait for Microsoft to publish the required ADMX templates in any relevant Windows build.

Knowing the registry key and values is what matters.

If you’ve the GroupPolicy module and an existing GPO, you can already populate the registry with these 2 lines of code


# 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 Feeds' -ValueName 'EnableFeeds' -Type DWord -Value 0

}

Ready for the next brilliant move 😎

Last but not least, if you want to grab the policy templates, Glenn Turner indicated that you can get Feeds.admx and Feeds.adml files by installing the LCU preview KB5001396.

Quick post: Remove an alternate data stream (ADS)

  • Context

I’ve been downloading updates (.msu) files from the Windows Update catalog
As an example, for KB5001330 I go to https://www.catalog.update.microsoft.com/Search.aspx?q=5001330 and click Download

dir ~/downloads/other/*.msu |
gi -Stream * |
Select Stream,Length

  • Problem

I can remove the Zone.Identifier alternate data stream (ADS) using the built-in Unblock-File cmdlet.

dir ~/downloads/other/*.msu |
Unblock-File -Verbose

dir ~/downloads/other/*.msu |
gi -Stream *|
Select Stream,Length

But, I doesn’t remove the SmartScreen ADS.

  • Solution

Here’s how to remove the SmartScreen alternate data stream (ADS):

dir ~/downloads/other/*.msu |
gi -Stream 'SmartScreen' -EA 0|
Foreach-Object {
Remove-Item -Path $_.FileName -Stream 'SmartScreen'
}

Windows Defender Attack Surface Reduction (ASR) Rules module

I’m pleased to share with you a new #PowerShell module about Windows Defender Attack Surface Reduction (ASR) Rules 🚀

After seeing what Palantir did about their ASR telemetry and the content of the following repository, I thought that we need a more “PowerShell-friendly” way to view and set Windows Defender Attack Surface Reduction (ASR) rules.

It seems that I’m not the first person to have this idea and you can find an another implementation of this idea on the PowerShell gallery here.

If you don’t know anything about Windows Defender Attack Surface Reduction, I’d recommend that you watch this 6 minutes long video Susan Bradley made

My approach is slightly different than the 2 other PowerShell code implementations/repositories I mentioned above. I don’t provide any graphical interface (GUI), although you can for sure use the built-in Out-GridView cmdlet to send the output and inspect it in a GUI. I propose to have 3 functions that you can use to bind properly using the pipeline and made an effort to have all the parameters data being discoverable using the TAB key.

Let’s see some practical examples in a video:

I’d like to point out another useful resource to test the defense measures and configuration.

What else?
If you encounter an issue with this module, you’re welcome to open an issue in the github repo with this link.

Last but not least. Let’s say you’ve configured some ASR rules using GPO but not all of them. The Get-ASRRuleConfig function is able to display the effective rules that apply (GPO or local and if GPO, GPO wins over local). But the Set-ASRRuleConfig is only able to set the local rules. It cannot touch GPO rules. If you use it to set a rule that is already managed by GPO, it will work on the local value only. If you then use back Get-ASRRuleConfig, you get the results of what’s effective. Remember GPO wins.

How do I get started?

Find-Module -Name ASRRules -Repository PSGallery
Save-Module -Name ASRRules -Repository PSGallery -Path ~/Downloads

Import-Module ~/Downloads/ASRRules/1.0.0/ASRRules.psd1 -Force -Verbose

# if in PS 7.x and there's a complaint about the required module,
Import-Module -Name ConfigDefender -Force
Import-Module ~/Downloads/ASRRules/1.0.0/ASRRules.psd1 -Force -Verbose

Enjoy 😎