一、简介

2021年9月1日,该样本images.exe首次在VT上被提交。该样本主要是针对Windows10以及往前系统版本进行攻击,是一个32位的PE文件。images.exe文件其实现仅是一个外壳程序,目的是用来加载和保护真正的RAT程序Liebert.bmp。在分析过程中,发现Liebert.bmp具有大量与WARZONE RAT相似的特征,但是又不完全相同,所以猜测其为WARZONE RAT的新型或变种。

WARZONE RAT是一款功能完善的商业化远控木马软件,多次在美国安全事件中出现。相关信息显示,WARZONE RAT相关的广告信息最早于2018年出现在 warzone.io,目前仍在warzone.pw网站提供销售服务。

二、Procmon行为分析

第一次执行images.exe该RAT时,对于文件操作,只是往"C:\Users\ADMINI~1\AppData\Local\Temp"目录写入Liebert.bmp(可执行文件)。该进程还会再次启动一个自身进程。完成这些工作后,该进程就会自动结束退出。刚开始执行images.exe启动的进程id为716,进程716会启动2820,之后716结束自身。进程2820会创建进程1068,之后同样结束自身。进程1068会创建进程1040,进程1068结束。最后,进程1040会持久运行下去。

image-20211223102230242

进程2820是和首次执行的进程716同一可执行文件同一路径,后面两个进程文件一样,但是路径不一样。通过火绒剑,观察到进程2820会往"C:\ProgramData"目录写入"images.exe"。通过注册表访问devenum和msvideo多媒体组件的版本信息,该组件负责声音和视频的输入输出。在注册表 "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run\Images"中添加"C:\ProgramDataimages.exe"作为开机启动项。还在在注册表 "HKEY_USERS\S-1-5-21-277753965-883269607-389298561-500\Software\Microsoft\Windows\CurrentVersion\Explorer"创建"1I1AM29X9N"键,并设置一个键值"inst"存储一个长52字节的二进制数据。

image-20211223111855647

此外,进程2820还启动powershell执行命令"powershell Add-MpPreference -ExclusionPath C:",从而修改 Windows Defender 的设置,把整个c盘作为排除目录。

image-20211223112105203

进程1068在快速启动目录下复制了一份样本"Legit Program.exe"。火绒剑里只检测到了该文件打开,没有写入行为,实际应该是有的,但是猜测因为该样本基本是使用native api进行操作的,所以可能有些行为没有检测到吧。此外,还在"C:\Users\ADMINI~1\AppData\Local\Temp"目录下写入Liebert.bmp文件,这是一个可执行文件,且与之前的进程的映像文件不一样。

image-20211223113100950

image-20211222173352668

发现进程1068只有注册表值获取的行为而没有设置行为,猜测该样本通过注册表记录工作进展,因为这些进程的源文件都是同一个,需要一些外部因素来区分不同阶段的操作内容。

image-20211223113949783

进程1040通过启动cmd.exe打开了一个shell,同时启动powershell再执行一次"powershell Add-MpPreference -ExclusionPath C:"命令 。

image-20211223114432633

与C2服务器91.193.75.183:1014建立连接,并进行通信。

image-20211223120249742

三、分析images.exe

拖进ida中分析,通过观察可以知道是个MFC框架开发的程序,于是打算找到CxxApp的Run函数,从这里开始分析。也就是WinMain->sub_43CA7A( AfxWinMain )->sub_402220(Run函数)。

image-20211222215236052

函数sub_402220中大量的赋值语句,赋值的内容是Proc函数、sub_443AD0、sub_447B40、sub_448640、sub_447B40、sub_447B40、sub_447B40、sub_447B40、sub_447B40、sub_447B40、sub_447B40、sub_447B40、sub_447B40等函数的真实代码,对这些函数的代码段进行还原。

image-20211220182605632

之后,通过LineDDA函数设置Proc函数回调(计算出连接两点的线段上的每一个屏幕像素的坐标,每计算出一个坐标,该函数就会调用设置的回调函数)。

image-20211220184735816

sub_445B90函数对0x455000处数据进行解密,得到一个长48字节的密钥"tyhevdypzsjpuiasmysnitjslviuleullwqfqdbjycfasjqn"。

image-20211222215420276

解密算法如下:

image-20211220214158234

