ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

乌克兰BlackEnergy病毒攻击SCADA实战复盘与防御

乌克兰BlackEnergy病毒攻击SCADA实战复盘与防御 简介这份PDF文档聚焦2015年乌克兰电力系统遭遇BlackEnergy病毒攻击并导致伊万诺-弗兰科夫斯克州大规模停电的真实事件面向电力系统安全、工控信息安全方向的研究人员与运维人员提供病毒机理分析与防御思路的参考。文档通过获取不同版本病毒样本、构建分析环境梳理出远程控制、数据劫持、系统崩溃等攻击路径并给出加强系统安全、恶意软件检测、实时监控与快速响应等防御方法同时延伸讨论电力系统安全与信息安全的多层次关系。资源包共1个PDF文件约2.89MB内容为期刊论文格式含摘要、引言、攻击分析与防御建议等完整章节便于按主题查阅。目前已有172人学习适合作为电力二次系统安全防护与工控安全研究的入门与进阶参考文献。1. 乌克兰电力系统BlackEnergy病毒一次把SCADA打到黑屏的实战复盘2015年12月23日乌克兰西部三个区域电力公司的调度中心几乎同时失去对变电站的远程控制权。值班员发现SCADA画面上断路器状态不再刷新遥控指令下发后无任何返回随后操作系统弹窗报错、鼠标失控、屏幕被强制锁定。事后复盘攻击链的起点是一封带恶意宏的Office文档载荷是BlackEnergy家族的一个变种后续还叠加了KillDisk组件擦除关键主机数据并配合电话呼叫中心的话务淹没让运维无法及时响应。这件事之所以被反复研究不是因为它用了多高深的0day而是它把“IT侧入口→横向移动→SCADA操作站→通信链路”这条路径完整走通了。今天做电力监控系统安全的工程师无论你面对的是国产SCADA还是rapid scada这类组态环境这套攻击链的每一环都值得拆开看它到底怎么进来的、在操作站上做了什么、为什么常规防病毒没拦住、以及我们现在能怎么防。这篇笔记就按这个顺序把BlackEnergy的样本行为、SCADA侧可观测痕迹和防御落地步骤讲清楚适合做工控安全、电力自动化、SCADA运维的读者照着复现分析思路。2. BlackEnergy样本行为拆解从宏文档到SCADA操作站的落地路径2.1 初始投递与宏载荷为什么钓鱼文档能绕过邮件网关BlackEnergy这轮攻击的初始投递物是伪装成电力调度相关通知的Office文档扩展名常见为.xls或.doc内容与“停电计划”“设备检修单”高度相关。文档打开后提示启用宏宏代码执行后释放并运行一个可执行载荷。很多单位的邮件网关只做附件类型和静态哈希匹配对带宏文档的检测依赖沙箱而沙箱里宏往往因为不联网或等待时间不够没有触发后续行为于是漏过。从分析角度拿到这类样本第一步不是直接双击而是在隔离环境里提取宏代码。常见做法是用olevba或oletools套件静态抽取# 安装 oletools用于静态分析 Office 宏 pip install oletools # 提取文档中的宏代码不执行 olevba suspicious.xls # 只看宏的自动执行入口快速判断是否恶意 olevba --deobf suspicious.xls | grep -i autoopen\|document_open\|workbook_openolevba会输出宏的VBA源码、可疑关键字和IOC。重点看AutoOpen、Document_Open、Workbook_Open这类自动执行函数以及是否有Shell、CreateObject(WScript.Shell)、URLDownloadToFile等调用。参数上--deobf会尝试对混淆字符串做还原遇到大量Chr()拼接的样本时很有用。如果宏里出现下载远程可执行文件的URL把它记录下来作为IOC但不要在联网环境里直接访问。这一步的产出是一份宏行为清单释放了什么文件、写到哪个路径、是否创建计划任务或注册表Run键。BlackEnergy变种常见做法是把载荷写到%TEMP%或%APPDATA%下文件名伪装成系统组件然后通过schtasks或注册表实现持久化。2.2 载荷落地与持久化注册表和计划任务两条腿宏释放的载荷运行后通常会做三件事复制自身到用户目录、写入自启动项、尝试连接C2。分析时可以在隔离虚拟机里用Process Monitor和Autoruns观察也可以直接静态看PE导入表和字符串。# 用 pefile 快速提取样本的导入表和可疑字符串 import pefile import re pe pefile.PE(blackenergy_payload.exe) # 打印导入的DLL和函数关注网络、进程、注册表相关API for entry in pe.DIRECTORY_ENTRY_IMPORT: print(entry.dll.decode()) for imp in entry.imports: if imp.name: print( , imp.name.decode()) # 提取样本中的URL和IP作为C2线索 data open(blackenergy_payload.exe, rb).read() urls re.findall(rbhttps?://[\w\./\-], data) ips re.findall(rb\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b, data) print(URLs:, urls) print(IPs:, ips)pefile解析导入表能快速判断样本能力如果同时导入InternetOpenUrl、RegSetValueEx、CreateProcess基本可以确认它有下载、持久化、执行三段能力。字符串提取是粗筛遇到加壳样本可能拿不到明文URL这时需要先脱壳或走动态分析。参数上正则匹配IP时要注意排除版本号之类的误报提取到的IP不要直接访问放到威胁情报平台比对即可。持久化方面BlackEnergy常见的是注册表Run键和计划任务。检查命令# 查看当前用户和系统的自启动项 reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run # 查看计划任务中是否有可疑项 schtasks /query /fo LIST /v | findstr /i TaskName TaskToRun在真实排查中重点看TaskToRun指向的路径是否在%TEMP%、%APPDATA%这类用户可写目录以及任务触发时间是否异常频繁。BlackEnergy的持久化不会用特别显眼的名字往往伪装成Java Update、Adobe Flash Player之类。2.3 横向移动到SCADA操作站凭据抓取与远程执行进入IT网络后攻击者要打到SCADA操作站靠的是凭据复用和远程管理通道。常见手法是用Mimikatz类工具抓取内存中的明文密码或哈希然后用PsExec、WMI、RDP横向。对防御方来说SCADA操作站如果和办公网在同一域、用同一套账号密码基本等于把门开着。从检测角度可以在操作站和跳板机上监控以下行为非工作时间的psexec服务创建、WMI远程调用、异常RDP登录来源。Windows事件日志里重点看4688进程创建、4624登录、7045服务安装。下面是一段用PowerShell拉取相关事件的示例# 查找最近7天内安装的服务关注可疑路径 Get-WinEvent -FilterHashtable {LogNameSystem; ID7045; StartTime(Get-Date).AddDays(-7)} | Select-Object TimeCreated, Message | Format-List # 查找来自非管理网段的4624登录 Get-WinEvent -FilterHashtable {LogNameSecurity; ID4624; StartTime(Get-Date).AddDays(-7)} | Where-Object { $_.Message -match 10\.10\.20\. } | Select-Object TimeCreated, Message | Format-List参数说明FilterHashtable按日志名、事件ID和时间过滤比全量拉取快很多StartTime按需调整排查期间建议覆盖攻击时间窗口前后各一周。输出里重点看服务路径是否指向用户目录、登录类型是否为3或10网络登录、远程交互。如果SCADA操作站上出现来自办公网段的RDP登录而运维又没有相应操作记录这就是高优先级告警。3. SCADA侧可观测痕迹操作站被控后画面为什么还在刷新3.1 HMI与通信链路BlackEnergy在操作站上做了什么很多人以为病毒进了操作站就会立刻让画面卡死实际不是。BlackEnergy在操作站上的行为分阶段先潜伏、收集信息、等待指令最后才执行破坏动作。破坏阶段常见的是结束SCADA相关进程、删除或篡改工程文件、断开通信配合KillDisk擦除磁盘。乌克兰事件中操作员先看到的是遥控失效然后才是系统崩溃中间有时间差。从SCADA组态和通信角度看操作站与RTU/PLC之间通常走IEC 60870-5-101/104、DNP3或厂商私有协议。BlackEnergy本身不直接解析这些规约它是在操作系统层面破坏HMI进程和通信服务。所以排查时要区分是通信链路断了还是操作站主机被控了。判断方法很简单在调度主站侧看前置通信机的通道状态如果通道正常但操作站画面不刷新问题大概率在操作站主机。# 在操作站上检查SCADA相关进程和网络连接 tasklist | findstr /i scada hmi client runtime netstat -ano | findstr 2404 20000 # 查看与前置机/RTU的TCP连接是否还在 netstat -ano | findstr ESTABLISHED | findstr 10.10.30.2404是IEC 60870-5-104常用端口20000是部分厂商私有端口。如果进程还在但连接断了看防火墙和路由如果进程没了看是崩溃还是被结束。BlackEnergy破坏阶段会调用taskkill或直接TerminateProcess结束HMI进程事件日志里可能留下应用程序错误记录。3.2 用国产SCADA和rapid scada做对照排查不同SCADA平台的可观测点不一样。国产SCADA如南瑞、四方、许继等通常有前置通信进程、实时库、历史库、告警服务操作站上还会装组态开发环境。rapid scada这类组态软件则常见rapid scada runtime、scada engine进程工程文件放在特定目录。排查时先摸清本单位的进程清单和端口清单做成基线再对比异常。排查对象国产SCADA常见进程/端口rapid scada常见进程/端口异常信号通信服务前置通信进程104端口2404ScadaServer自定义端口进程消失、端口无监听实时库实时库服务本地共享内存ScadaComm本地管道数据不刷新、共享内存异常操作站HMI画面客户端连接前置机ScadaWeb/ScadaClient画面卡死、进程被结束工程文件组态工程目录常被篡改工程XML/配置文件文件被删、内容被改这张表不是让你照搬而是提醒先建立自己环境的基线再谈检测。BlackEnergy这类攻击最怕的就是你有基线因为它的行为在基线对比下会显得很突兀。比如平时操作站不会在凌晨3点启动cmd.exe不会从办公网段发起RDP不会突然结束HMI进程这些“不会”就是检测点。3.3 网络侧检测C2通信和异常指令的抓法BlackEnergy的C2通信常用HTTP或HTTPS伪装成正常更新流量。网络侧检测靠流量基线加IOC匹配。没有流量镜像条件的至少在边界防火墙和核心交换机上开NetFlow看操作站和前置机是否有异常外联。# 用 tcpdump 抓取操作站与前置机之间的104报文保存后分析 tcpdump -i eth0 -w scada_104.pcap host 10.10.30.10 and port 2404 # 用 tshark 统计会话和异常外联 tshark -r scada_104.pcap -q -z conv,tcp tshark -r scada_104.pcap -Y ip.dst ! 10.10.30.0/24 -T fields -e ip.dst | sort | uniq -c参数说明-i eth0指定网卡host和port限定抓取范围避免全量抓包撑爆磁盘。tshark的conv,tcp看会话统计-Y过滤非工控网段的目的IP如果操作站有大量外联到互联网的会话基本可以判定异常。注意抓包要在镜像口或TAP上做不要在操作站本机抓避免影响生产。4. 防御落地从边界到操作站的五层加固清单4.1 边界与邮件把宏文档和可执行附件拦在外面第一层是边界。邮件网关要能检测带宏文档不能只看扩展名。常见做法是禁用来自外部的Office宏或者对宏文档做沙箱动态分析。防火墙侧限制工控网段主动外联只允许必要的白名单地址。# 示例用 iptables 限制工控网段主动外联只放行白名单 iptables -A FORWARD -s 10.10.30.0/24 -m state --state NEW -j DROP iptables -I FORWARD -s 10.10.30.0/24 -d 10.10.10.10 -p tcp --dport 443 -j ACCEPT iptables -I FORWARD -s 10.10.30.0/24 -d 10.10.10.11 -p tcp --dport 80 -j ACCEPT这段规则的意思是工控网段默认不允许主动发起新连接只放行到指定更新服务器和补丁服务器的流量。参数上-m state --state NEW匹配新建连接-I插入到链首保证白名单先匹配。实际部署前要在测试环境验证避免误断正常通信。4.2 主机加固操作站白名单与应用控制第二层是操作站主机。核心思路是应用白名单只允许SCADA相关进程和必要系统进程运行其他一律拦截。Windows上可以用AppLocker或WDACLinux上用SELinux/AppArmor。同时关闭不必要的服务比如操作站上不该有Office、不该有浏览器、不该有邮件客户端。# 示例用 AppLocker 创建默认规则后只允许指定目录的程序运行 # 先导出当前策略再编辑避免直接锁死自己 Get-AppLockerPolicy -Effective -Xml applocker_backup.xml # 查看当前 AppLocker 规则 Get-AppLockerPolicy -Local | Test-AppLockerPolicy -Path C:\Scada\*.exe -User Everyone参数说明Get-AppLockerPolicy -Effective导出当前生效策略改之前一定备份。Test-AppLockerPolicy可以预演某路径下的程序是否会被放行避免上线后SCADA起不来。白名单目录要包含SCADA安装目录、实时库目录、必要的系统目录其他一律拒绝。4.3 网络分区与访问控制让操作站打不到办公网第三层是网络分区。工控网和办公网之间要有防火墙且规则是白名单。操作站不能直接访问互联网不能访问办公网的共享和邮件。远程运维走堡垒机所有操作可审计。区域允许访问禁止访问审计要求操作站前置机、实时库办公网、互联网进程、登录、指令前置机RTU/PLC、操作站办公网、互联网通信报文、配置变更工程师站操作站、前置机互联网操作录屏、命令历史办公网互联网、办公系统工控网直连常规IT审计这张表的关键是“禁止”列。很多单位分区做了但规则是双向放行等于没分。正确做法是工控网到办公网默认拒绝只放行必要的采集和告警上报。4.4 监测与响应把SCADA操作站的日志接进SOC第四层是监测。操作站和前置机的日志要集中采集包括Windows事件日志、SCADA自身操作日志、通信日志。检测规则围绕前面说的基线异常进程、异常登录、异常外联、异常指令。-- 示例在 SIEM 中查询操作站上的异常进程创建 SELECT host, user, process_name, command_line, timestamp FROM process_events WHERE host IN (scada_op1, scada_op2) AND process_name IN (cmd.exe, powershell.exe, psexec.exe) AND timestamp BETWEEN 2025-01-01 00:00:00 AND 2025-01-02 00:00:00 ORDER BY timestamp;这条查询找的是操作站上不该出现的命令行工具。参数上host列表按实际资产填process_name按基线调整。如果SCADA操作站平时根本不跑cmd.exe那任何一次出现都值得查。响应流程要提前定好发现异常先隔离主机还是先保通信谁有权决定这些要在演练中确定。4.5 备份与恢复KillDisk来了也有后悔药第五层是备份。BlackEnergy配合KillDisk擦数据没有离线备份就只能重建。SCADA工程文件、组态配置、实时库快照、历史数据都要定期备份且备份介质要离线或不可写。恢复演练要定期做确保备份真的能恢复。# 示例用 rsync 做 SCADA 工程目录的增量备份到离线存储 rsync -avz --delete /opt/scada/project/ /mnt/backup/scada_project/ rsync -avz --delete /opt/scada/config/ /mnt/backup/scada_config/ # 备份后校验关键文件哈希确保完整性 sha256sum /opt/scada/project/*.xml /mnt/backup/scada_project.sha256参数说明-a保留权限和时间-v输出详情-z压缩传输--delete让目标与源一致。注意--delete有风险源目录被误删会同步到备份所以备份侧最好再做一层快照或版本化。校验哈希是为了发现备份文件被篡改或损坏。5. 避坑与排查BlackEnergy类攻击防守中最容易翻车的五件事5.1 只查病毒不查行为样本一变就瞎现象杀毒软件扫不出就认为系统干净。原因BlackEnergy变种多静态特征一改就免杀。解决把检测重心从文件哈希转到行为重点看进程链、网络连接、持久化项。操作站上出现winword.exe启动cmd.exe再启动未知程序这条链本身就是告警不管文件哈希是否命中。5.2 操作站和办公网同域同账号横向移动一路绿灯现象攻击者用一个办公网账号就能登录操作站。原因域账号复用、权限过大。解决工控网独立域或独立账号体系操作站登录账号与办公网隔离限制域管账号在工控网的登录。排查时看4624事件里操作站的登录来源如果有办公网IP立即查。5.3 只防边界不防内网U盘和运维笔记本成跳板现象边界防火墙很严但病毒从运维笔记本带进来。原因移动介质和自带设备未管控。解决运维笔记本接入工控网前做安全检查U盘统一管理操作站禁用USB存储。排查时看操作站上是否有新挂载的USB设备记录事件日志里找设备安装事件。5.4 日志没集中出事只能看单机现象操作站被控后日志被删查不到攻击路径。原因日志本地存储权限没分离。解决日志实时发到SOC或日志服务器操作站本地不留或只留短期。排查时如果发现某台操作站日志突然中断先查网络再查主机可能是攻击者断日志。5.5 备份在线可写KillDisk一擦全没现象有备份但备份盘挂载在操作站上且可写一起被擦。原因备份架构没做隔离。解决备份走独立网络备份存储对操作站只读或不可见关键备份离线保存。排查时定期做恢复演练别等真出事才发现备份是空的。6. 进阶技巧用通信基线做SCADA异常指令检测前面讲的都是主机和网络层的通用检测真正能提前发现SCADA被控的是通信行为基线。IEC 60870-5-104和DNP3这类规约的报文结构相对固定正常运行时遥控指令很少遥测遥信是周期性的。如果短时间内出现大量遥控指令或者非工作时间出现遥控这就是强信号。我一般会先抓一段正常运行时的104报文统计每天各类报文的数量和时段分布做成基线。然后写个简单脚本对实时流量做滑动窗口统计偏离基线就告警。# 示例统计104报文中遥控类报文的数量偏离基线则告警 # 假设已用 tshark 导出报文类型字段 import collections import time # 模拟从 tshark 输出读取的报文类型序列 packet_types [C_IC_NA_1, M_SP_NA_1, M_ME_NC_1, C_SC_NA_1, C_DC_NA_1] # 统计遥控类报文C_SC_NA_1 单点遥控C_DC_NA_1 双点遥控 control_types {C_SC_NA_1, C_DC_NA_1} window collections.deque(maxlen300) # 5分钟窗口假设每秒1条 alerts [] for ptype in packet_types: window.append(ptype) control_count sum(1 for p in window if p in control_types) # 基线5分钟内遥控报文不超过5条超过则告警 if control_count 5: alerts.append((time.time(), control_count)) print(告警:, alerts)这段代码是思路演示实际部署要接真实流量。参数上maxlen决定窗口大小control_count阈值按现场基线调。关键是先跑一段时间只记录不告警确认基线稳定后再开告警。误报主要来自正常操作比如计划内的倒闸操作所以要把计划操作时间表接进来做白名单。另一个技巧是看遥控指令的源IP和目的IP。正常遥控来自操作站到前置机再到RTU如果出现从办公网段或未知IP发起的104连接直接告警。这个规则简单但有效我在几个现场都用过抓到过配置错误的测试工具也拦过异常扫描。最后说个习惯每次分析完样本或排查完事件把IOC和检测规则更新到自己的知识库别只留在邮件里。BlackEnergy这类攻击不会只来一次变种会换C2、换文件名但行为模式变化不大。把行为规则沉淀下来下次就不用从零开始。希望帮到你。本文还有配套的精品资源点击获取
返回列表