SEVEN.LEGEND // V4
Users Online: 1
Total Hits: 8,856
CODES // DATA STREAM
SECURITY CODE & SCRIPTS « BACK
Detection Script for BatShadow/Vampire Bot
POWERSHELL
PowerShell script for detecting and remediating BatShadow threat actor's Vampire Bot malware. Based on threat intelligence from Aryaka Threat Research Labs (October 2025). Scans for malicious files, suspicious processes, C2 connections, registry persistence, and provides automated remediation capabilities.
ID: BatShadow // LANG: Powershell // LINES: 508
#Requires -RunAsAdministrator

<#
.SYNOPSIS
    Detection and remediation script for BatShadow/Vampire Bot malware
    
.DESCRIPTION
    This script detects and attempts to remediate BatShadow threat actor's Vampire Bot malware
    Based on threat intelligence from Aryaka Threat Research Labs (October 2025)
    
.NOTES
    Version: 1.0
    Author: Security Operations
    Requires: Administrator privileges
    
.LINK
    https://www.aryaka.com/blog/batshade-vampire-bot-social-engineering-malware/
#>

# Configuration
$LogPath = "$env:SystemRoot\Temp\BatShadow-Detection-$(Get-Date -Format 'yyyyMMdd-HHmmss').log"
$QuarantinePath = "$env:SystemRoot\Temp\Quarantine-$(Get-Date -Format 'yyyyMMdd-HHmmss')"

# Known IOCs based on threat intelligence
$IOCs = @{
    C2Domains = @(
        'api3.samsungcareers.work',
        'samsungcareers.work',
        'samsung-work.com',
        'marriott-careers.work'
    )
    MaliciousIPs = @(
        '103.124.95.161'
    )
    SuspiciousProcesses = @(
        'XtraViewer',
        'XVDesktop',
        'microsoftedge',
        'chrome'
    )
    FileIndicators = @{
        Extensions = @('.lnk', '.exe', '.zip')
        SuspiciousNames = @(
            '*job*description*.pdf.exe',
            '*job*description*.lnk',
            '*Marketing*Manager*.exe',
            '*Marriott*.lnk',
            '*Samsung*.lnk',
            'XtraViewer*'
        )
    }
    RegistryKeys = @(
        'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run',
        'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run',
        'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce',
        'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce'
    )
}

# Detection results
$DetectionResults = @{
    MaliciousFiles = @()
    SuspiciousProcesses = @()
    NetworkConnections = @()
    RegistryEntries = @()
    HostFileEntries = @()
    MutexObjects = @()
    ScreenshotFiles = @()
}

# Logging function
function Write-Log {
    param(
        [string]$Message,
        [ValidateSet('Info','Warning','Error','Success')]
        [string]$Level = 'Info'
    )
    
    $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
    $logMessage = "[$timestamp] [$Level] $Message"
    Add-Content -Path $LogPath -Value $logMessage
    
    switch($Level) {
        'Info'    { Write-Host $logMessage -ForegroundColor Cyan }
        'Warning' { Write-Host $logMessage -ForegroundColor Yellow }
        'Error'   { Write-Host $logMessage -ForegroundColor Red }
        'Success' { Write-Host $logMessage -ForegroundColor Green }
    }
}

# Banner
function Show-Banner {
    Write-Host "`n========================================" -ForegroundColor Cyan
    Write-Host "  BatShadow/Vampire Bot Detector v1.0" -ForegroundColor Cyan
    Write-Host "  Threat Intelligence: Aryaka Labs" -ForegroundColor Cyan
    Write-Host "========================================`n" -ForegroundColor Cyan
}

