Gorstaks Antivirus
unknown
powershell
3 months ago
30 kB
11
No Index
# Antivirus.ps1
# Author: Gorstak
# Define paths and parameters
$taskName = "Antivirus"
$taskDescription = "Runs the Simple Antivirus script at user logon with admin privileges."
$scriptDir = "C:\Windows\Setup\Scripts\Bin"
$scriptPath = "$scriptDir\Antivirus.ps1"
$quarantineFolder = "C:\Quarantine"
$logFile = "$quarantineFolder\antivirus_log.txt"
$localDatabase = "$quarantineFolder\scanned_files.txt"
$scannedFiles = @{} # Initialize empty hash table
# Check admin privileges
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
Write-Host "Running as admin: $isAdmin"
# Logging Function with Rotation
function Write-Log {
param ([string]$message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "[$timestamp] $message"
Write-Host "Logging: $logEntry"
if (-not (Test-Path $quarantineFolder)) {
New-Item -Path $quarantineFolder -ItemType Directory -Force -ErrorAction Stop | Out-Null
Write-Host "Created folder: $quarantineFolder"
}
if ((Test-Path $logFile) -and ((Get-Item $logFile -ErrorAction SilentlyContinue).Length -ge 10MB)) {
$archiveName = "$quarantineFolder\antivirus_log_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
Rename-Item -Path $logFile -NewName $archiveName -ErrorAction Stop
Write-Host "Rotated log to: $archiveName"
}
$logEntry | Out-File -FilePath $logFile -Append -Encoding UTF8 -ErrorAction Stop
}
# Initial log with diagnostics
Write-Log "Script initialized. Admin: $isAdmin, User: $env:USERNAME, SID: $([Security.Principal.WindowsIdentity]::GetCurrent().User.Value)"
# Ensure execution policy allows script
if ((Get-ExecutionPolicy) -eq "Restricted") {
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force -ErrorAction SilentlyContinue
Write-Log "Set execution policy to Bypass for current user."
}
# Load or Reset Scanned Files Database
if (Test-Path $localDatabase) {
try {
$scannedFiles.Clear() # Reset hash table before loading
$lines = Get-Content $localDatabase -ErrorAction Stop
foreach ($line in $lines) {
if ($line -match "^([0-9a-f]{64}),(true|false)$") {
$scannedFiles[$matches[1]] = [bool]$matches[2]
}
}
Write-Log "Loaded $($scannedFiles.Count) scanned file entries from database."
} catch {
Write-Log "Failed to load database: $($_.Exception.Message)"
$scannedFiles.Clear() # Reset on failure
}
} else {
$scannedFiles.Clear() # Ensure reset if no database
New-Item -Path $localDatabase -ItemType File -Force -ErrorAction Stop | Out-Null
Write-Log "Created new database: $localDatabase"
}
# Take Ownership and Modify Permissions (Aggressive)
function Set-FileOwnershipAndPermissions {
param ([string]$filePath)
try {
takeown /F $filePath /A | Out-Null
icacls $filePath /reset | Out-Null
icacls $filePath /grant "Administrators:F" /inheritance:d | Out-Null
Write-Log "Forcibly set ownership and permissions for $filePath"
return $true
} catch {
Write-Log "Failed to set ownership/permissions for ${filePath}: $($_.Exception.Message)"
return $false
}
}
# Calculate File Hash and Signature
function Calculate-FileHash {
param ([string]$filePath)
try {
$signature = Get-AuthenticodeSignature -FilePath $filePath -ErrorAction Stop
$hash = Get-FileHash -Path $filePath -Algorithm SHA256 -ErrorAction Stop
Write-Log "Signature status for ${filePath}: $($signature.Status) - $($signature.StatusMessage)"
return [PSCustomObject]@{
Hash = $hash.Hash.ToLower()
Status = $signature.Status
StatusMessage = $signature.StatusMessage
}
} catch {
Write-Log "Error processing ${filePath}: $($_.Exception.Message)"
return $null
}
}
# Quarantine File (Crash-Proof)
function Quarantine-File {
param ([string]$filePath)
try {
$quarantinePath = Join-Path -Path $quarantineFolder -ChildPath (Split-Path $filePath -Leaf)
Move-Item -Path $filePath -Destination $quarantinePath -Force -ErrorAction Stop
Write-Log "Quarantined file: $filePath to $quarantinePath"
} catch {
Write-Log "Failed to quarantine ${filePath}: $($_.Exception.Message)"
}
}
# Stop Processes Using DLL (Aggressive)
function Stop-ProcessUsingDLL {
param ([string]$filePath)
try {
$processes = Get-Process | Where-Object { ($_.Modules | Where-Object { $_.FileName -eq $filePath }) }
foreach ($process in $processes) {
Stop-Process -Id $process.Id -Force -ErrorAction Stop
Write-Log "Stopped process $($process.Name) (PID: $($process.Id)) using $filePath"
}
} catch {
Write-Log "Error stopping processes for ${filePath}: $($_.Exception.Message)"
try {
$processes = Get-Process | Where-Object { ($_.Modules | Where-Object { $_.FileName -eq $filePath }) }
foreach ($process in $processes) {
taskkill /PID $process.Id /F | Out-Null
Write-Log "Force-killed process $($process.Name) (PID: $($process.Id)) using taskkill"
}
} catch {
Write-Log "Fallback process kill failed for ${filePath}: $($_.Exception.Message)"
}
}
}
function Should-ExcludeFile {
param ([string]$filePath)
$lowerPath = $filePath.ToLower()
# Exclude assembly folders
if ($lowerPath -like "*\assembly\*") {
Write-Log "Excluding assembly folder file: $filePath"
return $true
}
# Exclude ctfmon-related files
if ($lowerPath -like "*ctfmon*" -or $lowerPath -like "*msctf.dll" -or $lowerPath -like "*msutb.dll") {
Write-Log "Excluding ctfmon-related file: $filePath"
return $true
}
return $false
}
# Remove Unsigned DLLs (Exclude Problem Folders)
function Remove-UnsignedDLLs {
Write-Log "Starting unsigned DLL/WINMD scan."
$drives = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DriveType -in (2, 3, 4) }
foreach ($drive in $drives) {
$root = $drive.DeviceID + "\"
Write-Log "Scanning drive: $root"
try {
$dllFiles = Get-ChildItem -Path $root -Include *.dll,*.winmd -Recurse -File -Exclude @($quarantineFolder, "C:\Windows\System32\config") -ErrorAction Stop
foreach ($dll in $dllFiles) {
try {
if (Should-ExcludeFile -filePath $dll.FullName) {
continue
}
$fileHash = Calculate-FileHash -filePath $dll.FullName
if ($fileHash) {
if ($scannedFiles.ContainsKey($fileHash.Hash)) {
Write-Log "Skipping already scanned file: $($dll.FullName) (Hash: $($fileHash.Hash))"
if (-not $scannedFiles[$fileHash.Hash]) {
if (Set-FileOwnershipAndPermissions -filePath $dll.FullName) {
Stop-ProcessUsingDLL -filePath $dll.FullName
Quarantine-File -filePath $dll.FullName
}
}
} else {
$isValid = $fileHash.Status -eq "Valid" # Only "Valid" is safe
$scannedFiles[$fileHash.Hash] = $isValid
"$($fileHash.Hash),$isValid" | Out-File -FilePath $localDatabase -Append -Encoding UTF8 -ErrorAction Stop
Write-Log "Scanned new file: $($dll.FullName) (Valid: $isValid)"
if (-not $isValid) {
if (Set-FileOwnershipAndPermissions -filePath $dll.FullName) {
Stop-ProcessUsingDLL -filePath $dll.FullName
Quarantine-File -filePath $dll.FullName
}
}
}
}
} catch {
Write-Log "Error processing file $($dll.FullName): $($_.Exception.Message)"
}
}
} catch {
Write-Log "Scan failed for drive ${root} $($_.Exception.Message)"
}
}
# Explicit System32 Scan
Write-Log "Starting explicit System32 scan."
try {
$system32Files = Get-ChildItem -Path "C:\Windows\System32" -Include *.dll,*.winmd -File -ErrorAction Stop
foreach ($dll in $system32Files) {
try {
if (Should-ExcludeFile -filePath $dll.FullName) {
continue
}
$fileHash = Calculate-FileHash -filePath $dll.FullName
if ($fileHash) {
if ($scannedFiles.ContainsKey($fileHash.Hash)) {
Write-Log "Skipping already scanned System32 file: $($dll.FullName) (Hash: $($fileHash.Hash))"
if (-not $scannedFiles[$fileHash.Hash]) {
if (Set-FileOwnershipAndPermissions -filePath $dll.FullName) {
Stop-ProcessUsingDLL -filePath $dll.FullName
Quarantine-File -filePath $dll.FullName
}
}
} else {
$isValid = $fileHash.Status -eq "Valid"
$scannedFiles[$fileHash.Hash] = $isValid
"$($fileHash.Hash),$isValid" | Out-File -FilePath $localDatabase -Append -Encoding UTF8 -ErrorAction Stop
Write-Log "Scanned new System32 file: $($dll.FullName) (Valid: $isValid)"
if (-not $isValid) {
if (Set-FileOwnershipAndPermissions -filePath $dll.FullName) {
Stop-ProcessUsingDLL -filePath $dll.FullName
Quarantine-File -filePath $dll.FullName
}
}
}
}
} catch {
Write-Log "Error processing System32 file $($dll.FullName): $($_.Exception.Message)"
}
}
} catch {
Write-Log "System32 scan failed: $($_.Exception.Message)"
}
}
# File System Watcher (Throttled and Crash-Proof)
$drives = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DriveType -in (2, 3, 4) }
foreach ($drive in $drives) {
$monitorPath = $drive.DeviceID + "\"
try {
$fileWatcher = New-Object System.IO.FileSystemWatcher
$fileWatcher.Path = $monitorPath
$fileWatcher.Filter = "*.*"
$fileWatcher.IncludeSubdirectories = $true
$fileWatcher.EnableRaisingEvents = $true
$fileWatcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor [System.IO.NotifyFilters]::LastWrite
$action = {
param($sender, $e)
try {
if ($e.ChangeType -in "Created", "Changed" -and $e.FullPath -notlike "$quarantineFolder*" -and ($e.FullPath -like "*.dll" -or $e.FullPath -like "*.winmd")) {
if (Should-ExcludeFile -filePath $e.FullPath) {
return
}
Write-Log "Detected file change: $($e.FullPath)"
$fileHash = Calculate-FileHash -filePath $e.FullPath
if ($fileHash) {
if ($scannedFiles.ContainsKey($fileHash.Hash)) {
Write-Log "Skipping already scanned file: $($e.FullPath) (Hash: $($fileHash.Hash))"
if (-not $scannedFiles[$fileHash.Hash]) {
if (Set-FileOwnershipAndPermissions -filePath $e.FullPath) {
Stop-ProcessUsingDLL -filePath $e.FullPath
Quarantine-File -filePath $e.FullPath
}
}
} else {
$isValid = $fileHash.Status -eq "Valid"
$scannedFiles[$fileHash.Hash] = $isValid
"$($fileHash.Hash),$isValid" | Out-File -FilePath $localDatabase -Append -Encoding UTF8 -ErrorAction Stop
Write-Log "Added new file to database: $($e.FullPath) (Valid: $isValid)"
if (-not $isValid) {
if (Set-FileOwnershipAndPermissions -filePath $e.FullPath) {
Stop-ProcessUsingDLL -filePath $e.FullPath
Quarantine-File -filePath $e.FullPath
}
}
}
}
Start-Sleep -Milliseconds 500 # Throttle to prevent event flood
}
} catch {
Write-Log "Watcher error for $($e.FullPath): $($_.Exception.Message)"
}
}
Register-ObjectEvent -InputObject $fileWatcher -EventName Created -Action $action -ErrorAction Stop
Register-ObjectEvent -InputObject $fileWatcher -EventName Changed -Action $action -ErrorAction Stop
Write-Log "FileSystemWatcher set up for $monitorPath"
} catch {
Write-Log "Failed to set up watcher for ${monitorPath} $($_.Exception.Message)"
}
}
$ApiConfig = @{
CirclHashLookupUrl = "https://hashlookup.circl.lu/lookup/sha256"
CymruApiUrl = "https://api.malwarehash.cymru.com/v1/hash"
MalwareBazaarApiUrl = "https://mb-api.abuse.ch/api/v1/"
}
# ============================================
# ============================================
function Check-FileHash {
param(
[string]$FilePath,
[string]$ProcessName,
[int]$ProcessId
)
try {
if (-not (Test-Path $FilePath)) {
Write-Log "[HASH] File not found for hash check: $FilePath"
return $false
}
$hash = (Get-FileHash -Path $FilePath -Algorithm SHA256).Hash
Write-Log "[HASH] Checking hash for $ProcessName (PID: $ProcessId): $hash"
$isMalicious = $false
# Check CIRCL Hash Lookup
try {
$circlUrl = "$($ApiConfig.CirclHashLookupUrl)/$hash"
$circlResponse = Invoke-RestMethod -Uri $circlUrl -Method Get -TimeoutSec 5 -ErrorAction Stop
if ($circlResponse -and $circlResponse.KnownMalicious) {
Write-Log "[HASH] CIRCL reports malicious: $ProcessName"
$isMalicious = $true
}
} catch {
Write-Log "[HASH] CIRCL lookup failed or no result"
}
# Check Team Cymru
try {
$cymruUrl = "$($ApiConfig.CymruApiUrl)/$hash"
$cymruResponse = Invoke-RestMethod -Uri $cymruUrl -Method Get -TimeoutSec 5 -ErrorAction Stop
if ($cymruResponse -and $cymruResponse.malicious -eq $true) {
Write-Log "[HASH] Cymru reports malicious: $ProcessName"
$isMalicious = $true
}
} catch {
Write-Log "[HASH] Cymru lookup failed or no result"
}
# Check MalwareBazaar
try {
$mbBody = @{ query = "get_info"; hash = $hash } | ConvertTo-Json
$mbResponse = Invoke-RestMethod -Uri $ApiConfig.MalwareBazaarApiUrl -Method Post -Body $mbBody -ContentType "application/json" -TimeoutSec 5 -ErrorAction Stop
if ($mbResponse -and $mbResponse.query_status -eq "ok") {
Write-Log "[HASH] MalwareBazaar reports known malware: $ProcessName"
$isMalicious = $true
}
} catch {
Write-Log "[HASH] MalwareBazaar lookup failed or no result"
}
return $isMalicious
} catch {
Write-Log "[HASH] Error during hash check: $_"
return $false
}
}
# ============================================
# ============================================
function Kill-Threat {
param(
[int]$ProcessId,
[string]$ProcessName,
[string]$Reason
)
try {
if (Get-Process -Id $ProcessId -ErrorAction SilentlyContinue) {
Write-Log "[KILL] Terminating process: $ProcessName (PID: $ProcessId) - Reason: $Reason"
Stop-Process -Id $ProcessId -Force -ErrorAction Stop
Write-Log "[KILL] Successfully terminated PID: $ProcessId"
return $true
} else {
Write-Log "[KILL] Process already terminated: PID $ProcessId"
return $false
}
} catch {
Write-Log "[KILL] Failed to terminate PID $ProcessId : $_"
return $false
}
}
# ============================================
# ============================================
# ============================================
# FILELESS MALWARE DETECTION
# ============================================
function Detect-FilelessMalware {
# Monitor for common fileless techniques
$filelessIndicators = @{
"PowerShellWithoutFile" = {
Get-Process -Name powershell -ErrorAction SilentlyContinue |
Where-Object {
$_.MainWindowTitle -match "encodedcommand|enc|iex|invoke-expression" -or
$_.Modules | Where-Object {
$_.ModuleName -eq "" -or $_.FileName -eq ""
}
}
}
"WMIEventSubscriptions" = {
Get-WmiObject -Namespace root\Subscription -Class __EventFilter -ErrorAction SilentlyContinue |
Where-Object { $_.Query -match "powershell|vbscript|javascript" }
}
"RegistryScripts" = {
$suspiciousKeys = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
)
$results = @()
foreach ($key in $suspiciousKeys) {
if (Test-Path $key) {
Get-ItemProperty -Path $key -ErrorAction SilentlyContinue | ForEach-Object {
$_.PSObject.Properties | Where-Object {
$_.Value -match "powershell.*-enc|mshta|regsvr32.*scrobj"
} | ForEach-Object {
$results += $_
}
}
}
}
return $results
}
}
$detections = @()
foreach ($indicator in $filelessIndicators.Keys) {
$results = & $filelessIndicators[$indicator]
if ($results) {
$detections += [PSCustomObject]@{
Indicator = $indicator
Details = $results
}
Write-Log "[ALERT] Fileless malware detected: $indicator"
if ($indicator -eq "PowerShellWithoutFile") {
foreach ($proc in $results) {
# Check hash if file path exists
if ($proc.Path) {
$hashMalicious = Check-FileHash -FilePath $proc.Path -ProcessName $proc.Name -ProcessId $proc.Id
if ($hashMalicious) {
Quarantine-File -FilePath $proc.Path
}
}
Kill-Threat -ProcessId $proc.Id -ProcessName $proc.Name -Reason "Fileless PowerShell execution"
}
}
elseif ($indicator -eq "WMIEventSubscriptions") {
foreach ($subscription in $results) {
try {
Write-Log "[ACTION] Removing malicious WMI event filter: $($subscription.Name)"
Remove-WmiObject -InputObject $subscription -ErrorAction Stop
# Also remove associated consumers and bindings
$consumers = Get-WmiObject -Namespace root\Subscription -Class __EventConsumer -Filter "Name='$($subscription.Name)'" -ErrorAction SilentlyContinue
$bindings = Get-WmiObject -Namespace root\Subscription -Class __FilterToConsumerBinding -Filter "Filter='$($subscription.__RELPATH)'" -ErrorAction SilentlyContinue
foreach ($consumer in $consumers) {
Remove-WmiObject -InputObject $consumer -ErrorAction SilentlyContinue
Write-Log "[ACTION] Removed associated WMI consumer: $($consumer.Name)"
}
foreach ($binding in $bindings) {
Remove-WmiObject -InputObject $binding -ErrorAction SilentlyContinue
Write-Log "[ACTION] Removed WMI binding"
}
} catch {
Write-Log "[ERROR] Failed to remove WMI subscription: $_"
}
}
}
elseif ($indicator -eq "RegistryScripts") {
foreach ($regEntry in $results) {
try {
$keyPath = $regEntry.PSPath
$valueName = $regEntry.Name
Write-Log "[ACTION] Removing malicious registry entry: $keyPath\$valueName"
Remove-ItemProperty -Path $keyPath -Name $valueName -Force -ErrorAction Stop
} catch {
Write-Log "[ERROR] Failed to remove registry entry: $_"
}
}
}
}
}
return $detections
}
# ============================================
# MEMORY SCANNER
# ============================================
$Base = $quarantineFolder
Write-Log "[+] Starting PowerShell memory scanner"
Start-Job -ScriptBlock {
$log = "$using:Base\ps_memory_hits.log"
$quarantineFolder = $using:quarantineFolder
$Base = $using:Base
${function:Check-FileHash} = ${using:function:Check-FileHash}
${function:Kill-Threat} = ${using:function:Kill-Threat}
${function:Quarantine-File} = ${using:function:Quarantine-File}
${function:Write-Log} = ${using:function:Write-Log}
$ApiConfig = $using:ApiConfig
$EvilStrings = @(
'mimikatz','sekurlsa::','kerberos::','lsadump::','wdigest','tspkg',
'http-beacon','https-beacon','cobaltstrike','sleepmask','reflective',
'amsi.dll','AmsiScanBuffer','EtwEventWrite','MiniDumpWriteDump',
'VirtualAllocEx','WriteProcessMemory','CreateRemoteThread',
'ReflectiveLoader','sharpchrome','rubeus','safetykatz','sharphound'
)
while ($true) {
Start-Sleep -Seconds 2
Get-Process | Where-Object {
$_.WorkingSet64 -gt 100MB -or $_.Name -match 'powershell|wscript|cscript|mshta|rundll32|regsvr32|msbuild|cmstp|excel|word|outlook'
} | ForEach-Object {
$hit = $false
try {
$_.Modules | ForEach-Object {
if ($EvilStrings | Where-Object { $_.ModuleName -match $_ -or $_.FileName -match $_ }) {
$hit = $true
}
}
} catch {}
if ($hit) {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | PS MEMORY HIT → $($_.Name) ($($_.Id))" | Out-File $log -Append
if ($_.Path) {
$hashMalicious = Check-FileHash -FilePath $_.Path -ProcessName $_.Name -ProcessId $_.Id
if ($hashMalicious) {
Quarantine-File -FilePath $_.Path
}
}
Kill-Threat -ProcessId $_.Id -ProcessName $_.Name -Reason "Malicious strings in memory"
}
}
}
} | Out-Null
# ============================================
# REFLECTIVE PAYLOAD DETECTOR
# ============================================
Write-Log "[+] Starting reflective payload detector"
Start-Job -ScriptBlock {
$log = "$using:Base\manual_map_hits.log"
$quarantineFolder = $using:quarantineFolder
$Base = $using:Base
${function:Check-FileHash} = ${using:function:Check-FileHash}
${function:Kill-Threat} = ${using:function:Kill-Threat}
${function:Quarantine-File} = ${using:function:Quarantine-File}
${function:Write-Log} = ${using:function:Write-Log}
$ApiConfig = $using:ApiConfig
while ($true) {
Start-Sleep -Seconds 2
Get-Process | Where-Object { $_.WorkingSet64 -gt 40MB } | ForEach-Object {
$p = $_
$sus = $false
if (-not $p.Path -or $p.Path -eq '' -or $p.Path -match '$$Unknown$$') { $sus = $true }
if ($p.Modules | Where-Object { $_.FileName -eq '' -or $_.ModuleName -eq '' }) { $sus = $true }
if ($sus) {
"$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | REFLECTIVE PAYLOAD → $($p.Name) ($($p.Id)) Path='$($p.Path)'" | Out-File $log -Append
if ($p.Path) {
$hashMalicious = Check-FileHash -FilePath $p.Path -ProcessName $p.Name -ProcessId $p.Id
if ($hashMalicious) {
Quarantine-File -FilePath $p.Path
}
}
Kill-Threat -ProcessId $p.Id -ProcessName $p.Name -Reason "Reflective payload detected"
}
}
}
} | Out-Null
# ============================================
# BEHAVIOR MONITOR
# ============================================
function Start-BehaviorMonitor {
$suspiciousBehaviors = @{
"ProcessHollowing" = {
param($Process)
# Check for process hollowing indicators
$procPath = $Process.Path
$modules = Get-Process -Id $Process.Id -Module -ErrorAction SilentlyContinue
return ($modules -and $procPath -and ($modules[0].FileName -ne $procPath))
}
"CredentialAccess" = {
param($Process)
# Check for credential dumping tools
$cmdline = (Get-CimInstance Win32_Process -Filter "ProcessId=$($Process.Id)" -ErrorAction SilentlyContinue).CommandLine
return ($cmdline -match "mimikatz|procdump|sekurlsa|lsadump" -or
$Process.ProcessName -match "vaultcmd|cred")
}
"LateralMovement" = {
param($Process)
# Detect lateral movement attempts
$connections = Get-NetTCPConnection -OwningProcess $Process.Id -ErrorAction SilentlyContinue
$remoteIPs = $connections | Where-Object {
$_.RemoteAddress -notmatch "^(127\.|192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)" -and
$_.RemoteAddress -ne "0.0.0.0" -and
$_.RemoteAddress -ne "::"
}
return ($remoteIPs.Count -gt 5)
}
}
Start-Job -ScriptBlock {
$behaviors = $using:suspiciousBehaviors
$logFile = "$using:Base\behavior_detections.log"
$Base = $using:Base
$quarantineFolder = $using:quarantineFolder
${function:Check-FileHash} = ${using:function:Check-FileHash}
${function:Kill-Threat} = ${using:function:Kill-Threat}
${function:Quarantine-File} = ${using:function:Quarantine-File}
${function:Write-Log} = ${using:function:Write-Log}
$ApiConfig = $using:ApiConfig
while ($true) {
Start-Sleep -Seconds 5
Get-Process | ForEach-Object {
$process = $_
foreach ($behavior in $behaviors.Keys) {
try {
if (& $behaviors[$behavior] $process) {
$msg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | BEHAVIOR DETECTED: $behavior | " +
"Process: $($process.Name) PID: $($process.Id) " +
"Path: $($process.Path)"
$msg | Out-File $logFile -Append
if ($behavior -in @("ProcessHollowing", "CredentialAccess")) {
if ($process.Path) {
$hashMalicious = Check-FileHash -FilePath $process.Path -ProcessName $process.Name -ProcessId $process.Id
if ($hashMalicious) {
Quarantine-File -FilePath $process.Path
}
}
Kill-Threat -ProcessId $process.Id -ProcessName $process.Name -Reason "Suspicious behavior: $behavior"
}
}
} catch {
# Silently continue on errors
}
}
}
}
} | Out-Null
}
Write-Log "[+] Starting behavior monitor"
# Initial scan
Remove-UnsignedDLLs
Start-BehaviorMonitor
Write-Log "Initial scan completed. Monitoring started."
# Keep script running with crash protection
Write-Host "Antivirus running. Press [Ctrl] + [C] to stop."
try {
while ($true) {
# Run fileless malware detection every 10 seconds
Start-Sleep -Seconds 10
Detect-FilelessMalware | Out-Null
}
} finally {
# Cleanup on exit
Write-Log "=== Stopping detection modules ==="
Get-Job | Stop-Job
Get-Job | Remove-Job
Write-Log "=== Detection stopped ==="
}
Editor is loading...
Leave a Comment