草庐IT

震网(Stuxnet)病毒深度解析:首个攻击真实世界基础设施的病毒

华为云开发者社区 2023-03-28 原文
摘要:震网病毒主要是通过改变离心机的转速,来破坏离心机,并影响生产的浓缩铀质量。

本文分享自华为云社区《【安全技术】震网(Stuxnet)病毒深度解析:首个攻击真实世界基础设施的病毒(1)【原创分析】》,作者:云存储开发者支持团队 。

第一章 震网病毒背景【源自网络】

2006年,伊朗重启核计划,在纳坦兹建立核工厂,安装大量离心机生产浓缩铀。2010年1月,联合国负责核查伊朗核设施的国际原子能机构(IAEA)发现纳坦兹核工厂出现问题,原本预期使用寿命10年的IR-1型离心机大规模故障,但是谁都说不清楚到底是什么原因导致的。

伊朗纳坦兹核工厂

2010年6月,白俄罗斯一家小型反病毒公司VirusBlockAda的技术负责人舍基·乌尔森(Sergey Ulasen),在分析伊朗计划上上的恶意文件时,发现该恶意文件异常复杂,不仅有效利用了"内核极"后门来躲过反病毒引擎的扫描,还利用了多个"零日漏洞"(zero-day) 来突破Windows系统,但是由于力不从心,没有完全破译该恶意代码。2010年7月12日,乌尔森将该发现发布在一个英文安全论坛上。

舍基·乌尔森(SergeyUlasen)

全球安全业界开始对这个病毒进行分析和破译。同时,微软将该病毒命名为:震网(Stuxnet)。通过分析发现,该病毒的隐蔽性、先进性和复杂性远远超过人们的想象。

据国外一些报道称,该病毒是由美国和以色列的程序员共同编写,其中攻击的西门子工控系统的技术规范由德国提供,西门子工控系统被广泛应用于伊朗核设施中。在以色列的迪莫诺,构建了西门子控制器和IR-1型离心机的试验系统,对该病毒进行了测试,英国政府也参与了试验,试验完成后,荷兰情报人员作为离心机的技术咨询工程师,将病毒植入到核设施中。

震网病毒主要是通过改变离心机的转速,来破坏离心机,并影响生产的浓缩铀质量。

离心机被故障

震网病毒原本的设计是定向攻击,作为网络武器来使用,算是APT攻击的鼻祖。之所以被发现,是因为开发震网病毒的程序员在编程的时候,错误的将and和or用错,导致病毒可以感染任何版本的Windows系统,最终在2010年6月被捕获。

第二章 震网病毒逆向深入分析【个人原创分析,非授权请勿转载】

震网病毒结构与运行流程

震网病毒主要包含6个文件,4个快捷方式图标文件,利用LNK漏洞从U盘自动感染计算机,两个tmp文件,用于初始化和安装震网病毒。

震网病毒共利用了7个漏洞,其中4个0 Day漏洞:

CVE-2008-4250(MS-08-067)-Windows Server Service NetPathCanonicalize()

CVE-2010-2772 WinCC default password

CVE-2012-3015 Step 7 Insecure Library Loading

CVE-2010-2568(MS-10-046)-Windows Shell LNK Vulnerability (O day)

CVE-2010-2743(MS-10-073)-Win32K.sys Local Privilege Escalation (O day)

CVE-2010-3888(MS-10-092) Task Scheduler vulnerability (O day)

CVE-2010-2729(MS-10-061)-Windows Print Spooler Service Remote Code Execution (O day)

震网病毒隐藏在U盘中,当U盘插入到计算机上时,利用LNK漏洞会自动感染Windows系统,感染执行后,通过Ring3 Hook Ntdll实现在内存中加载~WTR4141.tmp文件,Ring3 Hook Kernel32、Ntdll实现*.tmp和*.lnk文件隐藏。进而通过内存LoadLibrary加载~WTR4132.tmp文件,提取出核心的Main.dll,在内存中加密、脱壳、加载Main.dll,初始化安装震网病毒,注入进程、注册服务,释放资源文件,最终震网病毒以服务运行。服务运行时,会攻击西门子WinCC工控系统软件,通过该软件最终攻击PLC,让离心机异常工作,导致离心机快速故障。

