最近,我看了一下上传到VirusBay的样本,并发现了一些很特别的东西。一个名叫Bondey的用户上传了一个样本,并将其标记为Gh0st RAT。Gh0st RAT是一个已经被使用了很长时间的远程访问工具,并且有众多变种和变化。但是,到目前为止,这个RAT似乎已经消失了有一段时间。目前,使用Gh0st以获取远程访问的主要群体是“铁虎(Iron Tiger)”,一个被认为来自中国的APT组织。相关资料显示,该组织目前正瞄准亚洲和美国的政府、技术、教育和电信组织。我一直很喜欢查看APT组织使用的恶意软件,所以我下载了这个样本来分析它。
MD5:abdabfea475959703fb1957413b39cad
在执行通常的分析方法之前,我检查了VirusTotal上的散列。出乎我的意料的是,什么也没有出现。我上传了这个文件,并且意识到我是第一个将它上传到VT的人。我刚刚检查了一下, THOR APT Scanner对样本进行了评论,澄清它是Gh0st的一个变种 ,特别是s.exe被Iron Tiger使用。
我目前正在开发一个项目,下载新的样本并对它们进行基本的动态分析,以便初学者能够选择他们想要分析的恶意软件类型。对于这个RAT,我使用了这个项目的动态分析部分来分析它,得到了一个缩小的字符串列表:由于这是一项正在进行的工作,所以并不是所有的东西都能够被提取出来,不过它还是提出了一些有趣的字符串。似乎有一个存储在dllcache 和 system32文件夹中termsrvhack.dll的引用——也许这是一个stager组件,它将一个DLL放入到磁盘中?你可能还会注意到底部的熵,在之后它将被用于推测样本是否经过了打包/混淆。在这个案例中,它似乎并没有这样做,而且你会看到为什么当我用字符串来表示它以获得完整的输出:你可以将这些字符串看作键盘上的按键,这是完全正确的。这些字符串暗示了RAT中的键盘记录功能。这也就提出了这样一个问题:既然一个高级持续威胁(APT)组织选择它来作为他们的恶意软件,为什么他们甚至不尝试打包或混淆它?字符串不仅返回了一个键列表,还返回了嵌入在可执行文件中的URL:
这个URL指向的似乎是一个中国的社交媒体网站,但这并不能帮助我理解它为什么包含在EXE中。现在我们已经分析了字符串,是时候把它放入PEStudio中来收集有关于文件本身的信息了。
在检查资源部分时,我发现多个资源被存储在文件中,但其中一个资源被提取了出来——一个具有HTML签名的资源。我把它放到磁盘上,想看看资源里面有什么。然而,这里并没有什么有价值的证据,似乎是一些加密的文本和一个数字—— 360。接下来,我审查了导入,看看能否更好地了解这个样本的功能。在分析时,我并没有能够完全确定它可以做什么。该样本使用序号(与API名称对应的数值)以及API名称导入函数。幸运的是,PEStudio能够解决大部分序号导入,揭示了正确的名称。因此,我们可以看到样本从Winsock库导入了多个函数,这意味着该程序正在建立与某处连接或从某处接收连接的可能性很高。
查看导入的DLL,你可以看到一个msvfw32.dll被导入。看起来这个DLL为可执行文件提供了视频功能,所以这个样本是否能够对受害者的计算机进行屏幕录制呢?
所以现在我们已经完成了基本的可执行分析,是时候将它放入IDA中以反汇编可执行文件并了解它是如何运行的了。我再次检查了二进制文件中的字符串列表,以查看是否在原始列表中漏掉了什么。然后,我发现了一个看起来像是Visual Basic 脚本文件名的内容:
Jingtisanmenxiachuanxiao.vbs
就我所知,这个文件名没有上下文,所以也许它是一个将会被下载到系统的文件?继续前进,我决定查看TCP连接例程,因此我搜索了用于连接的交叉引用。三种不同的结果出现了,可能暗示了三种不同的C2服务器连接。 我还注意到一个有趣的字符串存储在偏移量aProgramFilesRu被推送(push)到堆栈。该变量包含文件路径“\ProgramFiles\Ru%d.EXE”。这可能是恶意软件下一阶段的放置位置,或恶意软件将要被复制到的目录。我花了一点时间来查看拆解后的样本,但没有发现任何非常有用的东西,于是我启用了x32dbg,并用它打开了样本。
通过使用x32dbg,我能够找到可执行文件的“main”函数,其中有趣的部分正在发生,而不仅仅是初始化。进入主函数后,我立即注意到程序是如何导入库和API调用的。并不是运行LoadLibrary(“Kernel32.dll”),而是初始化一个字母数组,并将其传递给LoadLibrary调用,在反汇编后看起来像下面这样:
在将调用传递给LoadLibrary之后,我发现了一个有趣的循环。这个循环清除了内存中的一个区域,并填充了一些无意义的字符串,比如Ruiswe wgzawios。这些字符串在某些时候看起来很重要,所以我需要记住它们。你还可以看到%SystemRoot%也被存储。该循环再一次运行,但是它清除了一个不同的内存区域,并将一个IP地址写入该内存区域——218.60.67.75。但是,在写入IP地址之后,循环不会结束。它会继续进行并向该区域写入一个URL——http://xxx.ys168.com。我试着在网上搜索,但是我什么也没有得到。
然后,该程序会使用sprintf来形成可执行文件将要被复制到的路径:
C:\Windows\Kbwgmwu.exe
这个文件名被硬编码到可执行文件中,所以每次都会有相同的名称。为了形成将传递给sprintf的字符串,需要遵循用于导入DLL的相同例程。%s\%s首先以数组的形式写入内存,然后作为字符串传递,其中%s仅仅是字符串的占位符。第一个%s包含C:\Windows,第二个%s包含Kbwgmwu.exe。一旦调用sprintf,最终的路径就形成了——C:\Windows\Kbwgmwu.exe。
继续往下走,另一个字符串被作为数组写入到程序内存中——这次是一个注册表键值:
SYSTEM\CurrentControlSet\Services\%s
再一次,首先将它写成一个数组,然后推送到堆栈进行格式化。在使用注册表之前,会形成另一个字符串——rundll32.exe。该字符串被传递给一个函数,该函数将导入并调用另外三个函数:
l GetToolhelp32Snapshot
l Process32First
l Process32Next
也许你并不知道这些函数的用途,第一个函数将获取当前正在运行的进程的列表,第二个函数将获取列表中的第一个进程的句柄,最后一个函数用于遍历列表。对于每个正在运行的进程,程序调用strcmpi,将进程名称与传递的参数(rundll32.exe)进行比较。如果找到了rundll32.exe,该函数将返回,然后使用导入的API调用WinExec执行taskkill /f /im rundll32.exe。如果rundll32.exe没有运行,该函数将返回并继续执行,而不执行taskkill。我仍然不能够完全确定程序为什么要检查rundll,除非它正在检查以前版本的Gh0stRat,因为它们是DLL格式的。
一旦它检查了RunDLL32.exe,该程序将导入注册表函数,以便可以创建and/or查询键值。还记得我之前提到的Reg键值?%s被格式化为读取Ruiswe wgzawios,所以完整的Reg键值是:
SYSTEM\CurrentControlSet\Services\Ruiswe wgzawios
程序检查键值是否存在,如果不存在,则关闭键值的句柄。再一次,RegCloseKey作为数组导入并调用,所以你可以在调试器中看到以下结果: 一旦注册表被查询,恶意软件就会使用GetModuleFileName找到自己的可执行文件名,并将结果与硬编码的文件路径C:\Windows\Kbwgmwu.exe进行比较。如果名称不匹配,则开始“安装(installation)”例程。否则,程序似乎会继续其常规执行。如果文件名不同,恶意软件会使用我们在调试器中找到的注册表键值创建另一个注册表键值:
SYSTEM\CurrentControlSet\Services\Ruiswe wgzawios
这是文件必须作为admin运行的第一个迹象,因为它试图创建一个需要管理员权限的HKLM注册表值。有趣的是,对于一个“高级(Advanced)”恶意软件,当它访问注册表键值失败时,我没有看到错误处理,但我仍选择继续以防万一它改变了当前用户注册表。无论是否添加了注册表键值,恶意软件都会将其自身复制到Windows目录下,名称为 Kbwgmwu.exe。为此,CopyFile将被导入并执行。再一次,当程序以常规用户的身份运行时,它将失败,并且不会尝试处理错误。
一旦文件被“复制(copied)”,恶意软件就会导入 ShellExecute。然后,恶意软件会得到一个正在运行的进程列表(与RunDLL循环一样),并循环遍历它,将每个值与Kbwgmwu.exe进行比较。如果没有匹配,则调用ShellExecute,执行Windows目录中的文件 Kbwgmwu.exe。一旦文件被“执行(executed)”,恶意软件将循环回到进程搜索函数,以检查 Kbwgmwu.exe是否真的在运行。由于Kbwgmwu.exe不存在(因为恶意软件没有提升权限),ShellExecute会失败。这个循环运行了4次,然后退出,这似乎是到目前为止唯一的错误处理形式。
当恶意软件退出(并且原始文件被删除)时,我运行了它的另一个实例来查看是否有任何文件名或注册表键值发生了更改。只有两个值改变了,但它们似乎并不重要。现在是时候以管理员身份调试这个样本了,看看恶意软件究竟能做些什么。
我跳过了一些区段,直到我到达添加了注册表项的那一部分,然后检查注册表。果然,新创建的键值就在那里。
注册表也被硬编码到二进制文件中,因为它对样本非常重要,用以检查以前的样本。在创建键值后,将一个值添加到它—— Releice Name,并且所设置的数据似乎是随机的。在本案例中,数据读取Uuzvmm ceypla。这显得非常神秘。
我注意到这个注册表创建函数运行了好几次,所以我在每次调用它时都放了一个断点,并最终找到了一个新的注册表键值——Uuzvmm ceypla。这个键值内部设置了一个值,表示为 ConnectGroup。这个值的数据更加神秘—— ĬÉÏÖÖ×é。接下来,程序在键值中创建另一个值,称为MarkTime。写入此值的数据是当前时间,这可能是恶意软件用来查看它存活了多长时间的指标。 一旦 MarkTime被写入注册表,主注册表函数就会退出,并调用CopyFile,这次是成功的。
现在文件已被成功复制,恶意软件使用OpenSCManager打开服务管理器 。这也体现了需要管理员权限——必须是admin才能打开服务管理器。然后使用CreateService创建一个服务 ,其名称为 Uuzvmm ceypla,与注册表项名称相同,被赋予随机生成的描述。该服务被设置为自动启动,并链接到Windows目录中的可执行文件Kbwgmwu。然后,恶意软件将调用 StartService 以执行 Kbwgmwu.exe。
然后,对服务的描述进行编辑,以显示一个更长的随机字符串。我并不能够完全确定它为什么这样做,但它无论如何都会这样做。在描述更改后,我检查了注册表键值,它包含了更多的值:
在调试阶段,我没有连接网络,所以很有趣的是看到这个样本正在通过UDP进行监听。我相信这可能是一个错误,因为我没有看到任何WSAStartup或监听被调用。
现在我已经看到了它以管理员身份运行,是时候弄清楚如果我运行了恶意软件,就好像它刚安装一样会发生什么。我将虚拟机重新启动到一个干净的状态,并运行原始恶意软件,以便它能够将其自身植入系统。一旦Kbwgmwu.exe被执行,我将一个调试器附加到它并重新启动恶意软件。这一次,当恶意软件检查了文件名称后,它将继续沿着下图中右边的路径前行,而不是左边的。
我遇到了字符串Cao360被作为CreateEvent的一个参数推送 ,于是我决定赶紧通过谷歌搜索来看看发生了什么。首先出现的一个结果是一个趋势科技关于TROJ_BEAUGRIT介绍页面的链接。我没有看到任何关于木马本身的分析,但是我所看到的信息似乎与我的分析结果相关。同时,我也没有足够多的关于Gh0stRat的信息来证明这个样本不是 Gh0stRat,所以我决定暂时忽略它。
在注意到Cao360后不久,我发现了三个非常有用的字符串—— IP地址、URL和“123456789”,被移入一个内存地址中。之所以说它们有用,是因为它们表明连接将很快启动,恶意软件也将很快连接到攻击者C2服务器。果然,在继续执行程序之后,WSAStartup被调用了。为了使用Winsock来创建网络连接,必须调用WSAStartup 来初始化库。再往下,恶意软件将调用connect,为的是连接到我们在样本中看到的IP地址。当我断掉网络连接时,恶意软件试图连接回来,它失败了。我重新连线,启动了Wireshark,并运行connect函数。恶意软件通过端口8000建立了与C2服务器的连接。我在网上搜索了这个URL,并在滥用IP的网站上发现了几个hit,尤其是这个。它位于中国,根据滥用报告,最近似乎相当活跃,端口扫描并暴力破解不同的服务。基于中国已经禁止了VPN民用的事实,这个IP地址很可能表明了攻击者的真实地址,但也可能是利用被攻陷的主机作为代理,这一切都取决于技能水平。
一旦成功建立了连接,恶意软件将使用beginthreadex创建一个新线程,并在该线程中继续执行。
总结
l 该程序被执行
l 表单3用于文件名、注册表键值等的随机字符串
l 将URL和IP地址写入程序内存,以备后用
l 在正在运行的进程列表中检查RunDLL32.exe
l 如果它正在运行,执行taskkill来停止它的运行
l 否则,继续
l 形成完整的注册表键值SYSTEM\CurrentControlSet\Services\Ruiswe wgzawios
l 检查键值是否存在
l 如果该键值不存在,则关闭句柄
l 恶意软件会将其当前名称重新命名,并将其与%Windows%\Kbwgmwu.exe路径进行比较
l 如果字符串匹配,则开始“安装(installation)”例程
l 恶意软件创建注册表键值SYSTEM\CurrentControlSet\Services\Ruiswe wgzawios
l 值“Releice Name”被写入注册表键值,数据是随机的
l 随机数据之后将用于在SYSTEM\CurrentControlSet\Services\%s上创建另一个键值
l 值“ConnectGroup”被写入注册表键值,数据为“ÄÉÉSÉ·Ö×é”
l 值“MarkTime”被写入到注册表键值,数据是当前的数据和时间
l 值“Description”被写入到注册表键值,数据是三个随机单词
l 值“DisplayName”被写入到注册表键值,数据是随机的
l 恶意软件将最后部分写入注册键值,然后继续
l 调用CopyFile,恶意软件将自身复制到C:\Windows\Kbwgmwu.exe
l 管理员权限:
l 恶意软件在开始时使用随机数据创建服务
l 此服务设置为自动启动并执行C:\Windows\Kbwgmwu.exe
l 然后调用StartService,执行新创建的服务。
l 用户权限:
l 恶意软件会检查Kbwgmwu.exe的运行实例
l 如果没有找到,则使用ShellExecute 执行C:\Windows\Kbwgmwu.exe
l 这个过程会循环4次,然后调用ExitProcess
l 如果字符串匹配,并且原始注册表键值存在,程序则将继续执行
l 调用WSAStartup,初始化WinSock
l 恶意软件使用connect调用连接到C2 IP地址
l 调用BeginThreadEx,创建第二个线程以恢复程序的执行
IOCs
MD5:abdabfea475959703fb1957413b39cad
C2服务器:218.60.67.75
文件路径:C:\Windows\Kbwgmwu.exe
注册表键值:SYSTEM\CurrentControlSet\Services\Ruiswe wgzawios
审核人:yiwang 编辑:边边