Thursday, May 21, 2020

Applocker Rules for Tanium

I had a client wanting to create AppLocker whitelisting rules in Tanium.  I created this little script that can be run on the endpoints (use Tanium or SCCM to easily get it to run there) and then the results can be used to create rules in Tanium.

This script will output two files; ApplockerPolicy.xml which could be imported directly into Tanium though I recommend against it and PublisherInfo.csv which can be used to manually create the rules.

The methodology is to run the script on most/all of the endpoints, merge all of the PublisherInfo.csv files together (concatenate) into one long file.  Open that long file in Excel and remove duplicates.  Then you have your list of publishers, applications, and files to use in Tanium.

Here's the script:

$ExePath = "C:"
$OutPath = $env:USERPROFILE + "\Documents\ApplockerTesting"
$PolicyFile = "$OutPath\ApplockerPolicy.xml"
$PublisherInfoFile = "$OutPath\PublisherInfo.csv"

CLS
Get-AppLockerFileInformation -Directory $ExePath -Recurse -FileType Dll,EXE | New-AppLockerPolicy -RuleType Publisher,Path -User Everyone -RuleNamePrefix AppLocker -xml | Out-File -FilePath $PolicyFile -Force #create the policy file

[XML]$AppDetails = Get-Content $PolicyFile
$OutString = "Publisher Name,Product Name,Binary Name"
$OutString | Out-File -filepath $PublisherInfoFile -Force
foreach($AppDetail in $AppDetails.AppLockerPolicy.RuleCollection.FilePublisherRule.Conditions){
    $OutString = ('"' + ($AppDetail.FilePublisherCondition).PublisherName) + '","' + (($AppDetail.FilePublisherCondition).ProductName) + '","' + (($AppDetail.FilePublisherCondition).BinaryName) + '"'
    $OutString | Out-File -filepath $PublisherInfoFile -Append
}
If you really do want to import the ApplockerPolicy.xml created from that script then you might want to use this script to make the names into something more manageable.  The names given by the Get-AppLockerFileInformation command are really cumbersome.

Here's a script to reset the names:

$DocsPath = $env:USERPROFILE + "\Documents\ApplockerTesting"
$PolicyFile = "$DocsPath\PolicyFile.xml"

[XML]$AppDetails = Get-Content $PolicyFile


foreach($AppDetail in $AppDetails.AppLockerPolicy.RuleCollection.FilePublisherRule){
$PublishName,$Garbage = (($AppDetail.Conditions.FilePublisherCondition.PublisherName).Replace("O=","")).split(",",2)
$ProdName = $AppDetail.Conditions.FilePublisherCondition.ProductName
$BinaryName = $AppDetail.Conditions.FilePublisherCondition.BinaryName


$RuleName = $PublishName + " :-: " + $ProdName + " :-: " + $BinaryName
$AppDetail.Name = $RuleName
Write-Output $RuleName
$AppDetails.Save($PolicyFile)
}

Enjoy!

Thursday, December 5, 2019

Check/Set/Change/Clear HP BIOS Password with Powershell

# Check if password is set
Get-WmiObject -Namespace root/hp/InstrumentedBIOS -Class HP_BIOSSetting | Where-Object Name -eq "Setup Password").IsSet


# Set password
(Get-WmiObject -Namespace root/hp/InstrumentedBIOS -Class HP_BIOSSettingInterface).SetBIOSSetting("Setup Password","<utf-16/>" + "NewPassword","<utf-16/>")


# Change password
(Get-WmiObject -Namespace root/hp/InstrumentedBIOS -Class HP_BIOSSettingInterface).SetBIOSSetting("Setup Password","<utf-16/>" + "NewPassword","<utf-16/>" + "OldPassword")


# Clear password
(Get-WmiObject -Namespace root/hp/InstrumentedBIOS -Class HP_BIOSSettingInterface).SetBIOSSetting("Setup Password","<utf-16/>","<utf-16/>" + "OldPassword")

CI to Check HP BIOS settings

# Check-BIOSSetting.ps1
# by Mark Randol - randoltech.blogspot.com
# Checks the setting for the BIOS item in $BIOSItem
# Against the desired state in $DesiredValue
# If good returns the exact text in $DesiredValue
# If bad returns the string from BIOS
# If item is not found retruns $BIOSItem not found in BIOS settings.
# If script properly runs but is indeterminent then returns Error (should never happen)


$BIOSItem = "Boot Mode"
$DesiredValue = "*UEFI Native (Without CSM)"
$OutputString = "Error"
$ItemValue = (Get-WmiObject -Namespace root\HP\InstrumentedBIOS -Class HP_BIOSEnumeration | Where-Object Name -eq $BIOSItem).Value
if ($ItemValue) {
    $CheckString = (($DesiredValue.Replace("*","\*")).Replace("(","\(")).Replace(")","\)")
    if ($ItemValue -match $CheckString) {
        $OutputString = $DesiredValue
    }
    else {
        $OutputString = $ItemValue
    }
}
else {
    $OutputString = "$BIOSItem not found in BIOS settings."
}
Write-Output $OutputString



