The Great SharePoint Rescue: How We Outsmarted Ransomware with a Clever Script

  • 11 januari 2024
  • 7 min leestijd

At Cloud Agent B.V., we recently got contacted by another IT company. One of their customers’ encrypted files were moved to SharePoint Online, and the hackers demanded €50,000 for decryption. But we chose to fight back and help them out with our expertise.

The Dilemma: A Costly Ransom or Total Data Loss

The client was at a crossroads: pay a hefty ransom or risk losing vital data. The ransomware, identifiable by the “.faust” extension, had wreaked havoc by encrypting files and relegating them to the SharePoint recycle bin. This was a test of our skills against a malicious adversary.

The Hero: A Custom PowerShell Script

Enter our custom PowerShell script, a digital savior crafted by Said Aazani. This script was not just code; it was our strategic response to the ransomware attack. It’s designed to navigate the complexities of SharePoint Online, target the encrypted files, and restore them to their pre-attack state.

The Outcome: Triumph Over Ransomware

The result? We successfully restored and decrypted all affected files without paying the ransom. Our script proved to be a decisive factor in outwitting the ransomware, saving the client €50,000 and protecting their crucial data.

# Enhanced SharePoint Online File Recovery Script
# Developed by Cloud Agent B.V. - https://cloudagent.nl
# This script restores encrypted files in SharePoint Online after a malware attack, renames them, and resets their version.

# Ensure necessary modules are installed
if (-not (Get-Module -Name "PnP.PowerShell" -ListAvailable)) {
    Install-Module -Name "PnP.PowerShell" -Scope CurrentUser
}

# Config Variables
$SiteURL = "<Your SharePoint Site URL>" # Replace with your SharePoint site URL
$DocumentLibraryPath = "<Your Document Library Path>" # e.g., 'sites/YourSite/Shared Documents/General'
$FileExtension = "<File Extension to Search>" # e.g., '.faust'
$SuffixToRemove = "<Suffix to Remove from File Name>" # e.g., '.id[XXXXXX].[email@example.com].faust'
$LogFilePath = "<Path to Log File>" # e.g., 'C:\logs\SharePointFileRecovery.log'

# Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -UseWebLogin

# Retrieve items from the Recycle Bin
$allItems = Get-PnPRecycleBinItem | Where-Object {
    $_.DirName -like "$DocumentLibraryPath/*" -and
    $_.Title -like "*$FileExtension*" -and
    $_.Title -notlike "desktop.ini.id*"
}

# Initialize counters
$totalItems = $allItems.Count
$currentItem = 0

# Process each item
foreach ($i in $allItems) {
    $currentItem++
    $newFileName = $i.Title -replace [regex]::Escape($SuffixToRemove), ""
    $serverRelativeUrl = "/" + $i.DirName + "/" + $newFileName

    $fileExists = $false
    try {
        $file = Get-PnPFile -Url $serverRelativeUrl -ErrorAction Stop
        $fileExists = $true
    } catch {
        $fileExists = $false
    }

    if (-not $fileExists) {
        try {
            # Restore and rename the file
            Restore-PnPRecycleBinItem -Identity $i.Id.Guid.ToString() -Force
            Start-Sleep -Seconds 5
            Rename-PnPFile -ServerRelativeUrl ("/" + $i.DirName + "/" + $i.Title) -TargetFileName $newFileName -Force

            # Reset file version
            Reset-PnPFileVersion -ServerRelativeUrl ("/" + $i.DirName + "/" + $newFileName)

            # Log success
            $logMessage = "Successfully restored: $($i.Title)"
            Add-Content -Path $LogFilePath -Value $logMessage
        } catch {
            # Log error
            $errorMessage = "Error processing $($i.Title): $_"
            Add-Content -Path $LogFilePath -Value $errorMessage
        }
    } else {
        # File already exists
        $logMessage = "File already exists, not restored: $serverRelativeUrl"
        Add-Content -Path $LogFilePath -Value $logMessage
    }

    $totalItems--
    Write-Host "Processed item $currentItem. Files left to process: $totalItems"
}

Write-Host "Script execution complete. Check log file for details: $LogFilePath"

 

Key Components of the Script

Module Dependency Check:

The script begins by ensuring that the necessary PowerShell module (PnP.PowerShell) is installed. This module is crucial for interfacing with SharePoint Online.

If the module is not present, the script automatically installs it, ensuring seamless execution regardless of the initial state of the environment.

Configurable Variables:

Variables like $SiteURL, $DocumentLibraryPath, $FileExtension, and $SuffixToRemove are defined at the start. These placeholders can be easily replaced with actual values specific to the environment, making the script highly adaptable to different scenarios.

Additionally, a $LogFilePath is specified for logging the script’s operations, aiding in tracking and auditing.

Connecting to SharePoint Online:

The script uses Connect-PnPOnline to establish a secure connection to the specified SharePoint Online site. This is a critical step for accessing and manipulating files in SharePoint.

Identifying and Processing Files:

It retrieves items from the SharePoint Recycle Bin, filtering for files with the specified extension (e.g., .faust) and excluding certain patterns (like desktop.ini.id*).

For each identified file, the script performs several operations:

  • Checks if a file with the same name minus the ransomware’s suffix (.faust) already exists in the location.
  • If the file does not exist, it restores the item from the Recycle Bin and renames it to remove the ransomware’s suffix.
  • Resets the file version to its pre-encryption state using Reset-PnPFileVersion.

Error Handling and Logging:

Throughout the script, try-catch blocks are used to handle potential errors gracefully.

Both successful operations and errors are logged to the specified log file, providing a detailed record of the script’s actions and any issues encountered.

Progress Monitoring:

The script keeps track of the total number of files processed and the number remaining. This real-time feedback is crucial for monitoring the script’s progress.

Conclusion

This enhanced PowerShell script is not just a tool; it’s a testament to our proactive approach against cyber threats. With its modular design, comprehensive logging, and robust error handling, it empowers organizations to efficiently recover from ransomware attacks in SharePoint Online environments. By automating the restoration and decryption process, we save valuable time and resources, turning a potential disaster into a manageable situation.