Swiftly secure system Update AnyDeskSystem with Automated Patching and remove compromised executables to prioritize digital security.

Table of Contents

    Swiftly secure system Update AnyDeskSystem with Automated Patching and remove compromised executables to prioritize digital security.

    Swiftly secure system Update AnyDeskSystem with Automated Patching and remove compromised executables to prioritize digital security.

    AnyDesk Compromised – How to Mitigate

    AnyDesk Software GmbH recently announced their production systems were compromised and that they are revoking code signing certificates prior to AnyDesk Windows version 8.0.8. As a best practice, whenever a code signing certificate is compromised, any executable in your environment signed with that certificate should be identified and removed immediately.

    Automox supports automated patching of AnyDesk, so we recommend checking your patch policies and implementing the latest AnyDesk patches immediately.

    We also recommend running the following scripts after patching to ensure no other executables in your environment are signed with the same certificate. These recommendations apply to everyone, regardless of whether you are an Automox customer or not (yet).

    Mitigation Script

    Powershell
    
    <#
    
    .SYNOPSIS
    
    This script will detect if the compromised AnyDesk certificate and executable(s) exist on a device.
    
    .DESCRIPTION
    
    It will iterate through all certificates within the Windows Certificate Store and look for a match against the compromised AnyDesk certificate's serial number.
    
    If found, the certificate details will be displayed to the console.
    
    It will then perform a recursive search through all .exe and .msi files on the device's SystemDrive, looking for a signing match for the compromised serial number.
    
    Note, the search for the compromised executable may take an extended period due to the device's disk speed and file structure.
    
    In the script's default state, if an executable is found it be reported against but it will not be deleted.
    
    To delete the executable, you must set the $removeExecutable parameter to $true.
    
    .PARAMETER $serialNumberToFind
    
    A [ String ] defining the serial number of the certificate and executable to search for.
    
    .EXAMPLE
    
    $serialNumberToFind = "0DBF152DEAF0B981A8A938D53F769DB8"
    
    This is defaulted to the AnyDesk compromised certificate.
    
    .PARAMETER $removeExecutable
    
    A [ Boolean ] defining if the compromised executable should be deleted from the device if found.
    
    This value is defaulted to $false, meaning the executable will remain on the device.
    
    If this value is set to $true, any matching executable that is found will be force deleted.
    
    .EXAMPLE
    
    $removeExecutable = $false
    
    Detected executables will remain on the device.
    
    .EXAMPLE
    
    $removeExecutable = $true
    
    Detected executables will be deleted.
    
    .NOTES
    
    Additional Log output can be enabled by uncommenting $VerbosePreference.
    
    This script will not uninstall AnyDesk from a device!
    
    It is merely a tool for reporting against and acting on the compromised certificate and executables.
    
    HISTORY
    
    Name: Automox
    
    Date: 02/02/2024
    
    Version: 1.0.0
    
    - Initial Release.
    
    .LINK
    
    https://www.automox.com/blog/anydesk-compromised-automox-fix/
    
    #>
    
    #########################################
    
    # DEFINE PARAMETERS
    
    # Define the serial number to search for
    
    $serialNumberToFind = '0DBF152DEAF0B981A8A938D53F769DB8' # This is defaulted to the AnyDesk compromised certificate.
    
    # Switch for removing the compromised executables
    
    $removeExecutable = $false # Set to $true if the file(s) should be deleted.
    
    #########################################
    
    # DEFINE VERBOSITY PREFERENCE
    
    # Uncommenting $VerbosePreference will expose additional script output
    
    # This can be used for troubleshooting purposes
    
    # $VerbosePreference = 'Continue'
    
    #########################################
    
    # PREDEFINED PARAMETERS
    
    # Defining the certificate stores and names to search in
    
    $storeLocations = @('LocalMachine', 'CurrentUser')
    
    $storeNames = @('My', 'Root', 'TrustedPublisher')
    
    # Setting flag for certificate detection
    
    $certificateFound = $false
    
    #########################################
    
    # DECLARING FUNCTIONS
    
    function Get-BinarySignature {
    
    param (
    
    [ Parameter ( Position = 0, Mandatory = $true ) ]
    
    [ System.String ]$FilePath,
    
    [ Parameter ( Position = 1, Mandatory = $true ) ]
    
    [ System.String ] $SerialNumber
    
    )
    
    $signature = Get-AuthenticodeSignature -FilePath $FilePath
    
    if ( $null -ne $signature -and $null -ne $signature.SignerCertificate ) {
    
    return $signature.SignerCertificate.SerialNumber -eq $SerialNumber
    
    }
    
    return $false
    
    }
    
    #########################################
    
    #--! Begin certificate search !--
    
    Write-Verbose 'Searching the certificate store for serial number matches...'
    
    # Iterate through store locations
    
    foreach ( $storeLocation in $storeLocations ) {
    
    # Iterate through store names
    
    foreach ( $storeName in $storeNames ) {
    
    # Open the certificate store
    
    $store = New-Object System.Security.Cryptography.X509Certificates.X509Store( $storeName, $storeLocation )
    
    $store.Open( [ System.Security.Cryptography.X509Certificates.OpenFlags ]::ReadOnly )
    
    # Define search by serial number
    
    $certificates = $store.Certificates | Where-Object { $_.SerialNumber -eq $serialNumberToFind }
    
    # Iterate through certificates
    
    foreach ( $certificate in $certificates ) {
    
    # Set found flag to true
    
    $certificateFound = $true
    
    # Indicate that certificate match was found
    
    Write-Output 'A certificate match was found!'
    
    # Prepare the details for the certificate
    
    $certificateDetails = @{
    
    'Store' = $storeName
    
    'Location' = $storeLocation
    
    'Issuer' = $certificate.Issuer
    
    'Serial Number' = $certificate.SerialNumber
    
    'Subject' = $certificate.Subject
    
    'Thumbprint' = $certificate.Thumbprint
    
    }
    
    # Output the certificate details
    
    $certificateDetails.GetEnumerator() | ForEach-Object {
    
    Write-Output "$( $_.Key ): $( $_.Value )"
    
    }
    
    # Close the store
    
    $store.Close()
    
    # If certificate found, break out of the inner loop
    
    if ( $certificateFound ) {
    
    break
    
    }
    
    }
    
    }
    
    # If certificate found, break out of the outer loop
    
    if ( $certificateFound ) {
    
    break
    
    }
    
    }
    
    # Indicate if certificate match was not found
    
    if ( -not $certificateFound ) {
    
    Write-Output 'A certificate match was not found.'
    
    }
    
    #########################################
    
    # --! Begin executable search !--
    
    Write-Verbose 'Searching for compromised executables...'
    
    # Search for .exe and .msi files starting from the root drive
    
    $files = Get-ChildItem -Path "${env:SystemDrive}\" -Recurse -Include .exe, .msi -ErrorAction SilentlyContinue
    
    # Filter files by checking their signature
    
    $matchingFiles = @()
    
    foreach ( $file in $files ) {
    
    if ( Get-BinarySignature -FilePath $file.FullName -SerialNumber $serialNumberToFind ) {
    
    $matchingFiles += $file.FullName
    
    }
    
    }
    
    # Executable was found, attempt force delete
    
    if ( $matchingFiles.Count -gt 0 ) {
    
    Write-Output 'Found compromised executable:'
    
    foreach ( $file in $matchingFiles ) {
    
    # Output the detected file(s)
    
    Write-Output $file
    
    # If $removeExecutable switch is true, delete the file(s).
    
    if ( $removeExecutable ) {
    
    Write-Verbose 'The removeExecutable variable is set to true. Proceeding with file deletion...'
    
    try {
    
    Remove-Item -Path $file -Force -ErrorAction Stop
    
    Write-Output "Successfully deleted: $file"
    
    }
    
    catch {
    
    Write-Error "Failed to delete: $file. Error: $_"
    
    exit 1
    
    }
    
    }
    
    # If $removeExecutable switch is false, indicate that the files will not be deleted.
    
    else {
    
    Write-Verbose 'The removeExecutable variable is set to false. The file will not be deleted.'
    
    }
    
    }
    
    }
    
    else {
    
    Write-Output 'No matching signed executables found. Device is compliant.'
    
    exit 0
    
    }

    YARA Rule

    If you’re having difficulty finding the version of AnyDesk you’re currently running, this YARA rule can help detect if the invalidated certificate is being used.