# Check 1: Scan for malicious files
function Find-MaliciousFiles {
    Write-Log "Scanning for suspicious files..." -Level Info
    
    $searchPaths = @(
        $env:TEMP,
        $env:USERPROFILE + '\Downloads',
        $env:USERPROFILE + '\Desktop',
        $env:APPDATA,
        $env:LOCALAPPDATA,
        "$env:SystemRoot\System32",
        "$env:ProgramData"
    )
    
    foreach ($path in $searchPaths) {
        if (Test-Path $path) {
            foreach ($pattern in $IOCs.FileIndicators.SuspiciousNames) {
                try {
                    $files = Get-ChildItem -Path $path -Filter $pattern -Recurse -ErrorAction SilentlyContinue -Force
                    foreach ($file in $files) {
                        $DetectionResults.MaliciousFiles += [PSCustomObject]@{
                            Path = $file.FullName
                            Name = $file.Name
                            Size = $file.Length
                            Created = $file.CreationTime
                            Modified = $file.LastWriteTime
                            Hash = (Get-FileHash -Path $file.FullName -Algorithm SHA256 -ErrorAction SilentlyContinue).Hash
                        }
                        Write-Log "FOUND: Suspicious file - $($file.FullName)" -Level Warning
                    }
                } catch {
                    Write-Log "Error scanning $path : $_" -Level Error
                }
            }
        }
    }
    
    # Look for WEBP screenshot files (Vampire Bot behavior)
    try {
        $webpFiles = Get-ChildItem -Path $env:TEMP -Filter "*.webp" -Recurse -ErrorAction SilentlyContinue -Force | 
            Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) }
        
        if ($webpFiles) {
            $DetectionResults.ScreenshotFiles += $webpFiles
            Write-Log "FOUND: Recent WEBP files (possible screenshots) - Count: $($webpFiles.Count)" -Level Warning
        }
    } catch {
        Write-Log "Error scanning for WEBP files: $_" -Level Error
    }
}

# Check 2: Identify suspicious processes
function Find-SuspiciousProcesses {
    Write-Log "Checking for suspicious running processes..." -Level Info
    
    $processes = Get-Process -ErrorAction SilentlyContinue
    
    foreach ($proc in $processes) {
        # Check against known suspicious process names
        foreach ($suspName in $IOCs.SuspiciousProcesses) {
            if ($proc.ProcessName -like "*$suspName*") {
                try {
                    $procInfo = [PSCustomObject]@{
                        Name = $proc.ProcessName
                        PID = $proc.Id
                        Path = $proc.Path
                        CommandLine = (Get-CimInstance Win32_Process -Filter "ProcessId = $($proc.Id)" -ErrorAction SilentlyContinue).CommandLine
                        StartTime = $proc.StartTime
                    }
                    $DetectionResults.SuspiciousProcesses += $procInfo
                    Write-Log "FOUND: Suspicious process - $($proc.ProcessName) (PID: $($proc.Id))" -Level Warning
                } catch {}
            }
        }
        
        # Check for Go-compiled executables (Vampire Bot is Go-based)
        if ($proc.Path) {
            try {
                $fileContent = [System.IO.File]::ReadAllText($proc.Path)
                if ($fileContent -match 'golang|Go build ID|runtime.main') {
                    Write-Log "FOUND: Go-based executable - $($proc.Path)" -Level Warning
                    $DetectionResults.SuspiciousProcesses += [PSCustomObject]@{
                        Name = $proc.ProcessName
                        PID = $proc.Id
                        Path = $proc.Path
                        Reason = "Go-based executable"
                    }
                }
            } catch {}
        }
    }
}

