PLAY勒索软件完整分析

逆向病毒分析 1年前 (2023) admin
509 0 0

PlayCTI

Play 勒索软件(又名PlayCrypt)活动至少从2022年7月中旬开始活跃。最多五张勒索信 play勒索软件已上传到病毒总数到目前为止。2022年8月中旬,首例公开的 play勒索软件是在一名记者揭露阿根廷科尔多瓦司法机构受害后宣布的。

众所周知,运营商使用常见的大型游戏狩猎(BGH)战术,如SystemBC RAT的持久性和cs后渗透的战术。他们还使用自定义PowerShell脚本和AdFind进行枚举,使用WinPEAS进行权限提升,使用RDP或SMB在目标网络内部进行横向移动。

该组织在加密文件后附加“.play”,其勒索信只包括“PLAY”一词和一个与威胁行为者通信的电子邮件地址。众所周知,威胁行为者使用WinSCP泄露文件,但不像许多其他BGH勒索软件活动那样拥有Tor数据泄露网站。

非常感谢我的人威尔托马斯为这个信息!

概述

这是我对 PLAY勒索软件。我将只关注它的反分析和加密特性。还有一些其他特性,如DLL注入和网络,将不在本分析中讨论。

尽管它很简单,但PLAY被大量独特的技巧严重混淆,这些技巧之前没有被任何勒索软件使用过。

该恶意软件使用通用的RSA-AES混合加密系统来加密文件。PLAY的执行速度相当平均,因为它使用深度优先遍历算法来遍历文件系统。尽管启动了单独的线程来加密每个文件,但这种递归遍历会显著地降低其性能。

IOCS

分析的示例是32位Windows可执行文件。

MD5 :223有效期1610年432年1月1日aa06年c60年7月9日a6

SHA256 :006ae41910887f0811a3ba2868ef9576bbbd265216554850112319af878f06e55型飞机

示例恶意软件市场

           PLAY勒索软件完整分析

           

图2:病毒总数结果。

勒索信

默认勒索信的内容以编码字符串的形式存储在PLAY的可执行文件中,其中包含字符串“PLAY”以及受害者联系威胁参与者的电子邮件地址。

PLAY的 勒索信文件名是“ReadMe.txt”

PLAY勒索软件完整分析

           

图3:PLAY的赎金笔记。

反分析

反分析:面向回报的程序设计

在IDA中打开可执行文件时,我们可以看到大多数汇编代码没有意义,也不是很有意义。一个例子可以从 WinMain软件,其中没有clear return语句会在有效代码中弹出垃圾字节。

PLAY勒索软件完整分析

             

图3:WinMain中的反编译功能。

如上面的反汇编代码所示,中的控制流 WinMain软件 唿叫 子模块_4142F5 并且在返回时, 埃迪弹出,然后在0x4142F2处遇到垃圾字节。因此,IDA无法正确地反编译此代码。

PLAY勒索软件完整分析

             

图4:未修补的WinMain反编译代码。

检查 子模块_4142F5 ,我们可以看到存储在堆栈指针处的值立即在 雷滕指令被执行。

我们知道 唿叫 指令基本上包含两个原子指令,一个推送下一个指令的地址(在 唿叫指令)到堆栈上且一个跳到正被调用的子例程。当密码输入 子模块_4142F5时,返回地址(在本例中为0x4142F1)存储在堆栈顶部的堆栈指针处。子例程将0x35加到这个地址,将返回地址更改为0x414326,然后 雷滕跳到它上面。

知道这一点后,我们可以向下滚动并尝试反汇编0x414326处的字节,以获取 WinMain软件密码。

PLAY勒索软件完整分析

             

图5:反汇编的隐藏代码。

使用这种面向返回的编程方法来转移程序的常规控制流,PLAY能够通过IDA的反汇编和反编译绕过大多数静态分析。

我们还可以很快看到,在0x41433A处,还有另一个调用指令,后面跟着一些垃圾字节。这意味着模糊处理在代码中发生多次。

我的方法是通过编程修补所有这些 唿叫指示完毕。在我的分析中使用的一个简单修补程序是计算跳转(添加到返回地址的值)并替换 唿叫 指令与 跳跃指令到目标地址。

为了扫描所有这些模糊代码,我使用了3个不同的(但非常相似的)正则表达式(这是一个词吗?)在IDAPython中查找并修补它们。您可以找到我的修补脚本 这里

打完补丁后,WinMain代码如下所示。

PLAY勒索软件完整分析

             

图6:修补WinMain。

