About the DellBIOSProvider module and ConstrainedLanguage mode

  • Context

I’ve just started working with the DellBIOSProvider module available on the PowerShell Gallery and had to see how to integrate it smoothly in the environment so that it’s compatible with the Constrained language mode.

  • Issues

If I do:

Import-Module -name DellBIOSProvider -Force -Verbose

What could go wrong? 🙄
Well, it depends on what you do. If you go down to the Applocker rules path, it depends on the rules, their type, on what’s missing.
I’ve listed below a few common road blocks you may encounter:

  • psd1 or psm1 has a dedicated rule trusting/allowing it while the other doesn’t:
  • there is/are rule(s) to allow both .psd1 and psm1, but when it loads the dll (listed in the .psd1 manifest file), it fails because there’s a missing rule:

Import-Module : Could not load file or assembly ‘file:///C:\Program
Files\WindowsPowerShell\Modules\DellBIOSProvider\2.6.0\DellBIOSProvider.dll’ or one of its dependencies. Operation is
not supported. (Exception from HRESULT: 0x80131515)

  • there is/are rule(s) to allow both .psd1 and psm1, but the .psm1 uses dot sourcing and tries to load single .ps1 file that don’t have an allow rule:
  • this is what happens when you’ve rule(s) allowing it to load and it’s a 100% success
  • Solution

It appears that there are 2 solutions.

The 1rst one and the longest is about declaring rules that will allow any file contained in the module. Let’s have a look at the content of the module with the following command:

Get-AppLockerFileInformation -Path 'C:\Program Files\WindowsPowerShell\Modules\DellBIOSProvider\2.6.0\*' | ogv -PassThru

We can see above that the dll, ps1, psd1, psm1 and cat files are all signed 🙂
Only the txt and pdf files are unsigned. These 2 files are not loaded so we don’t care.

At this step, we can choose either to add either:
– a single Applocker rule for the Path
or
– a single Applocker rule containing all the files’ hashes
or
– a single Applocker rule trusting the Publisher
O=DELL INC, L=ROUND ROCK, S=TEXAS, C=US
or
– a mix of files’ hashes and publisher based rules

I’ve chosen the latest option because it’s the most precise. I’ve listed the rules in this XML policy file.

The Applocker GUI will allow you to create rules for dll, .psd1 and psm1 files if you copy them with a .ps1 file extension 😎

Let’s see the 2nd solution and the shortest one:

Dell provided a signed catalog file. It contains all the files’ hashes. To trust it, I only have to copy it to its system location. There are various ways of doing this listed on this page.

copy 'C:\Program Files\WindowsPowerShell\Modules\DellBIOSProvider\2.6.0\DellBIOSProvider.cat' "c:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}"
Restart-Service CryptSvc -Force -Verbose

That’s all. It’s magic. You don’t need Applocker rules 😀

Group policies update/refresh without gpupdate.exe

  • Context

I was testing group policies, adding, removing them and using gpupdate.exe to apply changes. I messed with the Applocker gpo and set the PC in an unstable state.

I still had my PowerShell console opened but couldn’t use gpupdate.exe anymore. The Start menu wasn’t working anymore… 😦

Here’s what it looks like:

Usually, I’d just restart the computer and the transient state is cleared: either Applocker would work normally or would be disabled.

In this case, I couldn’t restart the computer because of Bitlocker. I was remote and the next time the laptop restarts it’d ask for a PIN. I couldn’t also suspend bitlocker for the next restart or simply disable it. Bad situation actually for Bitlocker, no UI, no cmdlet, no manage-bde.exe… (maybe I could have tried WMI/CIM).

  • Question: how would you refresh group policies when you cannot use gpupdate.exe
  • Solution:

I can still type some PowerShell in the opened console but bitlocker cmdlets don’t work.

It appears that there are 2 super hidden scheduled tasks responsible for refreshing group policies in the background.

Yes, super hidden because you cannot see them in the UI as an administrator even though you’ve enabled the “show hidden tasks” option:

Fortunately, the cmdlets of the ScheduledTasks module can interact with these super hidden tasks 🙂

Answer:

 Get-ScheduledTask -TaskPath '\Microsoft\Windows\GroupPolicy\' |
Where-Object { $_.Actions.Arguments -match 'computer' } |
Start-ScheduledTask
  • Conclusion

The above one-line code allowed me to run gpupdate.exe and saved me from having to restart the computer. Happy days 😎

Get CISA vulnerabilities report

There’s a new initiative from the US CyberSecurity & Infrastructure Security Agency.

They publish a list of known exploited vulnerabilities. Nice, isn’t it?

They publish a json version of the catalog. So I wanted a PowerShell function able to get the list of recently added vulnerabilities, the same way it’s presented in this news article from bleepingcomputer.com or this one.

Let me introduce

Get-Help Get-CISAVulnerabilitiesReport
Get-CISAVulnerabilitiesReport | Measure-Object
Get-CISAVulnerabilitiesReport -Last 3
Get-CISAVulnerabilitiesReport -StartDate (Get-Date).AddDays(-15) | ogv

Here’s the full code of the function, enjoy 🙂

Function Get-CISAVulnerabilitiesReport {
<#
.SYNOPSIS
Get known exploited vulnerabilities
.DESCRIPTION
Get the known exploited vulnerabilities catalog from CISA
.PARAMETER StartDate
Datetime object used to filter the catalog
.PARAMETER Last
Last number of entries in the catalog sorted by published date
.EXAMPLE
Get-CISAVulnerabilitiesReport
Get all the known exploited vulnerabilities from the catalog published by CISA
.EXAMPLE
Get-CISAVulnerabilitiesReport | Measure-Object
Get the count of all the known exploited vulnerabilities published in the catalog by CISA
.EXAMPLE
Get-CISAVulnerabilitiesReport -Last 3
Get the 3 most recent known exploited vulnerabilities from the catalog published by CISA
.EXAMPLE
Get-CISAVulnerabilitiesReport -StartDate (Get-Date).AddDays(-15)
Get the known exploited vulnerabilities from the catalog published by CISA over the last 15 days
#>
[CmdletBinding(DefaultParameterSetName='__AllParameterSets')]
Param(
[Parameter(ParameterSetName = 'ByDate')]
[datetime]$StartDate,
[Parameter(ParameterSetName = 'ByLast')]
[int32]$Last
)
Begin {}
Process {
$HT = @{
URI = 'https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json&#39;
ErrorAction = 'Stop'
UseBasicParsing = [switch]::Present
}
try {
$vuln = (Invoke-RestMethod @HT).vulnerabilities |
ForEach-Object -Process {
[PSCustomObject]@{
CVEId = $_.cveID
Vendor = $_.vendorProject
ProductName = $_.product
Name = $_.vulnerabilityName
StartDate = ([datetime]$_.dateAdded)
Description = $_.shortDescription
ActionRequired = $_.requiredAction
DueDate = ([datetime]$_.dueDate)
}
}
} catch {
Write-Warning -Message "Failed to get data from CISA because $($_.Exception.Message)"
}
if ($vuln) {
Switch ($PSCmdlet.ParameterSetName) {
'ByDate' {
$vuln | Where-Object { $_.StartDate -gt $StartDate }
break
}
'ByLast' {
$vuln | Sort-Object -Property StartDate -Descending | Select-Object -First $Last
break
}
default {
$vuln
}
}
}
}
End {}
}