VulnDetect Task Scripts - PowerShell & Certificates
The scripts used for running updates and doing certain maintenance tasks are signed using a certificate from DigiCert.
The certificate has the following properties:
Issued to: SecTeer ApS Valid from: Thursday, 6 October 2022 02.00.00 Valid to: Sunday, 5 October 2025 01.59.59 Thumbprint: 6dfcfab91dc7a9f2452b5602a022ef157a548428 Issuer: DigiCert, Inc.
The files we use can be found here (up-to-date as of 2nd May 2023):
The above scripts are released under the MIT License. While the code is carefully tailored to VulnDetect, a lot of the functions are based on other people's discussions on the Stack Exchange network and similar places. A great thank you to everybody who share their challenges and in particular those who contribute with awesome responses and useful code suggestions.
If you use the AllSigned ExecutionPolicy for PowerShell scripts, then you'd need to import the new certificate:
$cert = (Get-AuthenticodeSignature -FilePath functions.ps1).SignerCertificate Export-Certificate -Cert $cert -Filepath SecTeer-Task-Certificate.crt -Type Cert
And store it for trust purposes:
Import-Certificate -Filepath .\SecTeer-Task-Certificate.crt -CertStoreLocation Cert:\LocalMachine\TrustedPublisher\
Other security solutions may have other ways of whitelisting PowerShell scripts.
The certificate is valid until October 2025, we expect to renew and replace it some months prior to that.
If your security solution is whitelisting scripts based on location, then the below may be useful.
All scripts running as SYSTEM will be located in:
C:\Program Files (x86)\SecTeer VulnDetect\
(on 32-bit systems it would be without (x86)):
C:\Program Files\SecTeer VulnDetect\
And all user based scripts will be located in:
A bit of background about our Task Scripts:
The reason our Task Scripts are written in PowerShell, is because we need to be able to rapidly adapt the code to the need of various installers and applications.
Developing in PowerShell is fairly easy, and it is, well powerful, when it comes to do relatively small and trivial tasks in Windows.
In order to ensure that 3rd party security solutions don't sound the alarm because of our Task Scripts, we decided to digitally sign them with a Code Signing certificate.
However, when PowerShell scripts are signed, they also become valuable for malicious actors, if they aren't carefully engineered.
This is the reason that the scripts aren't just simple "wrappers" for the installers.
In fact, our Task Scripts, are fed with a Task definition in JSON.
This JSON contains information about the installer and the arguments supplied.
To ensure that you can't just supply the signed scripts any random JSON with a malicious installer and arguments, the Task Scripts will either call the VulnDetect backend with the Agent authentication token and the task UUID to get a SHA256SUM for JSON (old Agents) or read the SHA256SUM stored by the Agent in the registry (new Agents).
This ensures that the Task Script only runs task definitions created by the VulnDetect backend.
After verifying the task definition, the Task Script will download the installer and any other file needed for the task. These files are also verified based on the SHA256SUM in the Task definition.
The next step for the Task Script is to test whether any conflicting processes are running. This is to ensure that the installer won't be run if the application is known to be adversely affect by an upgrade. If the application handles it well, such as all major browser, the upgrade is run regardless, for other applications, such as VPN software, the upgrade is rescheduled for the next system reboot.
The next step is to actually run the installer, however, before running the installer, the Task Script will check if the Windows Installer database is busy. It may be busy if the system is applying other updates, or the user is installing an application. When the Windows Installer database is available, the installation or upgrade will proceed.
The Windows Installer database is often busy for some minutes after running each installer, the wait in the Task Script, cause some delay, which you may notice in the Update Activity in the UI, however, it improves the success rate and thus often saves the update from a retry and a 24-hour delay (or the next (manual) inspection).
The final step is to check the exit code of the installer and report back to the backend (it actually reports back multiple times).
The above is crude description of the Task Script, some minor details have been left out.