有点平淡无奇,但现在我们已经成功地对代码进行了反模糊处理,得到了一个有意义的 唿叫 指示 子模块_415110以及反编译代码中的正确返回语句!

反分析:垃圾代码

除了控制流混淆,PLAY还在代码中添加了随机移动指令,这些指令对程序的主要功能没有任何贡献。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图7、8:垃圾代码。

这使得反编译的代码看起来很混乱,而且修补所有这些错误代码并不简单,因为有效代码通常被填充在这些垃圾代码之间。跳过它们进行修补有时会破坏程序本身。

对此,我唯一的解决办法就是在分析时在心理上忽略它们。

反分析:API散列

与大多数现代勒索软件类似,PLAY通过API名称哈希来混淆其API调用。API解析函数接受目标哈希和DLL地址。

它遍历DLL的导出表以获取导出的名称。对于每个API名称,恶意软件调用 小于40F580并将0x4E986790添加到结果以形成最终散列。将此哈希与目标哈希进行比较,如果匹配,则返回API的地址。

PLAY勒索软件完整分析

             

图9:API散列

如下所示,散列函数包含许多唯一的常量,这使我们能够快速查找到它是xxHash32。这样,我们就知道完整的散列算法是xxHash32,种子为1,结果加到0x4E986790。

PLAY勒索软件完整分析

             

图10:xxHash32代码。

从这里开始,我开发了一个IDAPython脚本来自动解析恶意软件使用的所有API,您可以在这里找到

PLAY勒索软件完整分析

             

图11:解析API。

反分析:字符串加密

中最重要的字符串 播放都被编码在内存中。解码算法似乎不是太清楚,所以我只是动态通过这些我的方式。学校现在正忙得不可开交,所以我尽量避免分析东西。

PLAY勒索软件完整分析

             

图12:PLAY的字符串解密。

静态代码分析

命令行参数

PLAY 可以使用或不使用命令行参数运行。

下面是操作员可以提供的参数列表。

论证

-mc

-d<驱动器路径>

-ip<共享资源路径>

-d

PLAY勒索软件完整分析

             

图13:检查命令行参数。

加密初始化

在加密之前,PLAY初始化并检索加密算法提供程序。

首先,它调用BCryptOpenAlgorithmProvider加载并初始化CNG提供程序以生成随机数,并调用BCryptImportKeyPair导入其硬编码的RSA公钥。

PLAY勒索软件完整分析

             

图14:初始化&导入加密密钥。

接下来,恶意软件调用VirtualAlloc来分配缓冲区以存储128个用于加密文件的文件结构。该结构的大小为0x48字节,其内容如下所示。

  struct play_file_struct              
  {              
    int struct_index;              
    char *filename;              
    int initialized_flag;              
    int padding1;              
    char *file_path;              
    int file_marker[2];              
    int chunk_count;              
    int chaining_mode_flag;              
    DWORD large_file_flag;              
    HANDLE AES_provider_handle;              
    HANDLE bcrypt_RNG_provider;              
    HANDLE RSA_pub_key_handle;              
    HANDLE file_handle;              
    LARGE_INTEGER file_size;              
    DWORD file_data_buffer;              
    DWORD padding2;              
  };

字段

结构索引

档名

初始化标志

文件路径

文件标记

块计数

链接模式标志

大文件标志

AES提供程序句柄

b加密RNG提供程序

RSA发布密钥句柄

文件句柄

文件大小

文件数据缓冲区

PLAY 迭代这个全局结构列表并填充每个结构的字段。首先,它将结构体中的加密文件标记设置为以下硬编码值,这些值稍后将写入每个加密文件的末尾。

PLAY勒索软件完整分析

             

图15:加密文件标记。

然后,恶意软件将RNG和AES提供程序句柄以及RSA公钥句柄设置为该结构。这些将在以后用于生成随机AES密钥和IV来加密文件。

PLAY勒索软件完整分析

             

图16:加密文件标记。

检查现有驱动器

在遍历所有驱动器以进行加密之前, 播放 通过调用枚举受攻击系统上的所有卷 查找第一卷W 以及 查找下一卷W。如果卷不是CD-ROM驱动器或RAM磁盘,则恶意软件将调用 获取卷名称W的卷路径名称检索指定卷的驱动器号和已装入文件夹路径的列表。

如果此列表为空,这意味着卷未装入任何文件夹,PLAY将调用GetDiskFreeSpaceExW来检查卷的可用空间是否大于0x40000000字节。如果是,恶意软件将调用SetVolumeMountPointW尝试将卷装载到驱动器路径。