Call#15初始化安装Stuxnet

当Main.dll被加载的时候,导出表#15第一个被调用。#15主要负责检查Stuxnet是否运行在一个合适的系统中,检测当前系统是否已被感染,把当前进程权限提升到系统权限,检测系统中安装的杀毒软件版本,选择把DLL注入到哪个进程中;把DLL注入到选择的进程中,然后调用#16。

#15的第一个任务是检查配置数据(configuration data)是否是最新的。配置数据可以被存储到两个位置。Stuxnet检查最新的配置数据并且执行。然后Stuxnet检查是否运行在一个32位的系统中,如果运行在64位系统中则退出,同时也检查操作系统的版本,Stuxnet只能运行在以下版本的操作系统中:

Win2K

WinXP

Windows 2003

Vista

Windows Server 2008

Windows 7

Windows Server 2008 R2

接着检查当前进程是否具有Administrator权限,如果没有则会利用0-day漏洞提升运行权限。如果当前操作系统是Windows Vista、Windows 7、Windows Server 2008 R2,则利用Task Scheduler Escalation of Privilege来提升权限;如果操作系统是Windows XP、Win2K则利用Windows Win32k.sys Local Privilege Escalation(MS10-073)漏洞提升权限。

如果代码运行成功,如果利用win32k.sys漏洞,主DLL文件作为一个新进程运行,如利用Task Scheduler,主dll运行在csrss.exe进程中。

Win32k.sys漏洞利用的代码在资源文件#250中,

当导出表#15运行检查都通过后,#16运行。#16是Stuxnet的主安装程序。它检查日期和操作系统的版本,解密、创建并安装rootkit文件和注册表项;并把自己注入到services.exe中,以便感染移动存储设备;把自己注入到Step7的进程中感染所有的Step7工程;建立全局互斥量(mutexes)用于不同组件之间的通信;连接RPC服务器。

Call#16安装Stuxnet

#16首先检查配置数据是否有效,然后检查注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MS-DOS Emulation中的NTVDM TRACE值是否是19790509,如果是则退出。该项应该是是否允许感染的标识。然后读取配置数据中的日期(配置数据偏移0x8c处)和当前系统日期对比,如果当前日期比配置数据中的时间晚,则退出;配置数据中的日期是2012-6-24。

Stuxnet的各个组件之间的通信采用全局互斥信号量,当在Windows Xp中时调用SetSecurityDescriptorDacl创建这些互斥信号量;在Windows Vista、Windows 7和WindowsServer2008中调用SetSecurityDescriptorSacl创建,用此方法可以降低系统完整性检测,保证代码写操作被拒绝。

然后Stuxnet创建3个加密的文件,这些文件来自.stub节。然后将他们保存到磁盘。

Ø Stuxnet主要攻击载荷文件保存为Oem7a.pnf;

Ø 一个90个字节的数据被保存到%SystemDrive%\inf\mdmeric3.PNF中;

Ø 配置数据被拷贝到%SystemDrive%\inf\mdmcpq3.PNF中;

Ø 一个日志文件被拷贝到%SystemDrive%\inf\oem6C.PNF中;

接着Stuxnet检查系统时间,确保它在2012年6月24号以前。然后通过读取存并解密储到硬盘中的版本信息,来检查自己和保存到磁盘上的加密代码是否是最新的。此功能是通过#6实现的。

