简介
BlackBerry Cylance发现在WAV音频文件中有潜入的混淆后的恶意代码。每个WAV文件中都有一个用于解码和执行恶意内容的加载器组件。播放时,部分WAV文件产生的音乐没有任何质量问题,但部分文件播放时会生成白噪声。
研究人员进一步分析发现其中一些WAV文件中含有与XMRig门罗币挖矿机相关的代码。其他样本中含有用来建立反向shell的Metasploit代码。所有的payload都是在相同环境中找到的,表明攻击活动部署恶意软件的两个目的:获取经济收益和在受害者网络中建立远程访问。
WAV文件加载器可以分成3大类,分别是:
1. 使用Least Significant Bit (最低有效位,LSB)隐写术来解码和执行PE文件的加载器。
2. 使用基于rand()的解码算法来解码和执行PE文件的加载器。
3. 使用基于rand()的解码算法来解码和执行shell文件的加载器。
每个方法都允许攻击者来从非恶意的文件格式中执行代码。这些技术证明了可执行的内容理论上可以隐藏在任意文件类型中,而攻击者可以不破坏容器格式的结构和处理。使用该策略引入了一层额外的混淆,因为底层代码只在内存中出现,因此很难检测。
加载器
隐写PE加载器
概述
加载器的第一类使用隐写术来从WAV文件中提取可执行文件的内容。隐写术是将文件或消息隐藏到另一个文件中的实践,理想情况下也不会引起目标文件的怀疑。攻击者使用隐写术可以隐藏数据。研究人员发现的WAV文件加载器具有以下特征:
该加载器中含有硬编码的字符串,其中指定了要加载的文件名(“Song.wav”)和要执行的导出函数。Song.wav文件位于一个zip文件中:
执行后,加载器会读取Song.wav,在内存中提取DLL,执行“Start” export。提取的文件与XMRig门罗币CPU挖矿机相关:
攻击者部署CPU挖矿机来窃取处理资源,并利用加密货币挖矿来获益。加密货币挖矿机是主流的恶意软件payload,因为提供了经济利益而且可以在用户毫不知情的情况下在后台运行。一个高效的加密货币僵尸网络每个月可以为攻击者产生上千美元的收益。
技术细节
WAV (RIFF)文件的header为44字节,最后4字节表明data section的大小。在Song.wav文件中,数据大小为0xE79F20 (低字节序)或15,179,552字节:
图1: WAV文件header – data大小
在下面的代码段中,加载器按4字节读取,并使用这些值来在内存中分配字节。然后读取数据,并关闭WAV文件。最后,do-while循环,并提取LSB来决定解码的数据的大小:
图2: 解码文件大小
为了更好地理解上面的代码,认识到当counter < 32 时就会执行循环,每执行因此counter就会加1。data_offset表示编码的数据中的偏移量,每个循环该值会加2,该值是从0开始的。该循环会覆盖数据的前64个字节(32 * 2):
图3: WAV 文件数据 – 64字节
对每个处理的字节,加载器会提取LSB,并在decoded_size中分配适当的比特位置,从31开始每个循环减1。应用算法到数据的前64个字节:
最后的32位二进制值00000000 00001011 00110010 00000000用十六进制表示是0xB3200,十进制为733,696。该值位于decoded_size中。
然后,会分配decoded_size大小的内存,并执行不同的计算。默认标记名会被修改来表示所有计算的结果。这些数会用作下一个解码循环的编码数据中的偏移量:
图4: 分配内存和计算偏移量
Do-while循环开始解码编码数据的剩余部分:
图5: 解码文件内容
这部分循环会提取每个字节的LSB。有一点不同是它会在最低比特位来分配位置。每个循环会从8字节中提取LSB来组成解码数据的8比特(1字节)。应用算法来生成解码数据的2字节。因为8比特组成了一个解码的字节,LSB是从每2个编码的字节中提取的,生成2个解码的字节需要32个编码的字节(2 个解码字节 * 8 LSB(每个解码字节)* 2 = 32):
图6: 编码数据的32字节
解码的数据的第1个字节会生成:
生成解码数据的第2个字节:
第一个2字节是二进制值分别是01001101和01011010。十六进制表示就是0x4D5A,这就是Windows PE文件开始的MZ字节。
do-while循环会继续直到内存中生成了XMRig DLL。最后,解码的DLL会与内存进行映射,start export也会执行来驱动加密货币挖矿活动。
基于Rand()的PE加载器
概述
第二类加载器使用基于rand()的解码算法来隐藏PE文件。样本具有以下特征:
为加载WAV文件,加载器必须使用以下命令行:
<Loader EXE> <WAV File> <Decoded PE File Entry Point>
WAV文件具有以下特征:
与第一类加载器中的WAV文件不同,此类音频文件样本有合法的header,但播放时没有音乐,音频听起来就像是白噪声一样。
加载器执行时,会读取WAV文件,在内存中提取DLL文件,尝试执行特定的入口点。与第一个场景类似,提取的文件也与XMRig门罗币加密货币挖矿机有关:
事实上,文件结尾的4个字节不同外,该文件与从Song.wav中解码的dll是相同的。
技术细节
执行后,加载器会读取WAV header,提取data大小,对应地分配内存,并存储WAV数据到新分配的内存中。然后加载器会用运行负责解码WAV文件数据内容的代码:
图7: 基于Rand()的PE加载器解码循环
size_of_data表述从WAV header中提取的数据大小,wave_data含有编码的WAV数据的地址。加载器使用到srand()的初始调用,并重复调用rand()来从WAV数据中提取PE文件。给定srand()的seed值,调用rand()会生成相同的伪随机数。
do-while循环会便利编码数据的每个字节,用从编码的字节中减去rand()输出的结果来替换字节。比如,解码数据的前2个字节:
使用加载器和section中指定的WAV文件,下图寿命了srand() seed值0x309的前2个循环的值:
前2个字节表示Windows可执行文件开头的MZ字符。循环运行所有数据字节后,结果就是一个与XMRig门罗币挖矿机相关的64位DLL。生成的DLL与Song.wav中解码的DLL只有4个字节不同:
图8: 解码的click.wav 和 Song.wav
目前还不清楚为什么这些字节是不同的,这些不同的字节并不影响DLL的功能,所以XMRig DLL文件实际上是相同的。
然后,加载器需要获取命令行中指定的export的地址。如果存在,加载器就会启动一个线程来执行:
图9: 识别export地址并启动线程来执行
基于Rand()的Shellcode加载器
概述
第3类加载器使用基于rand()的解码算法来隐藏PE文件。加载器样本具有以下特征:
为了在加载器中加载WAV文件,必须读取下面命令行的内容:
<Loader EXE> <WAV File>
与前面介绍的加载器类似,音频文件中只含有白噪声没有音乐。执行后,加载器会打开一个可共用的WAV文件,读取数据,解码内容,尝试执行shellcode。
技术细节
加载器会读取WAV header,确定data大小,分配内容,并读取数据。解码的代码也是相同的,包括使用的srand() seed:
图10: 基于Rand()的shellcode加载器解码循环
唯一的不同的解码循环完成后立刻调用CreateThread。该加载器只处理shellcode。Shellcode会尝试连接IP 94.249.192.103。反向TCP连接发生在3527端口,而反向HTTPS连接发生在443端口。
结论
总的来看,攻击者在执行代码的方法上非常具有创意,包括使用不同文件格式的多个文件。研究人员发现了多个从WAV音频文件中提取和执行恶意代码的加载器样本。分析发现恶意软件作者使用隐写术和其他编码技术来反混淆和执行代码。这些战略使攻击者可以隐藏可执行文件的内容,并使检测变得很难。在本例中,攻击者使用混淆技术来执行加密货币挖矿活动,并并命令和控制建立反向连接。