PLAY勒索软件完整分析

             

图17:枚举卷。

对于要装入的每个卷,PLAY将遍历所有字符以查找驱动器名称,它可以调用SetVolumeMountPointW将卷装入到该驱动器名称。

PLAY勒索软件完整分析

             

图18:设置卷的挂接点。

使用相同的技巧迭代所有可能的驱动器名称, 播放 唿叫 获取驱动器类型W检查每个驱动器的类型。

它避免了加密光驱或RAM磁盘。如果是远程驱动器,恶意软件将调用WNetGetUniversalNameW来检索网络驱动器的通用名称。

PLAY勒索软件完整分析

             

图19:处理网络驱动器。

要加密的最终驱动器路径设置为网络驱动器的通用名称或连接名称,具体取决于存在哪一个。

PLAY勒索软件完整分析

             

图20:检索网络驱动器名称。

如果驱动器是常规驱动器,则其名称保持不变。每个有效驱动器的名称都添加到要遍历和加密的驱动器名称列表中。

递归遍历

为了开始横向驱动, 播放 遍历上面的驱动器名称列表并使用以下内容生成线程 创建线程遍历系统上的每个驱动器。

PLAY勒索软件完整分析

             

图21:生成线程以遍历驱动器。

在处理驱动器之前,恶意软件会提取以下勒索信内容,然后将其放入驱动器文件夹。这是唯一的地方,赎金说明是下降,而不是在每个文件夹像其他勒索软件。

PLAY              
[email protected]

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析 图22、23:在驱动器中放置勒索信。

要开始枚举,恶意软件调用FindFirstFileWFindNextFileW来枚举子文件夹和文件。它专门检查以避免处理当前和父目录路径“”。“…”

PLAY勒索软件完整分析 图24:枚举文件。

如果遇到的文件是目录,恶意软件会进行检查以避免加密“Windows”目录。然后,它将子目录的名称连接到当前文件查找路径,并通过调用遍历函数递归地遍历子目录。

PLAY勒索软件完整分析 图25:递归遍历子目录。

如果遇到的文件是一个普通文件,恶意软件会检查其名称和大小,以查看它是否可以加密。

PLAY勒索软件完整分析 图26:检查文件。

如果其名称/扩展名在下面的列表中,或者其大小小于6,PLAY将避免对其进行加密。

.exe, .dll, .lnk, .sys, readme.txt, bootmgr, .msi, .PLAY, ReadMe.txt

PLAY勒索软件完整分析

             

图27:检查文件&扩展名。

PLAY 还执行附加检查,查看文件扩展名是否是典型的大文件扩展名,以便稍后确定其加密类型。如果文件的扩展名在下面的列表中,则该文件被归类为大文件。

mdf, ndf, ldf, frm

填充文件结构

对于每个要加密的文件,PLAY首先用关于该文件的适当数据填充文件结构。

首先,它开始遍历全局文件结构列表,以检查是否有可用的结构来处理文件。

PLAY勒索软件完整分析

             

图28:检查可用的文件结构。

如果全局列表中没有可用的结构,PLAY调用Sleep使线程休眠并重新检查,直到找到一个为止。

一旦找到该结构,恶意软件就将其initialized_flag字段设置为1,并将filename字段设置为目标文件名。它还填充其他字段,如文件大小、大文件标志和文件句柄。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图29、30:填充文件结构以加密文件。

子线程加密

在填充了特定文件的文件结构之后,PLAY会生成一个线程来开始加密文件。

如果文件未被分类为大文件,则恶意软件将根据文件大小计算需要加密的区块数。如果文件大小小于或等于0x 3fffffff字节,则加密组块的数量为2;如果文件大小小于或等于0x 27 fffffff字节且大于0x 3fffffff字节,则加密组块的数量为3;如果文件大小等于0x 280000000,则加密组块的数量为0。如果文件大小大于0x 280000000字节,则加密组块的数目是5。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图32:计算加密区块。

默认链接模式设置为AES-GCM。但是,如果文件大小大于加密大小的4025倍(即块大小0x 100000乘以块计数),则链接模式将设置为AES-CBC。

这是因为与AES-CBC相比,AES-GCM的性能最差。根据这篇文章,AES-GCM是一个比AES-CBC更安全的密码,因为AES-CBC通过XOR’ing(异或)将每个块与前一个块进行运算,并且不能并行写入。由于涉及需要串行加密的复杂数学运算,这会影响性能。

对于文件加密,PLAY现在引入了一个新的结构,表示写入每个加密文件的文件页脚内容。