# Check 3: Network connections to C2
function Find-C2Connections {
    Write-Log "Checking network connections to known C2 servers..." -Level Info
    
    try {
        $connections = Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue
        
        foreach ($conn in $connections) {
            # Check against known malicious IPs
            if ($IOCs.MaliciousIPs -contains $conn.RemoteAddress) {
                $DetectionResults.NetworkConnections += [PSCustomObject]@{
                    LocalAddress = $conn.LocalAddress
                    LocalPort = $conn.LocalPort
                    RemoteAddress = $conn.RemoteAddress
                    RemotePort = $conn.RemotePort
                    State = $conn.State
                    OwningProcess = (Get-Process -Id $conn.OwningProcess -ErrorAction SilentlyContinue).ProcessName
                }
                Write-Log "FOUND: Connection to malicious IP - $($conn.RemoteAddress)" -Level Warning
            }
        }
        
        # Check DNS cache for C2 domains
        $dnsCache = Get-DnsClientCache -ErrorAction SilentlyContinue
        foreach ($entry in $dnsCache) {
            foreach ($domain in $IOCs.C2Domains) {
                if ($entry.Name -like "*$domain*") {
                    Write-Log "FOUND: DNS cache entry for C2 domain - $($entry.Name)" -Level Warning
                    $DetectionResults.NetworkConnections += [PSCustomObject]@{
                        Type = "DNS"
                        Domain = $entry.Name
                        IPAddress = $entry.Data
                    }
                }
            }
        }
    } catch {
        Write-Log "Error checking network connections: $_" -Level Error
    }
}

# Check 4: Registry persistence
function Find-RegistryPersistence {
    Write-Log "Scanning registry for persistence mechanisms..." -Level Info
    
    foreach ($regPath in $IOCs.RegistryKeys) {
        if (Test-Path $regPath) {
            try {
                $entries = Get-ItemProperty -Path $regPath -ErrorAction SilentlyContinue
                
                foreach ($prop in $entries.PSObject.Properties) {
                    if ($prop.Name -notin @('PSPath','PSParentPath','PSChildName','PSDrive','PSProvider')) {
                        # Check for suspicious patterns
                        $value = $prop.Value
                        
                        if ($value -match 'samsung|marriott|job.*description|XtraViewer|\.lnk|powershell.*-enc|powershell.*-w hidden') {
                            $DetectionResults.RegistryEntries += [PSCustomObject]@{
                                Path = $regPath
                                Name = $prop.Name
                                Value = $value
                            }
                            Write-Log "FOUND: Suspicious registry entry - $regPath\$($prop.Name)" -Level Warning
                        }
                    }
                }
            } catch {
                Write-Log "Error scanning registry path $regPath : $_" -Level Error
            }
        }
    }
    
    # Check scheduled tasks
    Write-Log "Checking scheduled tasks..." -Level Info
    try {
        $tasks = Get-ScheduledTask -ErrorAction SilentlyContinue | Where-Object {
            $_.TaskName -like "*samsung*" -or 
            $_.TaskName -like "*marriott*" -or
            $_.TaskName -like "*XtraViewer*"
        }
        
        foreach ($task in $tasks) {
            Write-Log "FOUND: Suspicious scheduled task - $($task.TaskName)" -Level Warning
            $DetectionResults.RegistryEntries += [PSCustomObject]@{
                Type = "ScheduledTask"
                Name = $task.TaskName
                Path = $task.TaskPath
                State = $task.State
            }
        }
    } catch {
        Write-Log "Error checking scheduled tasks: $_" -Level Error
    }
}

# Check 5: Host file manipulation
function Check-HostsFile {
    Write-Log "Checking hosts file for suspicious entries..." -Level Info
    
    $hostsPath = "$env:SystemRoot\System32\drivers\etc\hosts"
    
    if (Test-Path $hostsPath) {
        $hostsContent = Get-Content $hostsPath
        
        foreach ($line in $hostsContent) {
            foreach ($domain in $IOCs.C2Domains) {
                if ($line -match $domain) {
                    $DetectionResults.HostFileEntries += $line
                    Write-Log "FOUND: Suspicious hosts file entry - $line" -Level Warning
                }
            }
        }
    }
}

# Check 6: PowerShell execution policy and recent commands
function Check-PowerShellActivity {
    Write-Log "Checking PowerShell activity..." -Level Info
    
    # Check PowerShell history
    $historyPath = "$env:APPDATA\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt"
    
    if (Test-Path $historyPath) {
        $history = Get-Content $historyPath -Tail 100
        
        $suspiciousPatterns = @(
            'Invoke-WebRequest.*samsung',
            'Invoke-WebRequest.*marriott',
            'IEX.*DownloadString',
            '-enc.*',
            '-w hidden',
            'XtraViewer',
            'Start-Process.*-WindowStyle Hidden'
        )
        
        foreach ($cmd in $history) {
            foreach ($pattern in $suspiciousPatterns) {
                if ($cmd -match $pattern) {
                    Write-Log "FOUND: Suspicious PowerShell command in history" -Level Warning
                }
            }
        }
    }
}