----------------------------------

Remediation Script:

(Get-WmiObject -Namespace root\HP\InstrumentedBIOS -Class HP_BIOSSettingInterface).SetBIOSSetting("TPM Device","Available","<utf-16/>" + "YourBIOSPasswordHere")

Thursday, November 21, 2019

Extracting Microsoft Surface Drivers

For the Surface Pro 6 I ended up downloading four .msi files and needed to extract them to get the drivers for import into SCCM.  I wrote this little PowerShell script to iterate through all four and extract them for me complete with logs in case anything went wrong.  Figured I would post it here in case anyone else finds it useful.


#Extract-MSIFiles.PS1
#Creates folders for each .msi and extracts contents into the folders
#By Mark Randol - randoltech.blogspot.com

$BasePath = "C:\Users\me\Downloads\Drivers\Surface Pro 6 1796 Commercial"

Start-Transcript -Path "$BasePath\Extract-MSIFiles.log" -Force

$SearchPath = $BasePath + "\*"
$MSIFiles = Get-ChildItem $SearchPath -Include *.msi
foreach ($File in $MSIFiles) {
    $FileName = $File.Name
    New-Item -Path "$BasePath" -Name $File.BaseName -ItemType "Directory"
    $ExtractFolder = $BasePath + "\" + $File.BaseName
    $ArguementString = "/a ""$BasePath" + "\" + "$Filename"" targetdir=""$ExtractFolder"" /l*v ""$BasePath\$FileName.log"" /qn"
    Start-Process -FilePath "msiexec.exe" -ArgumentList $ArguementString
    Wait-Process -Name msiexec -Timeout 90
}

Stop-Transcript



-Enjoy

Wednesday, November 6, 2019

Detection Method for an APPX package

None of the standard SCCM application detection methods work for APPX packages.  For an APPX package use "Use a custom script to detect the presence of this deployment type" and this command line as the script (modify for the package name and version number that you need obviously):

if ([version]((Get-AppxPackage *AppUp.ThunderboltControlCenter*).Version) -ge ([version]("1.41.648.5"))) { write-output $true }

Enjoy!

Tuesday, October 1, 2019

A little script to back up your BitLocker keys to Active Directory

If you are using Azure AD then change Backup-BitLockerKeyProtector to BackupToAAD-BitLockerKeyProtector

# Backup-BitlockerKeys.ps1
# by Mark Randol
# randoltech.blogspot.com
# This script iterates through all of your possibly encryptable drives
# and if they are encrypted, backs up the keys to Active Directory.

$PossibleDrives = Get-BitLockerVolume
foreach ($Drive in $PossibleDrives)
{
    $DriveLetter = $Drive.MountPoint
    $Protectors = ((Get-BitLockerVolume -MountPoint $DriveLetter).KeyProtector)
    foreach ($Protectors in $Protectors) {
        $ProtectorID = $Protector.KeyProtectorId
        $ProtectorType = $Protector.KeyProtectorType
        if ($ProtectorType -eq "RecoveryPassword") {
            Backup-BitLockerKeyProtector -MountPoint $DriveLetter -KeyProtectorId $ProtectorID -Verbose
        }
    }
}

Wednesday, September 11, 2019

ThunderBolt Security Configuration Item for SCCM

This comes out of a need to secure ThunderBolt PCIe against DMA attacks while still allowing users (rather than just administrators) to approve attached devices.  This attack is very serious as it can done on a machine that is in sleep or hibernate.  As we know most laptop users never turn their computers off, they just close the lid.  The computer goes to sleep and everything it was doing gets stored in memory.  DMA = Direct Memory Access, so someone comes along, plugs in a malicious device and grabs everything stored in memory without even opening the lid of the computer.

Mitigation is two parts.  One part is BIOS configuration.  By default any modern ThunderBolt enabled computer will come with the BIOS set to require "User Approval" of any device that gets attached.  The problem is (in the operating system) that approval require that the user actually be an administrator not just any user.  That is not a usable solution in an enterprise environment.  It also requires that the device(s) be approved every single time they are used.  So, let's say you have a Thunderbolt dock... an administrator has to come and approve it every time you dock your laptop.  That's just not workable.

So, we configure that BIOS to a newer standard, Secure Connect.  That allows the device to only require approval the first time it is used.  Unfortunately that approval still needs to be an administrator.

Finally we are to the point of my post.  Here are two scripts to create a configuration item to detect existence of ThunderBolt and remediate the registry so that normal users can approve device connections.

A tech said to me "I don't see how this is any different than setting the BIOS to No Security".  Well, as I explained to him, you must understand how the DMA attack works in this instance.  The attack happens by simply attaching a malicious device (USB Key, SD Card, whatever) to the machine and the machine accepts its DMA request.  This can happen even while the machine is in Sleep mode (no user interface).  So, the difference between this and no security is that a user must actually be logged in and active to approve the connection.  I can't just walk up to your machine while you are at lunch, plug in a USB key, and take everything that your OS has in memory away with me.  I would have to have a valid login to approve the connection.  The attack is a way around drive encryption.  Having a valid logon is a way around drive encryption so this method makes your machine as secure as a machine that does not have ThunderBolt at all, meaning that nobody can run this particular DMA without a valid logon.  Once someone has a valid logon, you have other mitigation that you need to have in place but that's a story for another time.