我花了很长时间才完全理解和解析这个结构的字段,这提醒了我,我可能只是在恶意软件分析现在撕裂。

struct file_footer_struct              
{              
  byte footer_marker_head[16];              
  WORD last_chunk_size;              
  WORD skip_chunks;              
  WORD large_file_flag;              
  WORD small_file_flag;              
  DWORD default_chunk_size;              
  DWORD footer_marker_tail;              
  QWORD encrypted_chunk_count;              
  byte encrypted_symmetric_key[1024];              
};

字段

页脚标记页眉

最后块大小

跳过_块

大文件标志

小文件标志

块计数

默认块大小

页脚标记尾部

加密块计数

加密对称密钥

首先,PLAY读取文件末尾的0x428字节以检查文件页脚。如果文件大小小于0x428字节,则可以保证文件不会被加密,因此恶意软件会立即对其进行加密。

如果成功读取了最后一个0x428字节,则恶意软件将检查 xxHash32页脚标记头的散列等于页脚标记尾。如果是,则确认文件页脚有效,并且文件已经加密。

如果不是这种情况,PLAY会检查页脚标记头中的每个DWORD,并将其与文件结构中的硬编码值进行比较。这将检查文件页脚是否未加密,文件页脚是否已写入但尚未加密,或者文件是否已加密。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图33、34:检查文件页脚的加密状态。

文件加密

要从头开始加密文件,PLAY首先生成一个AES密钥来加密文件。

它调用BCryptGenRandom生成一个随机的0x20字节缓冲区。根据文件结构中指定的链接模式,恶意软件调用BCryptSetProperty为其AES提供程序句柄正确设置链接。

接下来, B加密生成对称密钥在随机生成的0x20字节缓冲区中调用,以生成AES密钥句柄。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图35、36、37:正在生成AES密钥句柄。

接下来,为了将AES密钥存储在文件页脚结构体中,PLAY调用BCryptExportKey将AES密钥导出到0x230字节的密钥blob中。它还调用BCryptGenRandom来随机生成0x10字节的IV,并将其附加到密钥blob之后。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图38、39:正在导出AES密钥块&IV。

然后,它调用BCryptEncrypt以使用RSA公钥句柄加密导出的密钥blob和IV,并将加密的输出写入0x400字节的缓冲区。然后将此缓冲区复制到文件页脚结构的encrypted_symmetric_key字段。

PLAY勒索软件完整分析

             

图40:使用RSA公钥加密AES密钥块。

PLAY 然后用文件结构中的现有信息填充文件页脚的其他字段,如footer_marker_head、footer_marker_tail、small_file_flag和large_file_flag。默认块大小也设置为0x100000字节。

PLAY勒索软件完整分析

             

图41:填充文件页脚结构。

文件页脚完全填充后,恶意软件调用SetFilePointerEx将文件指针移动到文件末尾,并调用WriteFile将结构写入其中。

PLAY勒索软件完整分析

             

图42:将文件页脚结构写到文件末尾.

如果文件大小大于0x500000字节,PLAY只加密文件中的第一个和最后一个块。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图43、44:加密大文件的第一个&最后一个块。

加密函数包括 读取文件 调用以读取文件结构中缓冲区中的块数据, B加密加密调用以使用AES密钥句柄和生成的IV加密文件。加密完成后,恶意软件调用 写入文件将加密输出写入文件以及在文件页脚中加密的块的索引。这可能用于在发生损坏或中断的情况下跟踪有多少块已被加密。

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

PLAY勒索软件完整分析

             

图45、46、47:数据加密功能。

如果文件大小小于默认块大小0x100000字节,恶意软件将加密整个文件。

PLAY勒索软件完整分析

             

图48:加密整个小文件。

如果文件大小介于0x100000和0x500000之间,则恶意软件会将其加密为0x100000字节的块,直到文件末尾。

PLAY勒索软件完整分析

             

图49:加密中型文件。

最后,文件加密后,恶意软件将其扩展名更改为 播放 通过调用 移动文件W

PLAY勒索软件完整分析

             

图50:附加加密扩展名。

代码中有一个小错误,即无论加密是否成功,由于文件加密函数的返回值,它总是更改文件的扩展名。

PLAY勒索软件完整分析

             

图51:加密中型文件。


翻译自网络

原文始发于微信公众号(闲聊知识铺):PLAY勒索软件完整分析

版权声明:admin 发表于 2023年3月7日 下午7:21。
转载请注明:PLAY勒索软件完整分析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...