Hello,
Today I am releasing a script/tool, called Orion Malware Cleaner.
Its uses heuristics to very aggressively target highly suspicious entities and persistence.
Before the scan, a system restore point will be creted.
The user is kept informed throughout every step of the process.
Any files that can't be removed immediately are scheduled for deletion on reboot.
Please be advised that these aggressive heuristics can lead to false positives and or system damage. Use at your own risk and not as a replacement of a security product.
Please be advised the tool targets active malware that may sabotage security scans, security products download/installation or may go unnoticed by malware scanners.
It does not detect and remove all malware.
The list of scans and heuristics is bellow:
And the script is below, you can copy, paste and save as PS1.
This script will be offered by the upcoming Orion engine as well, but there, it will more surgically take care of malware based on sandbox logs + generic cleanups.
Today I am releasing a script/tool, called Orion Malware Cleaner.
Its uses heuristics to very aggressively target highly suspicious entities and persistence.
Before the scan, a system restore point will be creted.
The user is kept informed throughout every step of the process.
Any files that can't be removed immediately are scheduled for deletion on reboot.
Please be advised that these aggressive heuristics can lead to false positives and or system damage. Use at your own risk and not as a replacement of a security product.
Please be advised the tool targets active malware that may sabotage security scans, security products download/installation or may go unnoticed by malware scanners.
It does not detect and remove all malware.
The list of scans and heuristics is bellow:
| Phase | Target Area | Heuristic / Logic |
| Pre-Flight | System Restore | System Snapshot: Creates a Checkpoint-Computer restore point to provide a full system rollback safety net before any changes are made. |
| Phase 1: Payloads | Public, Downloads Folders | Broad Scan: Recursively finds any .exe, .vbs, .js, .jar, .bat, or .vbe file that is either a script type or lacks a valid digital signature. |
| ProgramData, AppData\Roaming | "Lonely File" Scan: Finds folders containing only one file and flags it if that file is a suspicious script type or an unsigned executable. | |
| Files found above | Reputation Check: Submits suspicious files to the local Microsoft Defender engine (MpCmdRun.exe) for an on-demand verdict. | |
| Files found above | Ghost Hunter Scan: Checks the flagged suspicious files for hidden Alternate Data Streams (ADS). | |
| Phase 2: Anomalies | SystemRoot & System32 | Recent Anomaly Scan: Finds any .exe or .dll file that is both unsigned AND was created in the last 7 days, targeting freshly dropped malware. |
| High-Risk Locations | Masquerading Scan: Hunts for unsigned files named after critical system processes (e.g., svchost.exe) located outside their legitimate system directories. | |
| Phase 3: Persistence | Registry Run Keys | Suspicious Command Scan: Flags entries launching PowerShell with stealth flags (-enc), launching a .jar file from a high-risk location, or launching any unsigned executable or other script type. |
| Scheduled Tasks | Suspicious Action Scan: Flags tasks that launch PowerShell with stealth flags, a .jar file from a high-risk location, an unsigned executable, or another script type. | |
| WMI Subscriptions | Malicious Consumer Scan: Hunts for fileless persistence by flagging WMI consumers that launch PowerShell with stealth flags. | |
| System Services | Suspicious Service Scan: Flags services that are unsigned, run from a high-risk location, or use a script as their executable path. | |
| BITS Jobs | Backdoor Delivery Scan: Finds BITS transfers downloading from non-Microsoft URLs, often with random names, and configured to execute a payload. | |
| Office Startup Folders | Macro Persistence Scan: Checks the dedicated STARTUP folders for Word and Excel, flagging any content as suspicious. | |
| Phase 4: Hardening | System Policies (Registry) | Disabled Tools Scan: Checks if critical tools like Task Manager, User Account Control (UAC), or the SmartScreen filter have been disabled. |
| Critical Services | Disabled Service Scan: Checks if the Windows Update service has been disabled. | |
| hosts File | Network Hijack Scan: Scans for any active, uncommented entries that could be redirecting network traffic. | |
| Windows Firewall | Firewall Infiltration Scan: Finds and flags outbound rules that explicitly allow an unsigned program to communicate. | |
| Microsoft Defender | Dangerous Exclusion Scan: Flags overly broad or high-risk antivirus exclusions (e.g., for C:\, AppData). | |
| Phase 5: Hygiene | Startup Folders | Zero-Trust Cleanup: Proposes a complete wipe of the user and system Startup folders. |
| Temporary Files Folder | Volatile Data Cleanup: Proposes a full recursive deletion of the %TEMP% directory. | |
| Recycle Bin | Final Cleanup: Proposes to permanently empty the Recycle Bin. | |
| Phase 6: Browser Reset | Chrome, Edge, Firefox | Adware Cleanup: Offers to terminate and reset all major web browsers to their default state, wiping extensions and settings. |
| Phase 7: Integrity | Windows Update | Update Check: Offers to enable the update service and initiate a scan for missing security updates. |
| Core System Files | System File Repair: Offers to run DISM and SFC to repair any corruption to the OS itself. |
And the script is below, you can copy, paste and save as PS1.
This script will be offered by the upcoming Orion engine as well, but there, it will more surgically take care of malware based on sandbox logs + generic cleanups.
Code:
#Requires -RunAsAdministrator
if (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
Write-Warning "This script must be run with Administrator privileges. Please re-launch from an elevated PowerShell terminal."
Read-Host "Press Enter to exit..."
exit 1
}
Clear-Host
$logPath = "$env:USERPROFILE\Documents\Orion_Logs"
if (-not (Test-Path $logPath)) {
try {
New-Item -Path $logPath -ItemType Directory -Force -ErrorAction Stop | Out-Null
} catch {
Write-Warning "Could not create log directory at '$logPath'. Please check permissions."
Read-Host "Press Enter to exit..."
exit 1
}
}
$logFile = "$logPath\Orion_Remediation_Log_$(Get-Date -Format 'yyyy-MM-dd_HH-mm-ss').log"
try {
Start-Transcript -Path $logFile -ErrorAction Stop
} catch {
Write-Warning "Could not start transcript logging to '$logFile'. Error: $_.Exception.Message"
Read-Host "Press Enter to exit..."
exit 1
}
$psVersion = $PSVersionTable.PSVersion.Major
$actionsTaken = [System.Collections.ArrayList]::new()
$rebootFiles = [System.Collections.ArrayList]::new()
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host " Welcome to the Orion Standalone Remediation Tool" -ForegroundColor Yellow
Write-Host "================================================================" -ForegroundColor Yellow
Write-Host ""
Write-Host "This script will perform a multi-phase scan of your system for"
Write-Host "suspicious artifacts commonly associated with malware."
Write-Host ""
Write-Host "A detailed log of this session will be saved to:" -ForegroundColor Cyan
Write-Host $logFile -ForegroundColor Cyan
if ($psVersion -ge 7) {
Write-Host "PowerShell 7+ detected. Parallel scanning enabled." -ForegroundColor Green
} else {
Write-Host "Older PowerShell version detected. Scans will run sequentially." -ForegroundColor Yellow
}
Write-Host ""
Write-Host "You will be prompted for confirmation before any files are deleted"
Write-Host "or any system settings are changed."
Write-Host ""
Write-Host "Press Enter to begin the scan..." -ForegroundColor Cyan
Read-Host
Write-Host ""
function Confirm-Action {
param(
[string]$Prompt
)
try {
$response = Read-Host -Prompt $Prompt
return $response -match '^[Yy]'
} catch {
Write-Warning "Could not read response. Defaulting to 'No'. Error: $_.Exception.Message"
return $false
}
}
Write-Host "--- PRE-FLIGHT CHECK: System Restore Point ---" -ForegroundColor Yellow
Write-Host "It is highly recommended to create a System Restore Point before making changes."
Write-Host "This provides a safety net to revert the system if needed."
if (Confirm-Action "Do you want to create a System Restore Point now? (Y/N)") {
try {
$restorePointDescription = "Orion Remediation Tool Pre-Scan"
Write-Host "Creating restore point '$restorePointDescription'..." -ForegroundColor Cyan
Checkpoint-Computer -Description $restorePointDescription -ErrorAction Stop
Write-Host "Successfully created System Restore Point." -ForegroundColor Green
$actionsTaken.Add("Created System Restore Point: '$restorePointDescription'") | Out-Null
} catch {
Write-Warning "Failed to create System Restore Point. This can happen if System Restore is disabled. Error: $_.Exception.Message"
if (-not (Confirm-Action "Do you want to continue without a restore point? (Y/N)")) {
Write-Host "Aborting script."
Read-Host "Press Enter to exit..."
Stop-Transcript
exit
}
}
} else {
Write-Host "Skipping System Restore Point creation."
}
Write-Host ""
Write-Host "--- PHASE 1: Hunting for Suspicious Payloads & Hidden Data ---" -ForegroundColor Yellow
$targetExtensions = @("*.exe", "*.vbs", "*.js", "*.jar", "*.bat", "*.vbe")
$allSuspiciousFiles = @()
$exclusionPaths = @("$env:SystemRoot\SoftwareDistribution", "$env:SystemRoot\WinSxS")
$exclusionRegex = ($exclusionPaths | ForEach-Object { [regex]::Escape($_) }) -join '|'
Write-Host "Scanning Public and Downloads folders..."
$broadScanPaths = @("$env:PUBLIC", "$env:USERPROFILE\Downloads")
if ($psVersion -ge 7) {
$results = Get-ChildItem -Path $broadScanPaths -Include $targetExtensions -Recurse -ErrorAction SilentlyContinue | ForEach-Object -Parallel {
if ($_.FullName -notmatch $using:exclusionRegex) {
if ($_.Extension -in '.jar', '.vbe', '.bat') {
return $_
} elseif ((Get-AuthenticodeSignature -FilePath $_.FullName -ErrorAction SilentlyContinue).Status -ne 'Valid') {
return $_
}
}
return $null
} -ThrottleLimit 384
$allSuspiciousFiles += $results | Where-Object { $_ -ne $null }
} else {
$filesToScan = Get-ChildItem -Path $broadScanPaths -Include $targetExtensions -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch $exclusionRegex }
$totalFiles = $filesToScan.Count
$processedCount = 0
Get-ChildItem -Path $broadScanPaths -Include $targetExtensions -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch $exclusionRegex } | ForEach-Object {
$file = $_
$processedCount++
$percent = ($processedCount / $totalFiles) * 100
Write-Progress -Activity "Scanning Public and Downloads folders" -Status "Processing: $($file.FullName)" -PercentComplete $percent -CurrentOperation "$processedCount of $totalFiles"
if ($file.Extension -in '.jar', '.vbe', '.bat') {
$allSuspiciousFiles += $file
} elseif ((Get-AuthenticodeSignature -FilePath $file.FullName -ErrorAction SilentlyContinue).Status -ne 'Valid') {
$allSuspiciousFiles += $file
}
}
Write-Progress -Activity "Scanning Public and Downloads folders" -Status "Complete" -PercentComplete 100 -Completed
}
Write-Host "Scanning ProgramData and AppData\Roaming for isolated, suspicious files..."
$surgicalScanPaths = @("$env:PROGRAMDATA", "$env:APPDATA")
if ($psVersion -ge 7) {
$results = Get-ChildItem -Path $surgicalScanPaths -Directory -ErrorAction SilentlyContinue | ForEach-Object -Parallel {
$dir = $_
$items = Get-ChildItem -Path $dir.FullName -File -ErrorAction SilentlyContinue
if ($items.Count -eq 1) {
$file = $items[0]
if ($file.Extension -in '.exe','.vbs','.js','.jar','.bat','.vbe') {
if ($file.Extension -in '.jar', '.vbe', '.bat') {
return $file
} elseif ((Get-AuthenticodeSignature -FilePath $file.FullName -ErrorAction SilentlyContinue).Status -ne 'Valid') {
return $file
}
}
}
return $null
} -ThrottleLimit 384
$allSuspiciousFiles += $results | Where-Object { $_ -ne $null }
} else {
$dirsToScan = Get-ChildItem -Path $surgicalScanPaths -Directory -ErrorAction SilentlyContinue
$totalDirs = $dirsToScan.Count
$processedDirCount = 0
Get-ChildItem -Path $surgicalScanPaths -Directory -ErrorAction SilentlyContinue | ForEach-Object {
$dir = $_
$processedDirCount++
$percent = ($processedDirCount / $totalDirs) * 100
Write-Progress -Activity "Scanning Isolated Files" -Status "Processing: $($dir.FullName)" -PercentComplete $percent -CurrentOperation "$processedDirCount of $totalDirs directories"
$items = Get-ChildItem -Path $dir.FullName -File -ErrorAction SilentlyContinue
if ($items.Count -eq 1) {
$file = $items[0]
if ($file.Extension -in '.exe','.vbs','.js','.jar','.bat','.vbe') {
if ($file.Extension -in '.jar', '.vbe', '.bat') {
$allSuspiciousFiles += $file
} elseif ((Get-AuthenticodeSignature -FilePath $file.FullName -ErrorAction SilentlyContinue).Status -ne 'Valid') {
$allSuspiciousFiles += $file
}
}
}
}
Write-Progress -Activity "Scanning Isolated Files" -Status "Complete" -PercentComplete 100 -Completed
}
if ($allSuspiciousFiles.Count -gt 0) {
Write-Host "`nSuspicious Files Found in common areas:" -ForegroundColor Cyan
$uniqueFiles = $allSuspiciousFiles | Select-Object -Property FullName, Length, CreationTime, LastWriteTime -Unique
$uniqueFiles | Format-Table -AutoSize
if (Confirm-Action "Do you want to DELETE these files? This is irreversible. (Y/N)") {
Write-Host "Deleting files..."
$uniqueFiles | ForEach-Object {
$filePath = $_.FullName
try {
Remove-Item -Path $filePath -Force -Recurse -ErrorAction Stop
Write-Host " Deleted: $filePath" -ForegroundColor Green
$actionsTaken.Add("Deleted file: $filePath") | Out-Null
} catch {
Write-Warning " Could not delete '$filePath'. It may be in use. Scheduling for deletion on reboot. Error: $_.Exception.Message"
$rebootPath = "\\??\\" + (Resolve-Path -LiteralPath $filePath).Path
$rebootFiles.Add($rebootPath) | Out-Null
$rebootFiles.Add("") | Out-Null
$actionsTaken.Add("Scheduled for reboot deletion: $filePath") | Out-Null
}
}
} else {
Write-Host "Skipping deletion of suspicious files."
}
Write-Host "`nScanning suspicious files for hidden data streams (ADS)..."
$filesWithADS = $uniqueFiles | ForEach-Object {
$file = $_
if (Test-Path -LiteralPath $file.FullName) {
$streams = Get-Item -Path $file.FullName -Stream * -ErrorAction SilentlyContinue | Where-Object { $_.Stream -ne ':$DATA' }
if ($streams) { [PSCustomObject]@{ File = $file.FullName; HiddenStreams = $streams.Stream -join ", " } }
}
}
if ($filesWithADS) {
Write-Host "`nSECURITY RISK: Alternate Data Streams (ADS) can be used by malware to hide malicious code." -ForegroundColor Yellow
$filesWithADS | Format-Table -AutoSize
if (Confirm-Action "Do you want to REMOVE the hidden data from these files? (This does not delete the file itself) (Y/N)") {
$filesWithADS | ForEach-Object {
$filePath = $_.File
$streamsToRemove = ($_.HiddenStreams -split ', ')
foreach ($stream in $streamsToRemove) {
try {
Remove-Item -Path $filePath -Stream $stream -Force -ErrorAction Stop
Write-Host " Removed stream '$stream' from '$filePath'" -ForegroundColor Green
$actionsTaken.Add("Removed ADS '$stream' from: $filePath") | Out-Null
} catch { Write-Warning " Failed to remove stream '$stream' from '$filePath': $_.Exception.Message" }
}
}
}
}
} else {
Write-Host "No suspicious unsigned or isolated files found in high-risk locations." -ForegroundColor Green
}
Write-Host ""
Write-Host "--- PHASE 2: Hunting for Masquerading System Processes (Advanced) ---" -ForegroundColor Yellow
$legitimateProcesses = @{
"svchost.exe" = @("$env:SystemRoot\System32", "$env:SystemRoot\SysWOW64");
"lsass.exe" = @("$env:SystemRoot\System32");
"csrss.exe" = @("$env:SystemRoot\System32");
"wininit.exe" = @("$env:SystemRoot\System32");
"winlogon.exe" = @("$env:SystemRoot\System32");
"services.exe" = @("$env:SystemRoot\System32");
"smss.exe" = @("$env:SystemRoot\System32")
}
$masqueradingFiles = @()
$scanLocations = @("$env:USERPROFILE", "$env:PROGRAMDATA", "$env:PUBLIC", "$env:APPDATA", "$env:LOCALAPPDATA")
$exclusionPaths = @("$env:SystemRoot\SoftwareDistribution", "$env:SystemRoot\WinSxS")
$exclusionRegex = ($exclusionPaths | ForEach-Object { [regex]::Escape($_) }) -join '|'
if ($psVersion -ge 7) {
Write-Host "Running parallel masquerading process scan..."
$results = $legitimateProcesses.Keys | ForEach-Object -Parallel {
$procName = $_
$legitPaths = ($using:legitimateProcesses)[$procName]
$scanLocations_local = $using:scanLocations
$masqueradingFile = $null
Get-ChildItem -Path $scanLocations_local -Filter $procName -Recurse -ErrorAction SilentlyContinue | ForEach-Object {
if ($_.FullName -notmatch $using:exclusionRegex) {
$file = $_; $isLegit = $false
foreach($legitPath in $legitPaths) { if ($file.DirectoryName -eq $legitPath) { $isLegit = $true; break } }
if (-not $isLegit -and (Get-AuthenticodeSignature -FilePath $file.FullName -ErrorAction SilentlyContinue).Status -ne 'Valid') {
$masqueradingFile = [PSCustomObject]@{ImposterPath = $file.FullName; LegitimateName = $procName; Reason = "Unsigned file masquerading as a critical system process in an unauthorized location."}
}
}
}
$masqueradingFile
} -ThrottleLimit 384
$masqueradingFiles += $results | Where-Object { $_ -ne $null }
} else {
Write-Host "Running sequential masquerading process scan..."
$procNames = $legitimateProcesses.Keys
$totalProcs = $procNames.Count
$processedProcCount = 0
foreach ($procName in $procNames) {
$processedProcCount++
$percent = ($processedProcCount / $totalProcs) * 100
Write-Progress -Activity "Scanning for Masquerading Processes" -Status "Processing: $procName" -PercentComplete $percent -CurrentOperation "$processedProcCount of $totalProcs"
Get-ChildItem -Path $scanLocations -Filter $procName -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.FullName -notmatch $exclusionRegex } | ForEach-Object {
$file = $_; $isLegit = $false
foreach($legitPath in $legitimateProcesses[$procName]) { if ($file.DirectoryName -eq $legitPath) { $isLegit = $true; break } }
if (-not $isLegit -and (Get-AuthenticodeSignature -FilePath $file.FullName -ErrorAction SilentlyContinue).Status -ne 'Valid') {
$masqueradingFiles += [PSCustomObject]@{ImposterPath = $file.FullName; LegitimateName = $procName; Reason = "Unsigned file masquerading as a critical system process in an unauthorized location."}
}
}
}
Write-Progress -Activity "Scanning for Masquerading Processes" -Status "Complete" -PercentComplete 100 -Completed
}
if ($masqueradingFiles) {
Write-Host "`nPROCESS MASQUERADING DETECTED:" -ForegroundColor Red
$masqueradingFiles | Format-Table -Wrap
if (Confirm-Action "Do you want to DELETE these masquerading files? (Y/N)") {
Write-Host "Deleting files..."
$masqueradingFiles | ForEach-Object {
$filePath = $_.ImposterPath
try {
Remove-Item -Path $filePath -Force -Recurse -ErrorAction Stop
Write-Host " Deleted: $filePath" -ForegroundColor Green
$actionsTaken.Add("Deleted masquerading file: $filePath") | Out-Null
} catch {
Write-Warning " Could not delete '$filePath'. It may be in use. Scheduling for deletion on reboot. Error: $_.Exception.Message"
$rebootPath = "\\??\\" + (Resolve-Path -LiteralPath $filePath).Path
$rebootFiles.Add($rebootPath) | Out-Null
$rebootFiles.Add("") | Out-Null
$actionsTaken.Add("Scheduled masquerading file for reboot deletion: $filePath") | Out-Null
}
}
} else {
Write-Host "Skipping deletion of masquerading files."
}
} else {
Write-Host "No process masquerading detected in high-risk locations." -ForegroundColor Green
}
Write-Host ""
Write-Host "--- PHASE 3: Hunting for Suspicious Persistence Mechanisms ---" -ForegroundColor Yellow
$suspiciousRunKeys = @()
$suspiciousTasks = @()
$suspiciousWmiSubscriptions = @()
$scriptExtensions = @('.vbs', '.js', '.ps1', '.bat', '.vbe')
# Define the whitelist of trusted directories
$trustedPersistencePaths = @(
"${env:ProgramFiles}",
"${env:ProgramFiles(x86)}",
"${env:ProgramData}",
"${env:SystemRoot}",
"${env:SystemRoot}\System32",
"${env:SystemRoot}\SysWOW64"
)
$trustedRegex = ($trustedPersistencePaths | ForEach-Object { [regex]::Escape($_) }) -join '|'
#
# --- Sub-Phase 3a: Scanning Registry Run keys ---
#
Write-Host "Sub-Phase 3a: Scanning Registry Run keys for suspicious entries..."
$runKeysToScan = @(
@{ Name = "HKLM 64-bit"; Path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; Hive = "LocalMachine"; View = "Registry64" },
@{ Name = "HKCU 64-bit"; Path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; Hive = "CurrentUser"; View = "Registry64" },
@{ Name = "HKLM 32-bit"; Path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; Hive = "LocalMachine"; View = "Registry32" },
@{ Name = "HKCU 32-bit"; Path = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; Hive = "CurrentUser"; View = "Registry32" }
)
foreach ($keyInfo in $runKeysToScan) {
try {
Write-Progress -Activity "Scanning Registry Run Keys" -Status "Processing: $($keyInfo.Name)"
$baseKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey($keyInfo.Hive, $keyInfo.View)
$subKey = $baseKey.OpenSubKey($keyInfo.Path)
if ($null -ne $subKey) {
foreach ($valueName in $subKey.GetValueNames()) {
$commandValue = $subKey.GetValue($valueName).ToString()
if (-not [string]::IsNullOrWhiteSpace($commandValue)) {
$potentialPath = ""
$trimmedValue = $commandValue.Trim()
if ($trimmedValue.StartsWith('"')) {
$endQuoteIndex = $trimmedValue.IndexOf('"', 1)
if ($endQuoteIndex -gt 0) { $potentialPath = $trimmedValue.Substring(1, $endQuoteIndex - 1) }
} else {
$potentialPath = ($trimmedValue -split ' ')[0]
}
if ($potentialPath -and $potentialPath -match '\.(exe|vbs|js|ps1|bat|vbe|jar)$') {
$targetPath = [System.Environment]::ExpandEnvironmentVariables($potentialPath)
$fileExists = Test-Path -LiteralPath $targetPath
$isUntrusted = $targetPath -notmatch $trustedRegex
$isSuspicious = $false
if (-not $fileExists) {
$isSuspicious = $true
} elseif ($isUntrusted) {
$signature = Get-AuthenticodeSignature -FilePath $targetPath -ErrorAction SilentlyContinue
if ($signature.Status -ne 'Valid') {
$isSuspicious = $true
}
}
if ($isSuspicious) {
$suspiciousRunKeys += [PSCustomObject]@{
KeyPath = "Registry::$($keyInfo.Hive)\$($keyInfo.Path)"
Name = $valueName
Value = $commandValue
FilePath = $targetPath
}
}
}
}
}
}
}
catch {
Write-Warning "An error occurred while scanning key $($keyInfo.Name): $_"
}
}
Write-Progress -Activity "Scanning Registry Run Keys" -Status "Complete" -PercentComplete 100 -Completed
if ($suspiciousRunKeys) {
Write-Host "`nSuspicious Run Key Entries Found:" -ForegroundColor Cyan
$suspiciousRunKeys | Select-Object KeyPath, Name, Value | Format-Table -Wrap
if (Confirm-Action "Do you want to REMOVE these registry entries AND DELETE the associated files? (Y/N)") {
$suspiciousRunKeys | ForEach-Object {
# 1. Remove Registry Key
try {
Remove-ItemProperty -Path $_.KeyPath -Name $_.Name -Force -ErrorAction Stop
Write-Host " Removed Registry Key: $($_.Name)" -ForegroundColor Green
$actionsTaken.Add("Removed Run Key: $($_.Name) from $($_.KeyPath)") | Out-Null
} catch {
Write-Warning " Failed to remove registry key '$($_.Name)': $_.Exception.Message"
}
# 2. Delete File
if (Test-Path -LiteralPath $_.FilePath) {
try {
Remove-Item -Path $_.FilePath -Force -Recurse -ErrorAction Stop
Write-Host " Deleted File: $($_.FilePath)" -ForegroundColor Green
$actionsTaken.Add("Deleted associated file: $($_.FilePath)") | Out-Null
} catch {
Write-Warning " Could not delete '$($_.FilePath)'. Scheduling for reboot deletion. Error: $_.Exception.Message"
$rebootPath = "\\??\\" + (Resolve-Path -LiteralPath $_.FilePath).Path
$rebootFiles.Add($rebootPath) | Out-Null
$rebootFiles.Add("") | Out-Null
$actionsTaken.Add("Scheduled for reboot deletion: $($_.FilePath)") | Out-Null
}
}
}
} else { Write-Host "Skipping removal of registry entries and files." }
} else { Write-Host "No suspicious Run key entries found." -ForegroundColor Green }
Write-Host ""
#
# --- Sub-Phase 3b: Scanning Scheduled Tasks for suspicious actions (Corrected)---
#
Write-Host "Sub-Phase 3b: Scanning Scheduled Tasks for suspicious actions..."
$tasks = Get-ScheduledTask -ErrorAction SilentlyContinue | Get-ScheduledTaskInfo | Where-Object { $_.Actions }
if ($tasks) {
foreach ($task in $tasks) {
foreach ($action in $task.Actions) {
if ($action.Execute) {
$commandValue = "$($action.Execute) $($action.Arguments)"
$potentialPath = ""
$trimmedValue = $commandValue.Trim()
if ($trimmedValue.StartsWith('"')) {
$endQuoteIndex = $trimmedValue.IndexOf('"', 1)
if ($endQuoteIndex -gt 0) { $potentialPath = $trimmedValue.Substring(1, $endQuoteIndex - 1) }
} else {
$potentialPath = ($trimmedValue -split ' ')[0]
}
$targetPath = $null
if ($potentialPath -and $potentialPath -match '\.(exe|vbs|js|ps1|bat|vbe|jar)$') {
$targetPath = [System.Environment]::ExpandEnvironmentVariables($potentialPath)
}
if ($targetPath -and (Test-Path -LiteralPath $targetPath)) {
$isUntrusted = $targetPath -notmatch $trustedRegex
$isSuspicious = $false
if ($isUntrusted) {
# It's in an untrusted location, so check its signature.
$signature = Get-AuthenticodeSignature -FilePath $targetPath -ErrorAction SilentlyContinue
if ($signature.Status -ne 'Valid') {
$isSuspicious = $true
}
}
if ($isSuspicious) {
$suspiciousTasks += [PSCustomObject]@{ TaskName = $task.TaskName; TaskPath = $task.TaskPath; Action = $commandValue; FilePath = $targetPath }
}
}
}
}
}
}
if ($suspiciousTasks) {
Write-Host "`nSuspicious Scheduled Tasks Found:" -ForegroundColor Cyan; $suspiciousTasks | Format-Table -Wrap
if (Confirm-Action "Do you want to DISABLE these tasks AND DELETE the associated files? (Y/N)") {
$suspiciousTasks | ForEach-Object {
# 1. Disable Task
try {
Disable-ScheduledTask -TaskPath $_.TaskPath -TaskName $_.TaskName -ErrorAction Stop
Write-Host " Disabled Task: $($_.TaskName)" -ForegroundColor Green
$actionsTaken.Add("Disabled Scheduled Task: $($_.TaskName)") | Out-Null
} catch {
Write-Warning " Failed to disable '$($_.TaskName)': $_.Exception.Message"
}
# 2. Delete File
if (Test-Path -LiteralPath $_.FilePath) {
try {
Remove-Item -Path $_.FilePath -Force -Recurse -ErrorAction Stop
Write-Host " Deleted File: $($_.FilePath)" -ForegroundColor Green
$actionsTaken.Add("Deleted associated file: $($_.FilePath)") | Out-Null
} catch {
Write-Warning " Could not delete '$($_.FilePath)'. Scheduling for reboot deletion. Error: $_.Exception.Message"
$rebootPath = "\\??\\" + (Resolve-Path -LiteralPath $_.FilePath).Path
$rebootFiles.Add($rebootPath) | Out-Null
$rebootFiles.Add("") | Out-Null
$actionsTaken.Add("Scheduled for reboot deletion: $($_.FilePath)") | Out-Null
}
}
}
} else { Write-Host "Skipping disabling of scheduled tasks and deleting files." }
} else { Write-Host "No suspicious Scheduled Tasks found." -ForegroundColor Green }
Write-Host ""
Write-Host "Sub-Phase 3c: Scanning for suspicious WMI persistence..."
$wmiConsumers = Get-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -ErrorAction SilentlyContinue
if($wmiConsumers) {
foreach ($consumer in $wmiConsumers) {
$command = $consumer.CommandLineTemplate
if ($command -like "*powershell.exe*" -and $command -match '(-enc|-hidden|-w hidden|-windowstyle hidden|-noni)') {
$reason = "WMI subscription executes PowerShell with stealth flags."; $binding = Get-CimInstance -Namespace root/subscription -Query "REFERENCES OF {$($consumer.__PATH)} WHERE ResultClass = __FilterToConsumerBinding" -ErrorAction SilentlyContinue; $filter = Get-CimInstance -Namespace root/subscription -Query "ASSOCIATORS OF {$($binding.__PATH)} WHERE ResultClass = __EventFilter" -ErrorAction SilentlyContinue
if ($filter -and $binding) { $suspiciousWmiSubscriptions += [PSCustomObject]@{ ConsumerName = $consumer.Name; Command = $command; FilterName = $filter.Name; FilterQuery = $filter.Query; Reason = $reason } }
} elseif (($command -notmatch $trustedRegex -and $command -match $env:SystemRoot)) {
$reason = "Points to a file in a suspicious Windows subfolder."
$binding = Get-CimInstance -Namespace root/subscription -Query "REFERENCES OF {$($consumer.__PATH)} WHERE ResultClass = __FilterToConsumerBinding" -ErrorAction SilentlyContinue; $filter = Get-CimInstance -Namespace root/subscription -Query "ASSOCIATORS OF {$($binding.__PATH)} WHERE ResultClass = __EventFilter" -ErrorAction SilentlyContinue
if ($filter -and $binding) { $suspiciousWmiSubscriptions += [PSCustomObject]@{ ConsumerName = $consumer.Name; Command = $command; FilterName = $filter.Name; FilterQuery = $filter.Query; Reason = $reason } }
}
}
}
if ($suspiciousWmiSubscriptions) {
Write-Host "`nSuspicious WMI Persistence Subscriptions Found:" -ForegroundColor Cyan; $suspiciousWmiSubscriptions | Format-Table -Wrap
Write-Host "`nSECURITY RISK: WMI persistence is often used by advanced malware to achieve fileless persistence." -ForegroundColor Yellow
if (Confirm-Action "Do you want to REMOVE these WMI persistence objects? (Y/N)") {
Write-Host "Removing WMI objects..."; foreach ($sub in $suspiciousWmiSubscriptions) {
try {
Get-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Filter "Name = '$($sub.ConsumerName)'" | Remove-CimInstance; Write-Host " Removed Consumer: $($sub.ConsumerName)"
Get-CimInstance -Namespace root/subscription -ClassName __EventFilter -Filter "Name = '$($sub.FilterName)'" | Remove-CimInstance; Write-Host " Removed Filter: $($sub.FilterName)"
Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Filter "Filter = ""__EventFilter.Name='$($sub.FilterName)'""" | Remove-CimInstance; Write-Host " Removed Binding for '$($sub.ConsumerName)'" -ForegroundColor Green
$actionsTaken.Add("Removed WMI Persistence: $($sub.ConsumerName)") | Out-Null
} catch { Write-Warning " Failed to remove WMI objects for '$($sub.ConsumerName)': $_.Exception.Message" }
}
} else { Write-Host "Skipping removal of WMI persistence." }
} else { Write-Host "No suspicious WMI persistence subscriptions found." -ForegroundColor Green }
Write-Host ""
Write-Host "Sub-Phase 3d: Hunting for Suspicious Services..."
$suspiciousServices = @()
$services = Get-CimInstance -ClassName Win32_Service -ErrorAction SilentlyContinue
foreach ($service in $services) {
if ($service.PathName) {
$path = ($service.PathName -split ' ')[0].Trim('"')
if ($path -and (Test-Path -LiteralPath $path)) {
$isSuspicious = $false
$extension = [System.IO.Path]::GetExtension($path).ToLower()
if ($scriptExtensions -contains $extension) {
$isSuspicious = $true
}
elseif ($extension -eq '.exe') {
if ((Get-AuthenticodeSignature -FilePath $path -ErrorAction SilentlyContinue).Status -ne 'Valid') {
$isSuspicious = $true
}
}
if ($isSuspicious) {
$suspiciousServices += [PSCustomObject]@{ Name = $service.Name; DisplayName = $service.DisplayName; Path = $path; }
}
}
}
}
if ($suspiciousServices) {
Write-Host "`nSuspicious Services Found:" -ForegroundColor Cyan; $suspiciousServices | Format-Table -Wrap
if (Confirm-Action "Do you want to STOP/DISABLE these services AND DELETE the associated files? (Y/N)") {
$suspiciousServices | ForEach-Object {
# 1. Stop and Disable Service
try {
Stop-Service -Name $_.Name -Force -ErrorAction Stop
Set-Service -Name $_.Name -StartupType Disabled -ErrorAction Stop
Write-Host " Stopped and Disabled: $($_.DisplayName)" -ForegroundColor Green
$actionsTaken.Add("Stopped & Disabled Service: $($_.DisplayName)") | Out-Null
} catch { Write-Warning " Failed to stop/disable service '$($_.DisplayName)': $_.Exception.Message" }
# 2. Delete File
if (Test-Path -LiteralPath $_.Path) {
try {
Remove-Item -Path $_.Path -Force -Recurse -ErrorAction Stop
Write-Host " Deleted File: $($_.Path)" -ForegroundColor Green
$actionsTaken.Add("Deleted associated file: $($_.Path)") | Out-Null
} catch {
Write-Warning " Could not delete '$($_.Path)'. Scheduling for reboot deletion. Error: $_.Exception.Message"
$rebootPath = "\\??\\" + (Resolve-Path -LiteralPath $_.Path).Path
$rebootFiles.Add($rebootPath) | Out-Null
$rebootFiles.Add("") | Out-Null
$actionsTaken.Add("Scheduled for reboot deletion: $($_.Path)") | Out-Null
}
}
}
} else { Write-Host "Skipping service modification and file deletion." }
} else { Write-Host "No suspicious services found." -ForegroundColor Green }
Write-Host ""
Write-Host "Sub-Phase 3e: Hunting for Suspicious BITS Jobs..."
$suspiciousBitsJobs = @()
try {
$bitsJobs = Get-BitsTransfer -AllUsers -ErrorAction SilentlyContinue
if($bitsJobs) {
foreach ($job in $bitsJobs) {
$isSuspicious = $false; $reason = ""
if ($job.JobState -eq 'Transferring' -or $job.JobState -eq 'Suspended') {
if ($job.DisplayName -match '^[A-F0-9]{8}-([A-F0-9]{4}-){3}[A-F0-9]{12}$') {
$isSuspicious = $true; $reason = "Job uses a random GUID as a name, a common malware tactic."
}
if ($job.Files | ForEach-Object { $_.RemoteName -notlike "http*://*.microsoft.com/*" -and $_.RemoteName -notlike "http*://*.windowsupdate.com/*" }) {
$isSuspicious = $true; $reason = "Downloads from a non-Microsoft/Windows Update URL."
}
if ($isSuspicious) {
$suspiciousBitsJobs += [PSCustomObject]@{ JobName = $job.DisplayName; SourceURL = ($job.Files | Select-Object -ExpandProperty RemoteName) -join ', '; Destination = ($job.Files | Select-Object -ExpandProperty LocalName) -join ', '; Reason = $reason }
}
}
}
}
} catch {
Write-Warning "Could not retrieve BITS jobs. The BITS module may not be available or the service is stopped. Error: $_.Exception.Message"
}
if ($suspiciousBitsJobs) {
Write-Host "`nSuspicious BITS Jobs Found:" -ForegroundColor Cyan; $suspiciousBitsJobs | Format-Table -Wrap
if (Confirm-Action "Do you want to CANCEL and REMOVE these BITS jobs? (Y/N)") {
Write-Host "Removing BITS jobs..."; $suspiciousBitsJobs | ForEach-Object { try { Remove-BitsTransfer -BitsJob (Get-BitsTransfer -DisplayName $_.JobName); Write-Host " Removed: $($_.JobName)" -ForegroundColor Green; $actionsTaken.Add("Removed BITS Job: $($_.JobName)") | Out-Null } catch { Write-Warning " Failed to remove '$($_.JobName)': $_.Exception.Message" } }
} else { Write-Host "Skipping BITS job removal." }
} else { Write-Host "No suspicious BITS jobs found." -ForegroundColor Green }
Write-Host ""
Write-Host "Sub-Phase 3f: Hunting for Office Macro Persistence..."
$officeStartupPaths = @(
"$env:APPDATA\Microsoft\Word\STARTUP",
"$env:APPDATA\Microsoft\Excel\XLSTART"
)
$suspiciousOfficeFiles = @()
foreach ($path in $officeStartupPaths) {
if (Test-Path $path) {
$foundFiles = Get-ChildItem -Path $path -File -ErrorAction SilentlyContinue
if ($foundFiles) {
$suspiciousOfficeFiles += $foundFiles
}
}
}
if ($suspiciousOfficeFiles) {
Write-Host "`nSuspicious Files Found in Office Startup Folders:" -ForegroundColor Cyan
$suspiciousOfficeFiles | Select-Object -Property FullName, Length, CreationTime | Format-Table -AutoSize
Write-Host "`nSECURITY RISK: Files in these folders automatically execute when Word or Excel starts." -ForegroundColor Yellow
if (Confirm-Action "Do you want to DELETE these files? (Y/N)") {
Write-Host "Deleting files..."; $suspiciousOfficeFiles | ForEach-Object {
$filePath = $_.FullName
try {
Remove-Item -Path $filePath -Force -Recurse -ErrorAction Stop
Write-Host " Deleted: $filePath" -ForegroundColor Green
$actionsTaken.Add("Deleted Office Startup file: $filePath") | Out-Null
} catch {
Write-Warning " Could not delete '$filePath': $_.Exception.Message"
}
}
} else { Write-Host "Skipping Office startup file deletion." }
} else { Write-Host "No suspicious files found in Office startup locations." -ForegroundColor Green }
Write-Host ""
Write-Host "--- PHASE 4: System Integrity & Hardening ---" -ForegroundColor Yellow
Write-Host "Scanning for disabled system tools and critical services..."
$tamperedSettings = @()
$taskMgrPolicy = Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableTaskMgr" -ErrorAction SilentlyContinue
if ($taskMgrPolicy -and $taskMgrPolicy.DisableTaskMgr -eq 1) { $tamperedSettings += [PSCustomObject]@{ Setting = "Task Manager"; Status = "Disabled"; Risk = "Prevents you from terminating malicious processes."; FixAction = { Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableTaskMgr" -Force } } }
$uacPolicy = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -ErrorAction SilentlyContinue
if ($uacPolicy -and $uacPolicy.EnableLUA -eq 0) { $tamperedSettings += [PSCustomObject]@{ Setting = "User Account Control (UAC)"; Status = "Disabled"; Risk = "Allows malicious software to gain administrator rights silently."; FixAction = { Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableLUA" -Value 1 } } }
$smartScreenPolicy = Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer" -Name "SmartScreenEnabled" -ErrorAction SilentlyContinue
if ($smartScreenPolicy -and $smartScreenPolicy.SmartScreenEnabled -ne "On") { $tamperedSettings += [PSCustomObject]@{ Setting = "SmartScreen Phishing Filter"; Status = "Off"; Risk = "Increases risk of phishing and malicious downloads."; FixAction = { Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer" -Name "SmartScreenEnabled" -Value "On" } } }
$wuService = Get-Service -Name "wuauserv" -ErrorAction SilentlyContinue
if ($wuService -and $wuService.StartType -eq 'Disabled') { $tamperedSettings += [PSCustomObject]@{ Setting = "Windows Update Service"; Status = "Disabled"; Risk = "Prevents system from receiving critical security updates."; FixAction = { Set-Service -Name "wuauserv" -StartupType Automatic } } }
if ($tamperedSettings) {
Write-Host "`nSuspicious System Policy/Service Changes Found:" -ForegroundColor Cyan; $tamperedSettings | Format-Table -Wrap
if (Confirm-Action "Do you want to REVERT these settings to their secure defaults? (Y/N)") {
Write-Host "Reverting settings..."; $tamperedSettings | ForEach-Object { try { & $_.FixAction; Write-Host " Reverted: $($_.Setting)" -ForegroundColor Green; $actionsTaken.Add("Reverted setting: $($_.Setting)") | Out-Null } catch { Write-Warning " Failed to revert '$($_.Setting)': $_.Exception.Message" } }
} else { Write-Host "Skipping system policy/service changes." }
} else { Write-Host "No disabled system tools or critical services found." -ForegroundColor Green }
Write-Host ""
Write-Host "Scanning HOSTS file for potential network hijacks..."
$hostsFile = "$env:SystemRoot\System32\drivers\etc\hosts"; $suspiciousHostsEntries = Get-Content $hostsFile -ErrorAction SilentlyContinue | Where-Object { $_ -and $_ -notlike '#*' }
if ($suspiciousHostsEntries) {
Write-Host "`nActive Network Redirection Entries Found in HOSTS File:" -ForegroundColor Cyan; $suspiciousHostsEntries | ForEach-Object { Write-Host " - $_" }
Write-Host "`nSECURITY RISK: These entries can redirect you to malicious websites." -ForegroundColor Yellow
if (Confirm-Action "Do you want to NEUTRALIZE these entries? (This is reversible) (Y/N)") {
Write-Host "Neutralizing HOSTS file entries..."; try { $originalContent = Get-Content $hostsFile; $newContent = $originalContent | ForEach-Object { if ($_ -and $_ -notlike '#*') { "# DISABLED BY ORION: $_" } else { $_ } }; $newContent | Set-Content -Path $hostsFile -Force; Write-Host " Successfully neutralized active entries." -ForegroundColor Green; $actionsTaken.Add("Neutralized HOSTS file entries") | Out-Null } catch { Write-Warning " Failed to modify HOSTS file: $_.Exception.Message" }
} else { Write-Host "Skipping HOSTS file modification." }
} else { Write-Host "No active or suspicious HOSTS file entries found." -ForegroundColor Green }
Write-Host ""
Write-Host "Scanning Firewall for suspicious outbound rules..."
$suspiciousFirewallRules = Get-NetFirewallRule -ErrorAction SilentlyContinue | Where-Object { $_.Direction -eq 'Outbound' -and $_.Enabled -eq 'True' -and $_.Action -eq 'Allow' -and $_.Program } | ForEach-Object {
$rule = $_; $appPath = $rule.Program.Replace('"', ''); if ($appPath -and (Test-Path -LiteralPath $appPath)) { if ((Get-AuthenticodeSignature -FilePath $appPath -ErrorAction SilentlyContinue).Status -ne 'Valid') { [PSCustomObject]@{ Name = $rule.DisplayName; Program = $appPath; Reason = "Allows an unsigned program to make outbound connections." } } }
}
if ($suspiciousFirewallRules) {
Write-Host "`nSuspicious Outbound Firewall Rules Found:" -ForegroundColor Cyan; $suspiciousFirewallRules | Format-Table -Wrap
if (Confirm-Action "Do you want to DISABLE these firewall rules? (This is reversible) (Y/N)") {
Write-Host "Disabling firewall rules..."; $suspiciousFirewallRules | ForEach-Object { try { Disable-NetFirewallRule -DisplayName $_.Name; Write-Host " Disabled: $($_.Name)" -ForegroundColor Green; $actionsTaken.Add("Disabled Firewall Rule: $($_.Name)") | Out-Null } catch { Write-Warning " Failed to disable '$($_.Name)': $_.Exception.Message" } }
} else { Write-Host "Skipping firewall rule changes." }
} else { Write-Host "No suspicious outbound firewall rules found." -ForegroundColor Green }
Write-Host ""
Write-Host "Scanning for suspicious Defender exclusions..."
$suspiciousExclusionPaths = @("$env:TEMP", "$env:APPDATA", "$env:PROGRAMDATA", "$env:PUBLIC", "C:\"); $suspiciousExclusions = Get-MpPreference | Select-Object -ExpandProperty ExclusionPath | Where-Object { $exclusion = $_; $isSuspicious = $false; if ([string]::IsNullOrEmpty($exclusion)) { $isSuspicious = $true }; foreach ($path in $suspiciousExclusionPaths) { if ($exclusion -and $exclusion.StartsWith($path, [System.StringComparison]::OrdinalIgnoreCase)) { $isSuspicious = $true; break }}; $isSuspicious }
if ($suspiciousExclusions) {
Write-Host "`nHighly Suspicious Defender Exclusions Found:" -ForegroundColor Cyan; $suspiciousExclusions | ForEach-Object { Write-Host " - $_" }
if (Confirm-Action "Do you want to REMOVE these exclusions? (Y/N)") {
Write-Host "Removing exclusions..."; $suspiciousExclusions | ForEach-Object { try { Remove-MpPreference -ExclusionPath $_; Write-Host " Removed: $_" -ForegroundColor Green; $actionsTaken.Add("Removed Defender Exclusion: $_") | Out-Null } catch { Write-Warning " Failed to remove exclusion for '$_': $_.Exception.Message" } }
} else { Write-Host "Skipping exclusion removal." }
} else { Write-Host "No suspicious Defender exclusions found." -ForegroundColor Green }
Write-Host ""
Write-Host "--- PHASE 5: Proactive System Hygiene ---" -ForegroundColor Yellow
if (Confirm-Action "Do you want to clear common malware locations (Startup folders, Temp files)? (Y/N)") {
Write-Host "Clearing Startup folders..."; $startupFolders = @("$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup", "$env:PROGRAMDATA\Microsoft\Windows\Start Menu\Programs\StartUp"); foreach ($folder in $startupFolders) { if (Test-Path $folder) { try { Get-ChildItem -Path $folder | Remove-Item -Force -Recurse -ErrorAction Stop; Write-Host " Cleared: $folder" -ForegroundColor Green; $actionsTaken.Add("Cleared Startup folder: $folder") | Out-Null } catch { Write-Warning " Failed to clear '$folder': $_.Exception.Message" } } }
Write-Host "Clearing user temporary files..."; if (Test-Path -Path $env:TEMP) { try { Get-ChildItem -Path $env:TEMP -Recurse | Remove-Item -Force -Recurse -ErrorAction Stop; Write-Host " Cleared: $env:TEMP" -ForegroundColor Green; $actionsTaken.Add("Cleared Temp folder: $env:TEMP") | Out-Null } catch { Write-Warning " Failed to clear Temp folder: $_.Exception.Message" } }
} else { Write-Host "Skipping proactive system hygiene." }
if (Confirm-Action "Do you want to PERMANENTLY empty the Recycle Bin? This cannot be undone. (Y/N)") {
try {
Write-Host "Emptying Recycle Bin..."; Clear-RecycleBin -Force -ErrorAction Stop
Write-Host " Recycle Bin emptied." -ForegroundColor Green
$actionsTaken.Add("Emptied Recycle Bin") | Out-Null
} catch { Write-Warning " Failed to empty the Recycle Bin: $_.Exception.Message" }
} else { Write-Host "Skipping Recycle Bin cleanup." }
Write-Host ""
Write-Host "--- PHASE 6: Browser Reset ---" -ForegroundColor Yellow
Write-Host "This step can remove malicious browser extensions and settings."
Write-Host "It will reset Chrome, Edge, and Firefox profiles by renaming their parent folders."
Write-Host "Your bookmarks and passwords should be preserved if you are signed into a browser account." -ForegroundColor Cyan
if (Confirm-Action "Do you want to reset your browsers to their default settings? (Y/N)") {
$browsers = @("chrome", "msedge", "firefox")
foreach ($browser in $browsers) {
try {
Get-Process -Name $browser -ErrorAction Stop | Stop-Process -Force
Write-Host "Closed running $browser processes."
} catch {}
}
$browserPaths = @{
Chrome = "$env:LOCALAPPDATA\Google\Chrome\User Data\Default"
Edge = "$env:LOCALAPPDATA\Microsoft\Edge\User Data\Default"
Firefox = (Get-Item -Path "$env:APPDATA\Mozilla\Firefox\Profiles\*.default-release" -ErrorAction SilentlyContinue).FullName
}
foreach ($browser in $browserPaths.Keys) {
$path = $browserPaths[$browser]
if ($path -and (Test-Path $path)) {
try {
Rename-Item -Path $path -NewName "$path.bak_$(Get-Date -Format 'yyyyMMddHHmmss')" -Force -ErrorAction Stop
Write-Host "Successfully reset $browser profile." -ForegroundColor Green
$actionsTaken.Add("Reset $browser profile") | Out-Null
} catch {
Write-Warning "Could not reset $browser profile. It may be in use. Error: $_.Exception.Message"
}
}
}
} else {
Write-Host "Skipping browser reset."
}
Write-Host ""
Write-Host "--- PHASE 7: System File Integrity Check & Updates ---" -ForegroundColor Yellow
if ($wuService -and $wuService.Status -ne 'Running') {
Write-Host "Windows Update service is not running. Starting it..."
try { Start-Service -Name "wuauserv" -ErrorAction Stop; Write-Host "Windows Update service started." -ForegroundColor Green; $actionsTaken.Add("Started Windows Update service") | Out-Null } catch { Write-Warning "Failed to start Windows Update service: $_.Exception.Message" }
}
if (Confirm-Action "Do you want to check for and install Windows Updates now? (This can take a while)") {
Write-Host "Checking for Windows Updates..."
try {
$updateSession = (New-Object -ComObject 'Microsoft.Update.Session'); $updateSearcher = $updateSession.CreateUpdateSearcher()
$searchResults = $updateSearcher.Search("IsInstalled=0 and Type='Software'")
if ($searchResults.Updates.Count -gt 0) {
Write-Host "$($searchResults.Updates.Count) updates found. Downloading and installing..." -ForegroundColor Cyan
$downloader = $updateSession.CreateUpdateDownloader(); $downloader.Updates = $searchResults.Updates; $downloader.Download()
$installer = $updateSession.CreateUpdateInstaller(); $installer.Updates = $searchResults.Updates; $installResult = $installer.Install()
Write-Host "Update installation result: $($installResult.ResultCode)" -ForegroundColor Green
$actionsTaken.Add("Installed $($searchResults.Updates.Count) Windows Updates") | Out-Null
} else {
Write-Host "Your system is up to date." -ForegroundColor Green
}
} catch { Write-Warning "Failed to run Windows Update check: $_.Exception.Message" }
} else { Write-Host "Skipping Windows Update check." }
Write-Host ""
Write-Host "After a malware infection, it's possible that core system files were corrupted."
Write-Host "This final, optional step will use built-in Windows tools to scan for and repair any damage." -ForegroundColor Cyan
if (Confirm-Action "Do you want to run the System File Integrity Check (DISM & SFC)? (Y/N)") {
try {
Write-Host "`nRunning DISM RestoreHealth to repair the Windows component store..." -ForegroundColor Cyan
dism.exe /online /cleanup-image /restorehealth
Write-Host "DISM scan complete." -ForegroundColor Green
$actionsTaken.Add("Ran DISM RestoreHealth") | Out-Null
} catch {
Write-Warning "DISM command failed. Details: $_.Exception.Message"
}
try {
Write-Host "`nRunning SFC ScanNow to verify and repair system files..." -ForegroundColor Cyan
sfc.exe /scannow
Write-Host "SFC scan complete." -ForegroundColor Green
$actionsTaken.Add("Ran SFC ScanNow") | Out-Null
} catch {
Write-Warning "SFC command failed. Details: $_.Exception.Message"
}
} else {
Write-Host "Skipping System File Integrity Check."
}
Write-Host ""
if ($rebootFiles.Count -gt 0) {
Write-Host "--- Applying Deletions for Locked Files on Reboot ---" -ForegroundColor Yellow
try {
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -Value $rebootFiles.ToArray() -Force
Write-Host "Successfully scheduled locked files for deletion on the next system restart." -ForegroundColor Green
$actionsTaken.Add("Scheduled $($rebootFiles.Count / 2) files for reboot deletion") | Out-Null
} catch {
Write-Warning "Could not set PendingFileRenameOperations registry key. Some files may require manual deletion after reboot: $_.Exception.Message"
}
}
Write-Host "================================================================" -ForegroundColor Green
Write-Host " Orion Remediation Script Finished" -ForegroundColor Green
Write-Host "================================================================" -ForegroundColor Green
if ($actionsTaken.Count -gt 0) {
Write-Host "`nSummary of Actions Taken:" -ForegroundColor Cyan
$actionsTaken | ForEach-Object { Write-Host " - $_" }
} else {
Write-Host "`nNo changes were made to the system." -ForegroundColor Yellow
}
Write-Host ""
Read-Host "Press Enter to exit..."
Stop-Transcript
Last edited:



