from:https://securelist.com/files/2015/06/The_Mystery_of_Duqu_2_0_a_sophisticated_cyberespionage_actor_returns.pdf
今年年初,卡巴斯基实验室在安全扫描过程中,检测到了几个影响了自家内部系统的网络入侵行为。
接着我们大范围调查了这些入侵事件。我们分析发现了一个全新的木马平台,这个平台出自Duqu APT小组之手。Duqu APT小组是世界上最神秘,水平最高的APT小组。这个小组从2012年开始销声匿迹,直到今天又卷土重来。我们分析了这新一轮攻击,结果表明这是2011年Duqu木马的升级版,怀疑与Stuxnet木马有关。我们把这个新木马和相关的平台命名为"Duqu 2.0"。
Duqu利用了0-day漏洞CVE-2015-2360(WindowsKernel中的漏洞)和另外两个0-day漏洞,攻击了卡巴斯基实验室。微软在2015年6月9日修复了第一个漏洞,另两个漏洞在近期也得到了修复。
Filename:随机 / 根据具体样本而定 MD5 (根据具体样本而定): 14712103ddf9f6e77fa5c9a3288bd5ee Size: 503,296 bytes
MSI文件具有一下属性
其他攻击中使用的MSI文件可能具有另外一些属性。例如,我们还发现了另外几个字段:
在Windows资源管理器的文件属性对话框中,可以查看某些字段。
这个MSI数据包中有两个二进制文件:
ActionDll是一个dll文件,ActionData0是一个经过Camellia加密,LZJB压缩的数据payload(不同情况下的加密算法和压缩算法也不同)。实际上,经过加密或压缩的二进制数据块中,会有好几层可执行代码。
在后面的文章中,我们详细地说明了这些组件。
原文件名: msi.dll MD5: e8eaec1f021a564b82b824af1dbe6c4d Size: 17’920 bytes Link时间: 2004.02.12 02:04:50 (GMT) 类型: 64-bit PE32+ executable DLL for MS Windows
这个DLL只有一个StartAction导出函数,msiexec.exe进程的上下文会调用这个函数。当这个函数被调用时,这个函数就会获取一个MSI属性-PROP,并用这个值来解密actionData0包。
接下来,这段代码会遍历12个需要解密并启动的payload。这些payload是MSI的一部分,可能会包含以下名称:ActionData0, ActionData1, ActionData2。
我们的这个数据包中只包含一个paylioad-“ActionData0”。
主代码会被压缩和加密到这个二进制数据包中。这个二进制的组成包括可执行程序,位置无关代码块,和内嵌的数据对象。这些代码似乎遵循着某种框架,使用了很多辅助结构。辅助结构中包含了一些系统API的指针和内部数据块的偏移量。这些结构能反映出开发者的风格。当代码初始化时,一个字段(一般是前四个字节)中的magic值就会识别结构的状态和类型。
这名编码员还喜欢根据模块和输出名称的哈希来导入系统API。在可执行代码的很多层上都使用了这个哈希算法。通过两个DWORD常量就能识别:0x8A20C27和0x67F84FC6。
一般情况下,ActionData0中的代码会在一个内嵌的可执行程序-“klif.dll”上运行,由这个DLL文件的导出函数表上的第二个函数执行。也就是说,函数名称无所谓,就是要按照函数表上的顺序。当调用这个导出函数时,下一阶段的辅助结构指针就会传递到这个函数上,这样指针就能使用上一层中设置的一些值。
但是,在klif.dll执行之前,代码会尝试另一条路径。首先,代码会查找“api-ms-win-shell-XXXX.dll”,其中X可以是任意的十进制数。如果当前进程中没有这种名称形式的模块,名称就是无效的。这样的话,代码就会遍历查找任何符合名称形式的模块,首先从api-ms-win-shell-0000.dll, api-ms-win-shell-0001.dll, api-ms-winshell-0002.dll开始。这应该是Duqu平台组件的一个依赖选项。
在找到名称后,代码会尝试按照名称来映射内核(section kernel object)对象,这些名称是使用PRNG算法生成的。节名称的格式“/BaseNamedObjects{XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX}”,其中X是根据当前系统的启动时间生成的十六进制数字。到目前为止,节名称都是根据“machine/boot time” 来确定的,这样每个节名称都不一样,但是如果有其他模块的进程也使用了相同的名称生成算法,进程就能定位这样的节。以OSBoot节为例,一旦生成了节名称,代码就会打开节,如果能找到节,代码就会从节中选取几个值,然后尝试打开特定的设备,并把ICTL代码发送到驱动上。驱动设备的名称和IOC代码都在KMART.dll 内的一个节中。
这名编码员非常喜欢用节来访问数据。在映射klif.dll的代码/数据时,还是要用节。另外也可以通过硬编码magic QWORD数: 0xA1B5F8FC0C2E1064来找到这个节。一旦在当前进程的地址空间中找到了节,就由这个节来运行代码。当前的MSI文件数据包并不能应用这种执行路径,但是这种执行路径出现在了代码中,我们猜测这可能是为了使用通用代码模版来创建当前的MSI数据包。当然,这也说明,其他的Duqu平台组件还具有另外的特征。
Original filename: klif.dll MD5: 3fde1bbf3330e0bd0952077a390cef72 Size: 196’096 bytes Link time: 2014.07.06 08:36:50 (GMT) Type: 64-bit PE32+ executable DLL for MS Windows
很显然,这个文件伪装成了卡巴斯基产品的名称-“klif.sys”。虽然代码和文件信息与卡巴斯基产品完全不同,但是,这个模块的导出函数名称使用了卡巴斯基实验室的缩写:KLInit 和KLDone。
当这个DLL加载到一个新进程中时,DLL的内部结构就会初始化,比如给系统API提供指针的结构。
这个模块的payload位于KLDone导出函数上,是导出函数列表上的第二个函数。这个导出函数是从上一层代码中调用的。 首先,模块会确保全局应用结构和关键函数ntdll.dll, kernel32.dll and user32.dll,已经初始化。在调用系统API函数时,需要使用导出函数名称的哈希。哈希算法与前文提到的算法相同,并且也使用了相同的magic常量:0x8A20C27 和0x67F84FC6。
接下来,代码会遍历正在运行的进程列表,并且获取每个进程的小写名称哈希。这个哈希可以是0x3E3021CB 的硬编码值,也就是“avp.exe”字符串的哈希。
如果“avp.exe”进程正在运行,模块就会尝试打开OSBoot-section,并且尝试攻击avp.exe进程。攻击开始时,首先遍历下列产品的硬编码注册表项和注册表值,来识别卡巴斯基产品的安装路径:
在模块所查询的注册表值中包含了卡巴斯基产品的根目录路径,如“C:/Program Files/KasperskyLab/Kaspersky Internet Security 15.0.0/”
一旦找到了注册表项和注册值,模块就会确认avp.exe是不是在那个路径下面。另外它还会对文件执行一些额外的检查:环境变量的检查,文件能否被读取的检查,是否是一个PE文件的检查.
之后这个模块执行如下动作:1.把avp.exe映射到它内部2.改变内存区域的属性让代码执行3.改变avp.exe内的字符4.使用SSE2 CPU扩展对avp.exe打补丁.
接着,模块会尝试启动一个新的线程,线程的开始位置就是其中一个补丁的位置。到目前为止,新的线程会首先调用avp.exe模块,这个模块会执行其他的一些调用,比如,跳回到klif.dll。很显然,这次攻击是为了让avp.exe相信后续的调用是安全的,相信调用堆栈是来自一个合法的avp.exe模块。继续研究代码,发现:新线程会立刻从avp.exe跳转会klif.dll,并且会尝试与卡巴斯基产品的微过滤器,也就是klif.sys通信。
事实上,在与klif.sys通信之前,新线程会打开OSBoot-section,并获取一个IOCTL代码和驱动设备的名称,然后把这个IOCTL代码发送给设备。这个节和相应的驱动(KMART.dll)会给当前模块提供一定的支持。代码会获取当前进程名称的哈希,并且验证哈希是不是下列三个哈希之一:0x3E3021CB (avp.exe), 0xDE6D4DA0 (msiexec.exe), 0xB915B2D8 (rundll32.exe)。
如果能识别当前进程名称的哈希,模块就会打开/KlifComm微过滤器的通信端口,并且发送一些驱动通信信息,来和klif.sys通信。通过分析这些信息,我们发现这项技术能让klif发现不了进程或线程操作。所有的杀毒产品都会认为这个注册过的项目是受信任的,所以不会扫描其活动,也不会检测或拦截其进程。另外,这个模块会要求卡巴斯基产品的自我防御支持,这个功能是防止木马利用系统技术来杀掉安全产品的进程。这样的话,即使是管理员用户也无法终止模块的进程。
我们测试了卡巴斯基的其他一些产品,结果发现,这些产品都会检查进程的自定义数字签名来验证caller进程。截至目前,如果没有额外的驱动支持,这项技术不会成功。从2010年开始,如果有进程尝试打开/KlifComm微过滤器的通信端口,卡巴斯基的产品就会验证这些进程的数字签名。这种攻击只能影响旧版的卡巴斯基产品,比如在2009年发布的KIS2010。
[Image: https://quip.com/-/blob/TdYAAADa8nk/FYSC6P1vMR30Db4HW0OsDA]一般来说,攻击者现在不会攻击卡巴斯基在2009年之前发布的产品。所以,我们有分析了另一种比较合理的解释。
通常来说,这类攻击不会攻击我们的产品,因为我们的产品会检查进程的自定义数字签名,来验证进程的合法性。为了绕过这种检测,Duqu 2.0的一个“KMART.dll”模块给内存中的“klif.sys”打了补丁。因为 “KMART.dll”已经利用Windows内核漏洞在内核模式下运行了,所以这种攻击才能发挥作用。
在发送完代码后,模块会继续下一阶段,也就是进程迁移。
第三层-klif.dll会执行多个函数,来保证木马能驻进内存,并且绕过杀毒检测。
很重要的一点就是获取内核权限。在64位系统上,如果驱动没有签名,用户就不能加载和运行它。虽然其他攻击者,例如Equation 或 Turla,他们会选择利用第三方签名的驱动,但是Duqu 2.0平台使用的手段要高明很多。
其中一个payload-“CTwoPENC.dll”捆绑了“klif.dll”。这是一个Windows内核漏洞(CVE-2015-2360)。利用这个漏洞,payload就能使用最高权限来运行代码。我们恢复了几个版本的“CTwoPENC.dll”,存在32位和64位版本,编译时间戳如下:
不同于Duqu 2.0的其他模块,这些时间戳看起来都是合法的。至于为什么会这样,我们还不清楚-可能Duqu平台的开发者使用的是其他人编写的模块,而开发者忘了修改编译时间戳。
“CTwoPENC.DLL”是 “win32k.sys” 中存在的一个0-day漏洞,利用这个漏洞,非权限用户也能获取到内核权限。这个模块会利用漏洞来创建窗口,线程的类别名称分别是“CPer”, “Zero”, “CTwo”, “Vero” ,并且模块还能操控回调指针。
部分漏洞代码会注册窗口类并创建新的窗口
这个漏洞的目的是加载一个“KMART.dll”驱动。如果漏洞攻击成功,“KMART.dll”就会从模块中解压缩,然后在内核模式下发动攻击。“KMART.dll”既有32位也有64位版本。然后,这个驱动会执行一个内核模式攻击,攻击目标就是卡巴斯基产品的过滤器“klif.sys”。“KMART.dll”会给系统API函数-PsGetCurrentProcessId, PsLookupProcessByProcessId的导入表地址打补丁,也会给杀毒驱动-klflt.sys的输出函数KlGetStringRef 打补丁。在函数被拦截之前,恶意代码已经把恶意模块伪装成来自进程/文件“avp.exe”(使用杀毒组件的真实位置),这样就能绕过杀毒软件的监视。
在测试期间,所有的Windows版本(32位和64位的XP, Vista, 7, 8, 8.1)上都受这个漏洞的影响。微软于2015年6月9日修复了这个漏洞。
payload容器中包含一个短代码节,用于描述目标CPU的架构,payload类型和目标进程的名称或哈希。当模块使用某些内嵌代码或文件时,代码中一般会有两个代码变量:32位和64位。每个payload的运行类型都是根据单一字符来识别。当前模块支持这5种payload 运行类型:g,i,k,l,q。开发者使用的字符按照字母表顺序排列,也就是说,代码中原来可能还有其他的payload类型,只不过被移除了。
首先,代码会在其他进程中查找权限。进程句柄是硬编码的,或者是通过查找当前运行进程,获取进程的名称,然后对比已知哈希来获得的。模块中包括下列硬编码进程的哈希: 0x31283314 (services.exe), 0x1026D1BA (lsass.exe), 0x3BD2498C (svchost.exe)。
如果发现了任何识别出的进程,模块就会打开进程标记,并验证下列的权限是否可用:
如果这些权限可用,模块就会复制进程标记并保存到内部结构中,以便日后使用。
模块在当前系统中,查找一个可用的杀毒软件和一些通用进程。如果什么都没有发现,模块就会尝试查找下列软件的可执行文件:
当模块发现了一个这样的可执行程序后,模块会从发现的位置上运行一个新的进程,并使用自己的代码替换当前可执行文件中的可执行代码,代码会经过加密和压缩。
如果代码能从具有安全权限的进程中,找到一个安全标记,代码就会使用CreateProcessAsUser API来创建一个新的进程,在这时,代码就会使用得到的安全标记。否则,代码只会简单地生成一个新的进程。
这个新进程在启动时,处于挂起和调试状态。在新进程启动前,为了简化代码注入和数据操控,子进程的DEP是禁用的。这样,从外表上看,这个进程就像是一个杀毒程序的进程,但是它的内部代码可完全不是合法的模块。
这种payload与上面的payload几乎一样,但是这个payload的载入程序更简单-这个Loader不进行hijack和提权步骤。注入进程的选择是自动的,只要是可用进程就可以。
这种payload类似于G类 payload,但是它的载入程序在解析payload的标头时有区别:这个载入程序只会选取4个字节来作为进程的哈希,而是不是进程名称字符串。这种方法可能是为了隐藏目标进程的名称,但是,并不是整个模块都应用了这种方法。
这种payload会在当前进程的上下文中运行。代码仅仅会复制需要在独立内存中执行的代码,然后在单独的线程中运行这些代码。在线程完成执行后,执行就会被拦截。
这种payload与 Q类 payload一样,但是这种payload不会拦截新线程的执行。目前来看,新代码是异步运行的。
在payload容器打开后,代码就会迁移到另一个进程,安全软件会保护这个进程,这样真正的恶意代码就启动了。在多数情况下,我们称其为后门通道,能监听协调器的通信。在很少的情况下,某些设备上的协调器模块才能与C2通信,这是才可以作为一个双向代理,来提供大量的二级插件。
除了基本的远程后门,攻击者还在域控制器上和受害者的设备上,部署了更复杂的数据包。这些MSI软件包包括很多模块,各自的作用也不同。
具备完整功能的软件包很大-18MB,基本的远程后门只有500KB。这两者的结构相同,都有ActionDll和加载程序,但是软件还有用于载入和运行的插件。
分析中,我们识别了100多种插件的变种。关于插件的描述如下。我们使用MD5的前两个字节创建了虚拟标识符,来区分插件。
可以使用HTTP HTTPS SMB网络管道 或者加密的TCP直连的方式通信.跟2011duqu一样它可以把交互隐藏在Jpeg或者gif图片中通过http的方式来进行.请求名字,url,和user-agent在不同的攻击中可能是不同的.
已知其他变种:3026, 4F11。
收集到的信息会通过caller提供的命名管道来传输。
已知其他变种:C0B7
073C **–在客户端和服务器上应用完整的Windows Socket传输**。提供工厂类来封装网络函数。
0872-当Windows安装程序启动了恶意软件安装包时, MSI CustomAction library就 会被激活。然后,加载包含payload的加密二进制,接着解密,并在内存中执行。
版本信息中的名称有好几个: svcmsi_32.dll, msi3_32.dll, MSI.dll, msi4_32.dll。
加密算法也不同: Camellia 256, AES, XXTEA。
从MSI参数中提取出的解密密钥可能是: PROP,HASHVA, CKEY。
通过前缀(根据具体情况)来搜索加密的二进制对象:ActionData, CryptHashs, CAData。
已知存在32位和64位版本。其他已知变体:8D7C, 16EF, E6E5,434C, 44BD, F708。
09A0-64位变体,能窃取文件内容。搜索符合下列规则的文件:
09A0 插件感兴趣的文件名称和目录名称
已知其他变体:8858
0AB8 –提供25个函数,这些函数能操控文件和目录:
在某些情况中,模块会搜索目录-“/int”, “/lg”, “/of/md”, “/tl”, “/ak”,以及扩展名-“.part”, “.manual”, “.inuse”。
0AB8 插件感兴趣的文件目录名称
其他已知变体:A69E
0B97-网络传输。利用API来连接socket和caller提供的管道。其他变体:56A2。
152B-网络和域发现。
其他已知样本:A987
1C71-把文件数据放到内存中。
2125-网络感染模块。尝试从正在运行的进程中,获取管理凭证。然后使用Windows共享来连接到一个目标设备。接着,恶意DLL后门成功感染设备;目标目录是变化的,可能在UPDROOT$, ADMIN$ 或 C$。使用自定义SMB数据包来识别目标OS的版本。然后使用新创建的服务“svcmsi_32@”,来启动目标恶意DLL。这个模块通过Windows管道与目标后门通信。其他变体:DB65。除了恶意DLL,模块还会上传一个新的MSI数据包,并且依赖MSIEXEC.EXE 通过新创建的服务“msisvc_32@”来启动MSI,目标MSI的名称是随机生成的,名称模版是“tmp%x.tmp”。
在被感染时,Windows创建的事件日志(系统)项目
模块通过窃取当前运行进程的token来获取管理凭证。这些进程需要是管理员权限用户启动的。所以,模块首先会直接在域控制器中,查询当前域中的100个管理员用户名。
网络感染模块使用的远程位置
24B7-远程桌面管理。获取屏幕截图,同时可以发送输入到桌面,移动鼠标光标。存在32位和64位版本的变体。其他的已知变体:65BE, 7795, BDC8, DEE2
26D6-检测正在运行的网络嗅探器(wireshark, tcpview, netstat, dumpcap, perfmon),设置一个TCP服务器,并通过网络管道通信。内部名称:“P.dll。
2829-收集系统信息
2913-WMI数据收集
其他已知变体:C776
29D4-模块2125利用服务msisvc_32@; DLL backdoor来感染网络,通过管道“Global{B54E3268-DE1E-4c1e-A667- 2596751403AD}”来接收命令。存在32位和64位变体。
其他已知变体:6F92, A505, D242
2B46-收集系统和用户信息
模块收集到的一些注册位置
已知变体:A7F8
2BF7-实用工具DLL。提供基本的API来创建新的MSI数据包,加载并注入任意PE模块。同时负责加载恶意MSI文件中,VFS的第一层。存在32位和64位变体。
已知名称:“ntdll.dll”, “klif.dll”, “apiset.dll”.
其他已知变体:6DA1, 32DB, 8304, 9931, 9E60, A2D4, ABA9, B3BB, DC5F, DD32, F7BB
3395-MS SQL发现模块。这个模块能向网络发送ARP数据包,同时发现MS SQL Server端口。其他函数负责连接额读取远程注册表内容。
35E9-文件系统发现。
3F45-管道后门。打开一个新的全局可见的Windows管道,接收并执行加密的命令。“magic”字符串说明加密的协议是“tttttttt”。
存在32位和64位版本。
已知的管道名称:
其他已知变体:6364, 3F8B, 5926, A90A, DDF0, A717, A36F, 8816, E85E, E927
使用这些数据来定位Chrome保存的登录信息
其他已知 变体:B656
该模块收集的信息
其他已知变体:992E,AF68,D49F
其他已知变体:F3F4
ActiveDirectory详细路径
它有两个导出函数其中一个的名字是"Getreport"
存在32位和64位版本。
其他已知变体:E8C7,EE6E
生成系统报告的XML标签
内部名称“d3dx9_27.dll”。执行基于时间的事件。
其他已知变体:FA84
列举文件名称和目录,检查它们是否存在。
其他已知变体:880B
使用合法WinPcap驱动器“npf.sys”。检测NBNS(NetBIOS协议)感兴趣的请求并发送响应
网络过滤器基于BPF库。HTTP和WPAD的payload由外部提供.
虚假HTTP响应及相关状态信息
其他已知变体:A7EE
其他已知变体:EF2E
搜索文件、档案及implements routines中的信息并提取:
创建扩展名为“.fg4”的临时文件。
其他已知变体:EB18,C091
感兴趣的文件扩展名及其对应的状态信息列表
8172——嗅探攻击。执行 NBNS(NetBIOS协议)名称解析来欺骗:
附加功能:该组件能够在硬编码模板中新建shellcode blob。
其他已知变体: C1B9
已知互斥体和映射名:
其他已知变体: D19F, D2EE
9224——运行控制台应用程序。使用桌面"default"创建进程,附加到命令行窗口,把i/o重定向到命名管道.
92DB——修改cmd.exe shell。
9F0D(64位), D1A3 (32位)——NPF.SYS这个驱动是伴随着VFS插件一起分发的,它有合法的签名.。它被用来执行嗅探攻击。
B6C1 - WNet API。为WnetAddConnection2和WNetOpenEnum函数提供wrappers
其他已知变体:BC4A
C25B——嗅探攻击。运行一个 伪造SMB服务器 来诱骗其他电脑用NTLM进行验证。
其他已知变体:F71E
一般来说,刻画黑客的犯罪过程是一件很困难的事情,duqu2.0尤甚.
duqu除了使用大量的代理来隐蔽自身的犯罪行为外,还额外使用了一些小伎俩:比如它会在代码中植入几个虚假的标记,ugly.gorilla&romanian.antihacker, LZJB算法,前者会让我们错误的认为此次攻击事件是由中国人干的或者这是一次来自罗马尼亚的黑客攻击,后者会让我们错误的认为这个木马来源于miniduke家族.
duqu的攻击具有多地域特征,受害者既有西方国家,也有中东和亚洲国家.关于duqu背后的黑客我们发现了很有趣的一点,那就是他们不仅会盗窃,还会偷方便盗窃用的工具.比如为了投放木马他们在2011年攻击了匈牙利的一家管理数字证书的企业.
duqu2.0的攻击目标和duqu1.0的攻击目标有很多重合的地方.伊朗核设施和一些工控企业始终是他们觊觎的目标.
对一家网络安全公司来说,承认系统被入侵是一件不可想象的事情,但是对卡巴斯基来说不是这样的,因为我们秉承公开透明的原则,基于对用户安全的考量,我们选择公布了此次事件的调查结果.---|---|为了用户的信任 我们会战斗到底。