此外,该恶意样本通过事先使用需要使用到的导入库中导入函数开头的一串代码(长度为遇0结束)来计算出一个校验值,在执行时再通过这个校验值来查找出函数的入口地址。例如下图中的例子。

image-20211220215925990

库地址和函数地址查找和计算校验的原理类似,这里只贴函数地址计算部分。

image-20211220215716118

通过以下代码导入实现恶意样本开机自启动需要用到的库和函数。

  v5[0] = 'o';
  v5[1] = 'l';
  v5[2] = 'e';
  v5[3] = '3';
  v5[4] = '2';
  v5[5] = '.';
  v5[6] = 'd';
  v5[7] = 'l';
  v5[8] = 'l';
  v5[9] = 0;
  v4[0] = 's';
  v4[1] = 'h';
  v4[2] = 'e';
  v4[3] = 'l';
  v4[4] = 'l';
  v4[5] = '3';
  v4[6] = '2';
  v4[7] = '.';
  v4[8] = 'd';
  v4[9] = 'l';
  v4[10] = 'l';
  v4[11] = 0;
  strcpy(CoInitializeEx, "CoInitializeEx");
  strcpy(CoCreateInstance, "CoCreateInstance");
  strcpy(SHCreateItemFromParsingName, "SHCreateItemFromParsingName");
  strcpy(SHGetSpecialFolderPathW, "SHGetSpecialFolderPathW");
  v10 = sub_448640(0x22D3B5ED);                 // 获得ntdll.dll内存加载基址
  v9 = sub_448640(0x7040EE75);                  // 获得kernel32.dll内存加载基址
  a1[1] = sub_4488A0(v10, 699883401);           // 获得RtlInitUnicodeString
  if ( !a1[1] )
    return 0;
  a1[2] = sub_4488A0(v10, -147079866);          // 获得RtlDecompressBuffer
  if ( !a1[2] )
    return 0;
  *a1 = sub_4488A0(v10, 50846499);              // 获得LdrLoadDll
  if ( !*a1 )
    return 0;
  a1[7] = sub_4488A0(v9, -342440432);           // 获得CreateFileW
  if ( !a1[7] )
    return 0;
  a1[8] = sub_4488A0(v9, -1407036457);          // 获得CopyFileW
  if ( !a1[8] )
    return 0;
  a1[3] = sub_4488A0(v9, -818824417);           // 获得GetProcAddress
  if ( !a1[3] )
    return 0;
  (a1[1])(v3, v5);
  v8 = (*a1)(0, 0, v3, &v7);
  if ( v8 < 0 )
    return 0;
  (a1[1])(v3, v4);
  v8 = (*a1)(0, 0, v3, &v6);
  if ( v8 < 0 )
    return 0;
  a1[4] = (a1[3])(v7, CoCreateInstance);
  if ( !a1[4] )
    return 0;
  a1[9] = (a1[3])(v7, CoInitializeEx);
  if ( !a1[9] )
    return 0;
  a1[6] = (a1[3])(v6, SHGetSpecialFolderPathW);
  if ( !a1[6] )
    return 0;
  a1[5] = (a1[3])(v6, SHCreateItemFromParsingName);
  if ( !a1[5] )
    *a2 = 1;
  return 1;

sub_444630函数会调用两个自定义的解密函数对一串硬编码的数据进行解密,第一次使用之前解密出来的48字节密钥解密,第二次只是使用自定义的异或函数进行解密,最终会解密出一个exe文件。

image-20211221113417069

sub_445DE0函数将该exe文件命名为"Legit Program.exe",并写入启动目录(Windows特殊目录)C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup,实现自启动。此外,经过MD5值比对,发现"Legit Program.exe"与该恶意样本内容是一致。

image-20211221114913794

sub_447EF0函数中导入大量与远程进程注入有关的api。

image-20211221164739657

sub_4425A0函数中通过调用sub_4421E0函数获得远程注入的目标"\System32\scvhost.exe"和"\System32\WerFault.exe",接着调用CreateProcessInternalW函数创建目标进程,并调用NtMapViewOfSection将该RAT的的几个节区映射进去。

image-20211222112232809

四、Liebert.bmp分析

在分析进程1040时,发现其将"Liebert.bmp"文件映射入内存中并执行,且与C2的网络活动都在该文件映射的模块中。

从Main函数(sub_413435函数)开始分析,使用计算自身映像的MurmurHash,并以此值为名创建一个事件。

image-20211224104357736