# Remediation function
function Start-Remediation {
    param([bool]$AutoRemove = $false)
    
    if (-not $AutoRemove) {
        Write-Host "`n[?] Do you want to attempt automatic remediation? (Y/N): " -NoNewline -ForegroundColor Yellow
        $response = Read-Host
        if ($response -ne 'Y') {
            Write-Log "Remediation cancelled by user" -Level Info
            return
        }
    }
    
    Write-Log "Starting remediation process..." -Level Info
    
    # Create quarantine directory
    if (-not (Test-Path $QuarantinePath)) {
        New-Item -ItemType Directory -Path $QuarantinePath -Force | Out-Null
    }
    
    # Kill suspicious processes
    foreach ($proc in $DetectionResults.SuspiciousProcesses) {
        try {
            Write-Log "Terminating process: $($proc.Name) (PID: $($proc.PID))" -Level Info
            Stop-Process -Id $proc.PID -Force -ErrorAction Stop
            Write-Log "Successfully terminated process $($proc.PID)" -Level Success
        } catch {
            Write-Log "Failed to terminate process $($proc.PID): $_" -Level Error
        }
    }
    
    # Quarantine malicious files
    foreach ($file in $DetectionResults.MaliciousFiles) {
        try {
            $destPath = Join-Path $QuarantinePath $file.Name
            Write-Log "Quarantining file: $($file.Path)" -Level Info
            Move-Item -Path $file.Path -Destination $destPath -Force -ErrorAction Stop
            Write-Log "Successfully quarantined: $($file.Name)" -Level Success
        } catch {
            Write-Log "Failed to quarantine $($file.Path): $_" -Level Error
        }
    }
    
    # Remove registry persistence
    foreach ($regEntry in $DetectionResults.RegistryEntries) {
        try {
            if ($regEntry.Type -eq "ScheduledTask") {
                Write-Log "Removing scheduled task: $($regEntry.Name)" -Level Info
                Unregister-ScheduledTask -TaskName $regEntry.Name -Confirm:$false -ErrorAction Stop
            } else {
                Write-Log "Removing registry entry: $($regEntry.Path)\$($regEntry.Name)" -Level Info
                Remove-ItemProperty -Path $regEntry.Path -Name $regEntry.Name -Force -ErrorAction Stop
            }
            Write-Log "Successfully removed persistence mechanism" -Level Success
        } catch {
            Write-Log "Failed to remove persistence: $_" -Level Error
        }
    }
    
    # Block C2 domains via hosts file
    Write-Log "Blocking C2 domains..." -Level Info
    $hostsPath = "$env:SystemRoot\System32\drivers\etc\hosts"
    $hostsBlock = "`n# BatShadow C2 Domains - Blocked by Security Script $(Get-Date)`n"
    
    foreach ($domain in $IOCs.C2Domains) {
        $hostsBlock += "127.0.0.1    $domain`n"
        $hostsBlock += "::1          $domain`n"
    }
    
    try {
        Add-Content -Path $hostsPath -Value $hostsBlock -Force
        Write-Log "C2 domains blocked in hosts file" -Level Success
    } catch {
        Write-Log "Failed to update hosts file: $_" -Level Error
    }
    
    # Clear DNS cache
    try {
        Clear-DnsClientCache -ErrorAction Stop
        Write-Log "DNS cache cleared" -Level Success
    } catch {
        Write-Log "Failed to clear DNS cache: $_" -Level Error
    }
    
    # Firewall rules to block malicious IPs
    foreach ($ip in $IOCs.MaliciousIPs) {
        try {
            $ruleName = "Block BatShadow C2 - $ip"
            New-NetFirewallRule -DisplayName $ruleName -Direction Outbound -Action Block -RemoteAddress $ip -ErrorAction Stop | Out-Null
            Write-Log "Firewall rule created to block $ip" -Level Success
        } catch {
            Write-Log "Failed to create firewall rule for $ip : $_" -Level Error
        }
    }
}