The first script, detection:
This script will detect the existence of the ThunderBolt registry branch.  If it doesn't exist then your machine doesn't have ThunderBolt (or at least doesn't have drivers for it which amounts to the same thing, you are not vulnerable to the DMA attack) so it is compliant.  If your machine does have the branch then it checks the AccessRule item to ensure that it is set to 1.  By default this item will either not exist (IBM Lenovo) or be set to 0 (HP).

Create a new CI of type Script.  I named mine "Win10 Core - ThunderBolt PCIe Security" to add it to my Win10 Core baseline.
   The Setting Type is Script.
   The Data Type is String.
   Here is the Discovery Script:

#Created by Mark Randol - randoltech.blogspot.com
#This script detects existence of teh Thunderbolt Service registry branch
#and the setting of the "Approval Level" item within it
#Non-existence of the branch = compliant
#Non-existence ApprovalLevel within the branch = noncompliant
#ApprovalLevel 1 = compliant
#Any other value for ApprovalLevel = noncompliant
 
if (Test-Path -Path "HKLM:SYSTEM\CurrentControlSet\Services\ThunderboltService\TbtServiceSettings") {
$OutString = (Get-ItemProperty "HKLM:SYSTEM\CurrentControlSet\Services\ThunderboltService\TbtServiceSettings").ApprovalLevel
}
else {
$OutString = "1"
}
Write-Output $OutString
Return $OutString

Here is the Remediation Script:

# Change Thundebolt security approval level to allow users
# to accept Thundebolt equpiment without being local admin
# Originally created by Jens-Kristian Myklebust <jensmyklebust@outlook.com>
# Modified to work as an SCCM CI by Mark Randol - randoltech.blogspot.com

$logfile = "$env:windir\ccm\logs\Install_Fix-ThunderboltRegistry.log"
Start-Transcript -Path $logfile -force #start logging

$RegistryKey = "SYSTEM\CurrentControlSet\Services\ThunderboltService\TbtServiceSettings" #Registry key to modify
$RegistryPath = "HKLM:\$RegistryKey" #Full path to the registry key
$ServiceName = "AdobeARMservice" #"ThunderboltService"

#Set the registry Value
if ((Test-Path -Path $RegistryPath)){ #make sure we're on a machine that actually has the key
       
    $TheService = Get-Service -Name $ServiceName
    #Stop the Thunderbolt Service
    if (($TheService)) {
        $TheService | Stop-Service -Confirm:$false -Verbose
        $TheService.WaitForStatus('Stopped')
    }

    $ACLinfo = Get-Acl "HKLM:\$RegistryKey" #Store original ACL info

    #Give "SYSTEM" user full access to registry key
        $RegKeyDotNETItem = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($RegistryKey,[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
        $DotNET_ACL = $RegKeyDotNETItem.GetAccessControl()
        $DotNET_AccessRule = New-Object System.Security.AccessControl.RegistryAccessRule ("System","FullControl","Allow") -Verbose
        $DotNET_ACL.SetAccessRule($DotNET_AccessRule)
        $DotNET_AccessRule = New-Object System.Security.AccessControl.RegistryAccessRule ($env:USERNAME,"FullControl","Allow") -Verbose
        $DotNET_ACL.SetAccessRule($DotNET_AccessRule)
        $RegKeyDotNETItem.SetAccessControl($DotNET_ACL)

    #check for existence of the property in the key
    #if the property doesn't exist, create it
    if (!((Get-ItemProperty $RegistryPath).ApprovalLevel)){
        New-ItemProperty -Path $RegistryPath -Name 'ApprovalLevel' -Value 1 -PropertyType DWORD -Force -Verbose
    }
    #if the property does exist, change it to the correct value
    else {
        Set-ItemProperty -Path $RegistryPath -Name 'ApprovalLevel' -Value 1 -Verbose
    }

    #Put the security back on the registry
    $RegKeyDotNETItem.SetAccessControl($ACLinfo)

    #Restart service
    if (($TheService)) {
        $TheService | Start-Service -Confirm:$false -Verbose
        $TheService.WaitForStatus('Running')
    }
#>
}
Stop-Transcript #stop logging

Create a compliance rule, I named mine "ApprovalLevel" as that is the registry item that we are dealing with.  Here are the settings for it:
Value = 1
Check the checkbox "Run the specified remediation script when this setting is noncompliant"
Check the checkbox "Report noncompliance if the setting instance is not found"

From there, add your new CI to a baseline, deploy the baseline at your (suspected) Thunderbolt enabled machines and it should set the setting for you.

With BIOS set to SecureConnect and this registry entry your users should be able to approve devices to connect to their computer and will only need to do it the first time similar to pairing a Bluetooth device.

- Enjoy