版本检查通过后,Stuxnet从资源文件中(#201、#242)释放、解码并将内容写2个文件中:Mrxnet.sys和Mrxcls.sys;它们是两个驱动文件:一个用于Stuxnet的加载点(Load point),另一个用于隐藏磁盘中恶意文件。并且这两个文件的时间和系统目录中的其他文件时间一致,以免引起怀疑;然后创建注册表项指向这两个驱动文件,将它们注册为服务项,以便开机的时候就启动这2个服务。一旦Stuxnet创建的这个Rootkit正确安装后,会产生一些全局信号量,表明安装成功。

Stuxnet接着采用另外的2个导入函数(exports)继续完成安装和感染(infection)过程。

  1. 然后把payload .dll注入到services.exe中并且调用#32(感染可移动存储设备和启动RPC服务);
  2. 把payload .dll注入到Step7的进程:S7tgtopx.exe中并且调用#2(用于感染Step7工程文件),为使这一步成功,Stuxnet可能需要杀掉explorer.exe和S7tgtopx.exe进程,如果他们在运行中的话。

Stuxnet的通过上述的两种payload .dll注入和创建的服务及驱动文件运行起来。

Stuxnet将等待一段短暂时间后才试图连接RPC服务(#32开启的),将调用0号函数检查连接是否成功并且调用9号函数接收一些数据存储到oem6c.pnf中。

至此,所有默认的传播方式和攻击载荷已经被激活。

Stuxnet攻击西门子PLC流程

攻击PLC过程:

  1. 恶意DLL将s7otbxdx.dll重命名为s7otbxsx.dll,用定制的DLL替代s7otbxdx.dll,该定制DLL主要重写s7otbxsx.dll 109个中的16个涉及读、写和枚举代码块的导出函数,其他导出函数还是由s7otbxdx.dll提供;
  2. 震网根据不同目标系统的特征选择不同的代码来感染PLC,一个感染的序列包含注入到PLC中的代码块和数据块,来改变PLC行为,主要有三种感染序列,其中两种比较相似,功能相同,标记为序列A和B,另外一种标记为序列C;
  3. 如果s7otbxdx.dll是运行在ccrtsloader.exe文件中,替换后的s7otbxdx.dll启动两个线程感染特定的PLC:

线程1:(每15分钟运行一次;感染含有特定SDB特征的6ES7-315-2 PLC)

  1. 通过s7ag_read检测PLC类型,必须为6ES7-315-2;
  2. 检测SDB块来确定PLC是否被感染以及选择写入哪个序列(A或B);
    Ø 枚举、解析SDB(系统数据块),寻找一个偏移50h DWORD的地方等于0100CB2Ch的SDB;(说明使用的是Profibus communications processor module CP 342-5。)
    Ø 在SDB中搜索特定的值7050h和9500h,只有当两个值出现在总数大于等于33时才满足感染要求;(7050h代表KFC750V3变频驱动器,9500h代表Vacon NX频率转换驱动器。)
  3. 按照序列A或B进行感染:

Ø 拷贝DP_RECV块到FC1869,然后用定制的块替换DP_RECV块;(DP_RECV是网络协处理器使用的标准代码块的名称,用来接收Profibus上的网络帧。每次接收包时,定制块会调用FC1869中原始的DP_RECV进行处理,然后对包数据进行一些后处理。)

Ø 将一些定制块写入到PLC(20个);

Ø 感染OB1,使每个周期开始先执行恶意代码;(首先增加原始块的大小;然后将定制代码写入到块的开头;最后将原始的OB1代码插入到定制代码后面。)

Ø 感染OB35;(和OB1相同,采用code-prepending感染技术)

线程2:(每5分钟查询一次;保证攻击同时进行)

  1. 监控、查询总线上的每个特定PLC(如S7-315)中被线程1成功注入的数据块DB890;
  2. 当达到特定条件,启动破坏例程时,该线程向所有监控的PLC中的DB890写入数据,使同一总线上的PLC同时发起破坏攻击。

(4) 某些条件下,会将序列C写入PLC,针对6ES7-417,更为复杂;

(5) 破坏:(在不同时间降低或增加马达频率)

  1. 确定正常的操作频率:807-1210Hz;
  2. 将频率设定为1410Hz;
  3. 恢复正常操作;
  4. 大约27天后,先将频率设为2Hz,然后设为1064Hz;
  5. 恢复正常操作;

重复上述过程。

第三章 震网病毒重现

【篇幅原因,请关注后续文章】

 

点击关注,第一时间了解华为云新鲜技术~

有关震网(Stuxnet)病毒深度解析:首个攻击真实世界基础设施的病毒的更多相关文章

  1. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 用逗号、双引号和编码解析 csv - 2

    我正在使用ruby​​1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\

  4. ruby-on-rails - 我更新了 ruby​​ gems,现在到处都收到解析树错误和弃用警告! - 2

    简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und

  5. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  6. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  7. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  8. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  9. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  10. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

随机推荐