修改注册表"Software\Microsoft\Windows\CurrentVersion\Internet Settings"键下"MaxConnectionsPer1_0Server"项和"MaxConnectionsPerServer"项, 即设置Web 服务器的最大 HTTP 连接数为10。

image-20211224104648557

在注册表中设置"Software\Microsoft\Windows\CurrentVersion\Explorer\"和"Software\Microsoft\Windows\CurrentVersion\Run\"的键值,实现开机自启动。

image-20211224111506098

sub_411AB9函数通过sdclt.exe进行提权,当 sdclt.exe 被标准用户权限的进程调用,它会以更高权限运行另一个进程 sdclt.exe。高权限的 sdclt.exe 进程会调用 C:\Windows\System32\control.exe,而control.exe 进程会以更高权限运行,并尝试打开 HKCU\Software\Classes\Folder\shell\open\command 注册表值。

image-20211224170226286

sub_412FD7函数设置Windows Defender的排除目录,命令如下图所示。

image-20211224170320022

sub_411136函数往快速启动目录上添加一个bat脚本用于获取Windows上存储的密码备份。

image-20211224170924507

在完成以上操作后,RAT会自动创建cmd.exe为子进程,并休眠1000秒。

image-20211224171200268

sub_4057FB函数创建与c2服务器的连接。

image-20211224171325503

sub_404C0A函数是一个命令解释函数,对输入的一个字符,调用对应的功能函数。

命令id功能72创建cmd.exe进程53使用密钥为“warzone160″的RC4加密算法加密数据并发送数据56初始化网络58通过ShellExecuteW打开或创建一个文件60同5374文件搜索48未知34下载和执行文件36键盘记录38同36,键盘记录40rdp远程桌面42启动一个反向代理44关闭反向代理32获取浏览器中保存的密码18打开摄像头20关闭摄像头22同5324同5326检查网络连接状态28上传文件30未知16结束通信线程10删除文件12杀死进程14与cmd.exe建立一个管道,也就是shell8读取目标文件并传输2枚举进程4获得磁盘驱动器信息6列举目录的所有子项

sub_4055A5函数进行网络数据传输,使用密钥为“warzone160″的RC4加密算法进行加密。

image-20211224113140915

sub_40882F函数通过SetWindowsHookExA设置系统钩子,进行键盘记录。

image-20211224122545421

sub_40E3FA函数设置远程桌面。

image-20211224123820846

sub_40275A设置反向代理。

image-20211224123931227

sub_40C1B2函数获取浏览器中保存的密码。

image-20211224124231558

sub_412D0A函数打开摄像头。

image-20211224124836586

sub_41171C函数检查网络是否连接。

image-20211224125615462

sub_40EAFB函数作用是与命令72创建的cmd.exe进程建立管道通信。

image-20211224164624613

sub_410D24函数枚举进程,获得当前的进程列表。

image-20211224165327197

五、IOC

样本1名称:images.exe

MD5:6edb91afaf154a24ded33849dedd9bda

SHA-1:469fc6186a06f7e68753ecf941576f7c2c3cc598

SHA-256:4c3c2596ae1617b31d06d9eed15e3d1c40c25d944e5418896c595dab6ae7f553

来源:https://app.any.run/tasks/e6ffb8fc-1b9a-4277-9f81-d772b9666a75/

C2地址:91.193.75.183:1014

样本2名称:Liebert.bmp

MD5:ecb95794953b7c6ad9934c826be3366d

SHA-1:eb3f590b2473d775721a38d0d8ae3295d9062840

SHA-256:2476fd8bad3916c27508ef2e33993002988c8452d8e750b9776f9648ba84ab0c

来源:由样本1释放

六、总结

如果发现计算机已经被该远控木马控制,可以尝试在用户的"AppData\Local\Temp"目录、快速启动目录(C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup),以及"C:\ProgamData"目录下寻找和删除images.exe和Liebert.bmp文件。打开任务管理其杀死子进程中有cmd.exe的进程树。打开regedit,查看 "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run\Images"是否有加入未知开机自启动项。还需要打开Windows defender,查看是否添加了未知的排除目录选项,如果有就删掉。目前,发现该病毒可以被Windows defneder检测到,所以最后要用denfender扫描以下电脑磁盘。做完这些,虽然还有些注册表残留,但是已经没有威胁性了,电脑回到安全状态。