# Generate report
function Show-Report {
    Write-Host "`n========================================" -ForegroundColor Cyan
    Write-Host "         DETECTION SUMMARY" -ForegroundColor Cyan
    Write-Host "========================================`n" -ForegroundColor Cyan
    
    Write-Host "Malicious Files Found: " -NoNewline
    Write-Host $DetectionResults.MaliciousFiles.Count -ForegroundColor $(if($DetectionResults.MaliciousFiles.Count -gt 0){'Red'}else{'Green'})
    
    Write-Host "Suspicious Processes: " -NoNewline
    Write-Host $DetectionResults.SuspiciousProcesses.Count -ForegroundColor $(if($DetectionResults.SuspiciousProcesses.Count -gt 0){'Red'}else{'Green'})
    
    Write-Host "C2 Network Connections: " -NoNewline
    Write-Host $DetectionResults.NetworkConnections.Count -ForegroundColor $(if($DetectionResults.NetworkConnections.Count -gt 0){'Red'}else{'Green'})
    
    Write-Host "Registry Persistence: " -NoNewline
    Write-Host $DetectionResults.RegistryEntries.Count -ForegroundColor $(if($DetectionResults.RegistryEntries.Count -gt 0){'Red'}else{'Green'})
    
    Write-Host "Screenshot Files (WEBP): " -NoNewline
    Write-Host $DetectionResults.ScreenshotFiles.Count -ForegroundColor $(if($DetectionResults.ScreenshotFiles.Count -gt 0){'Yellow'}else{'Green'})
    
    Write-Host "`nDetailed log saved to: $LogPath" -ForegroundColor Cyan
    
    $totalThreats = $DetectionResults.MaliciousFiles.Count + 
                    $DetectionResults.SuspiciousProcesses.Count + 
                    $DetectionResults.NetworkConnections.Count + 
                    $DetectionResults.RegistryEntries.Count
    
    if ($totalThreats -gt 0) {
        Write-Host "`n[!] THREATS DETECTED - Immediate action recommended!" -ForegroundColor Red
        return $true
    } else {
        Write-Host "`n[+] No BatShadow/Vampire Bot indicators detected" -ForegroundColor Green
        return $false
    }
}

# Main execution
function Main {
    Show-Banner
    
    Write-Log "Starting BatShadow/Vampire Bot detection scan..." -Level Info
    Write-Log "Log file: $LogPath" -Level Info
    
    # Run all detection checks
    Find-MaliciousFiles
    Find-SuspiciousProcesses
    Find-C2Connections
    Find-RegistryPersistence
    Check-HostsFile
    Check-PowerShellActivity
    
    # Show results
    $threatsFound = Show-Report
    
    # Offer remediation if threats found
    if ($threatsFound) {
        Write-Host "`n"
        Start-Remediation
        
        Write-Host "`n========================================" -ForegroundColor Green
        Write-Host "   RECOMMENDED NEXT STEPS" -ForegroundColor Green
        Write-Host "========================================" -ForegroundColor Green
        Write-Host "1. Change all passwords (especially email/cloud accounts)"
        Write-Host "2. Review recent login activity for unauthorized access"
        Write-Host "3. Scan with updated antivirus/EDR solution"
        Write-Host "4. Monitor for any suspicious network activity"
        Write-Host "5. Review and restore from clean backup if necessary"
        Write-Host "6. Consider forensic analysis for sensitive systems"
        Write-Host "7. Report incident to security team/authorities`n"
    }
    
    Write-Log "Scan completed" -Level Success
}

# Execute
Main