本文翻译自:
https://malfind.com/index.php/2018/07/23/deobfuscating-emotets-powershell-payload/
原标题:Deobfuscating Emotet’s powershell payload
Emotet是2014年发现的一个银行木马,之后研究人员发现了大量的emotet垃圾邮件活动,使用多种钓鱼方法诱使用户下载和加载恶意payload,主要使用武器化的word文档。
Emotet感染链
用户在收到假的email时,点击Email中的链接后,就会下载武器化的doc文档。然后恶意文档会诱使用户启用内容和宏来加载嵌入的VBA代码。但是VBA代码是混淆过的,二球最后会加载一个power shell命令。下面讲述使用沙箱和powershell审计技术在不解混淆的情况下获取VBA代码加载的powershell命令。
Emotet文档示例
Powershell代码本身也是经过混淆的,在虚拟环境下加载的问题就是我们可能看不到任何网络IoC。最好的办法就是将代码解混淆,这样才能更好地理解它。
混淆是一种使恶意代码不便于阅读的方法,有两个作用:
下面介绍2017年12月起Emotet恶意软件使用的三种混淆方法:
字符串替换方法使用多个powershell的replace功能来交换无用的字符串和一些关键字,最终产生有效的power shell代码。
例1 用代码替换方法混淆的代码
可以通过替换字符串的方式在文本编辑器中解混淆混淆后的代码,用正则表达式可以加速这一过程。最后可以通过python脚本中的正则表达式自动完成解混淆。
在python中实施解混淆时应注意:
反混淆例1中代码的结果
字符串压缩方法也很简单,使用power shell内置的DeflateStream
类来解压缩和执行压缩流。
例2 解压缩字符串混淆方法
最简单的解混淆方法是用power shell简单的解压缩字符串。
需要注意的是要手动移除前两个括号中的命令,因为这是混淆的Invoke-Expression cmdlet(接受任何字符串输入并将它视为PowerShell代码)。在处理恶意代码时,最好使用安全的虚拟环境。
powershell中使用的解压缩反混淆方法
查看MSDN文档,可以看到RFC 1951 Deflate数据格式说明中的DeflateStream
类,所以可以用zlib库完成解压缩。Zlib的解压缩方法默认需要准确的zlib文件头,而DeflateStream
是不需要的,因为这就变成了一个流而不是文件。为了让zlib解压缩流,可以在文件中加一个header或者简单的传递一个zlib.MAX_WBITS
参数给解压缩函数。zlib.MAX_WBITS
参数如果是负值就表示解压缩函数应该跳过header位。
计算机用0101数字串来表示字符串,但对人类而言,字符串更易读,所以数字串要通过程序转变成字符串。如果混淆的目的是使代码更难读取,那么为什么还要隐藏恶意代码的真实目的呢?因此,就有了ASCII码数组混淆方法。
例3 ASCII码数组混淆方法
在图5的例子中,我们可以看到一些含有数字的长字符串。如果熟悉ASCII码,可能就可以马上认出来。如果不熟悉的话,可以通过映射表将数字转化为int
然后在转化为char
。例子中的方法使用了切割函数,通过给定的分割器将字符串分割开来进行下一步的混淆。
为了在python中解混淆代码,可以使用一个简单的split
方法,然后用chr()
函数将字符与数字进行映射。
用split方法在python中解混淆出的ASCII码数组
在解混淆出源代码后,可以看出是一个简单的释放器,用WebClient
类来连接硬编码的域名,在%TEMP%
目录下载二进制文件,然后加载。代码中使用break
,try-catch
语句来确保脚本在下载完成前能够连接到域名。
许多混淆的power shell脚本都用Invoke-Expression cmdlet
来把混淆后的字符串当作代码运行。在Windows console中运行power shell恶意代码是有必要的,因为如果没有invoke-expression cmdlet
混淆后的恶意代码就不能运行。
因此,找出伪装的Invoke-Expression cmdlet
就非常重要。首先,power shell允许为长命令使用缩写。所以Invoke-Expression
的内置缩写就是iex
,但power shell还允许将字符串连接并用作cmdlets
,而且字符串可以保存为变量。
这就是问题所在,我们可以用DeflateString
压缩的例子来说明。脚本开始的一行代码是:
$vERBOsepreFErEncE.tOStRIng()[1,3]+'X'-JoIn''
这行代码将power shell内置变量$verbosepreference
的值转化为字符串,然后在第2和第4个字符后面连接了X,之后再用join将所有的字符连接成一个字符串。
那么变量$verbosepreference
的默认值是什么呢?SilentlyContinue
,第2个第4个字符分别是i和e。当连接一个x后就变成了iex
,也就是Invoke-Expression cmdle
t的缩写。事实上,这类技巧在power shell中应用还是很普遍的,尤其是在恶意软件开发者中。
Invoke-Expression混淆示例
作者给出了Emotet反混淆源码,下载地址:https://github.com/lasq88/deobfuscate/