第一次逆向分析——彩虹猫病毒分析

最近在学习移动逆向,找到了彩虹猫病毒,就用来学习一下

观察和信息收集

彩虹猫病毒在运行之后,桌面会出现一些现象,比如:

  1. 自动弹出多个浏览器搜索窗口
  2. 鼠标异常晃动
  3. 窗口颜色怪异
  4. 反复出现系统提示音
  5. 出现多个MEMZ进程

出现的进程,用户尝试关闭任意一个,或者手动关闭计算机,都会遭至大量弹窗随后蓝屏,接着windows无法正常启动,只会循环播放一只彩虹猫附带的欢快的背景音乐,无论重启多少次都是如此。不会制作视频就不录制了 首先打开PEID分析该样本

第一次逆向分析——彩虹猫病毒分析

使PEID分析发现该样本可能使用ASProtect v1.32进行加壳,有点难度啊 使用studyPE+查看样本的导入表,发现了很多的函数,根据前面运行出现的情况可以进行简单的分类

第一次逆向分析——彩虹猫病毒分析

明显的现象

一、弹出多个浏览器搜索窗口——ShellExecute(windows的API函数,是执行可执行文件(exe)或任何关联文件(doc、txt、xls等))

二、鼠标异常晃动——SetCursorPos、GetCursorPos(SetCursorPos,将光标移动到指定的屏幕坐标。如果新坐标不在最近一次ClipCursor函数调用设置的屏幕矩形内,系统会自动调整坐标,使光标停留在矩形内。)(GetCursorPos,检索鼠标光标的位置(以屏幕坐标为单位))

三、桌面出现奇怪图标——Drawlcon(将图标或光标绘制到指定的设备上下文中)

四、窗口颜色怪异——BitBlt、StretchBlt(BitBlt:该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。)(StretchBlt:函数从源矩阵中复制一个位图到目标矩阵,必要时按目标设备设置的模式进行图像的拉伸或压缩。也即是将内存中的位图拷贝到屏幕上,并且可以根据屏幕画图区的大小来进行伸缩,适应响应的屏幕(或图像控件)。

五、反复出现系统提示音——PlaySoundA(windows用来播放声音的API函数)

六、出现多个MEMZ进程——ShellExecute(windows的API函数,是执行可执行文件(exe)或任何关联文件(doc、txt、xls等))

不能直接关联、但经常成对出现完成某些功能

一、OpenProcessToken、AdjustTokenPrivilege、LookUpPrivilegeValue——给进程提权

二、GetMessage、TranslateMessage、DispatchMessage——建立消息循环

三、CreateToolhelp32Snapshot、Process32First、Process32Next——遍历进程

四、SetwindowsHookEx、UnhookWindowsHookEx、CallNextHookEx——给窗口下钩子

五、LoadLibrary、GetProcAddress——加载库并导入函数

入口

使用IDA载入样本,定位入口函数start并获得伪代码(和源码存在差异)

第一次逆向分析——彩虹猫病毒分析

分析下得到的伪代码,start运行之后调用了GetCommandLineW()和CommandLineToArgvW(),阅读资料可知,GetCommandLineW()的返回值是指向当前进程的命令行字符串的指针;CommandLineToArgvW()是解析Unicode命令行字符串并返回指向命令行参数的指针数组,以及此类参数的计数,其方式类似于标准C运行时argv和argc值。由此可得出在start函数的其实部分调用这两个函数获取进程参数,之后整个start函数就根据进程参数分成了几大块

if (参数数量 > 1)
{
 if(参数 == "/watchdog")
 {
  //....
 }
 if(参数 == "/main")
 {
  //....
 }
}
else
{
 //...
}

第一次运行程序是不带参数,先来看看这部分

无参数部分

从代码中可以看到首先调用了MessageBoxA()函数,然后弹出两个警告信息提示框,当我们点击确认两个警告提示框之后GetModuleFileNameW()获取当前进程并保存,保存地址为LocalAlloc申请的空间。接着由do while执行五次循环,每次循环调用一次ShellExecuteW(),参数是刚才样本得到的路径地址,以及字符串”/watchlog”,也可以说是以参数”/watchlog”生成五个MEMZ进程。

第一次逆向分析——彩虹猫病毒分析

在组后调用ShellExecuteExW函数以”/main”为参数生成了一个MEMZ进程。Ex后缀的函数为加强函数,表示该函数的扩展,A是ANSI版本,W是UNICODE版本,ExW则是扩展版的UNICODE版。该函数接受了一个SHELLEXECUTEINFOW结构体,结构体中设定了进程路径和执行参数,和前面区别不大。

第一次逆向分析——彩虹猫病毒分析

随后这里调用了SetPriorityClass,其中对hprocess成员赋值为0x80,查看MSDN得知该值意味着创建的进程将拥有最高的响应优先级,最后调用ExitProcess()结束当前进程。

现在知道了6个MEMZ.exe的进程是怎么来的:最开始双击生成了一个进程,原始进程调用ShellExecuteExW函数以”watchdog”生成了五个进程和一个以”/main”为参数的进程,然后原始进程结束自己,当我们查看时存在6个进程。

“watchdog”部分

接下来我们看下”watchdog”部分的内容

1、主体

第一次逆向分析——彩虹猫病毒分析

根据代码来看,首先CreateThread创建一个进程,IDA自动命名为sub_40114A,以watchdog为参数生成运行的MEMZ.exe进程有五个,这里看到的创建一个进程是”某个进程”的行为。

2、子函数”sub_40114A”

第一次逆向分析——彩虹猫病毒分析

根据代码可以看到调用了LocalAlloc、GetCurrentProcess、GetProcessImageFileNameA三个函数用来获取当前进程路径,LocalAlloc申请空间用来存路径字符串,GetCurrentProcess获取当前进程句柄,GetProcessImageFileNameA指向接受可执行文件的完整路径的缓冲区的指针。

<!--注:-->
 <!--进程句柄:每个进程都会有一个句柄表,来保存当前进程获取的内核对象句柄及其他信息。当进程获取一个内核对象
,操作系统会自动将该对象信息插入当前进程的句柄表,并返回类似于索引的句柄。因此每个内核对象的句柄在不同的进程中基本是不一样的。-->
 <!--伪句柄与真实句柄:
GetcurrentThread()和GetcurrentProcess()函数获得的句柄就是伪句柄。当我们调用GetcurrentThread()和GetcurrentProcess()时,总是会返回值0xfffffffe(-2),0xffffffff(-1)。这就是伪句柄,他们并不反映真实的句柄信息,仅用来作用于当前线程进程本身。-->
 <!--伪句柄注意事项:
-->
  <!--1、伪句柄仅限作用于当前线程进程,超出了当前线程进程便没有任何意义。
-->
  <!--2、伪句柄不用调用CloseHandle函数关闭,因为伪句柄不是真正的句柄,因此不需要CloseHandle来关闭。
(即使调用了也没有任何影响,CloseHandle会返回errorcode ERROR_INCALID_HANDLE)。-->
 <!--获取真实句柄:
可以利用DuplicateHandle获取线程或进程的真实句柄,该函数常用来从进程A中来赋值一内核对象句柄并使B进程可用。需要注意的是,通过DuplicateHandle获取的真实句柄,需要CloseHandle进行关闭。-->

接着一个while循环把后面的代码都包了进去,该while循环的条件永远为真,是个死循环。在循环内部使用CreateToolhelp32Snapshot获取进程快照,以及这些进程使用的堆、模块和线程,再用Process32FirstW和Process32NextW进行遍历,每当遍历到一个进程时都要获取他的路径,并和之前获取的路径对比,如果相同就让计数器加一,当遍历完所有进程后,就统计出了MEMZ.exe的进程个数。由于sleep函数的存在,死循环每隔一段时间就能统计出当前MEMZ.exe进程的个数并存放在v5变量中,然后先判断v5和v8的大小,再让v8保存v5的值。

这样就形成了v8永远只保存v5最大的值,一旦v5的值小于v8就会被if语句监测到,并进入sub_401021子函数。在运行程序的时候发现只要MEMZ.exe的进程数量减少就会蓝屏重启,即sub_401021就是完成蓝屏重启的。

第一次逆向分析——彩虹猫病毒分析

3、子函数sub_401021

第一次逆向分析——彩虹猫病毒分析

出了点意外,子函数开头是一个do while循环,循环次数为20次,用CreateThread创建线程,双击之后却不跳转,输出窗口存在一个报错。

第一次逆向分析——彩虹猫病毒分析

键盘按G输入地址4010FE可以跳到StartAddress的代码。

第一次逆向分析——彩虹猫病毒分析

可以观测到MessageBoxA用于弹出消息,存于IpText所指向的地址中。使用sub_401A55获取随机数保存在v3,v3对0x1A取余以实现在消息中随机选取一条并显示。

第一次逆向分析——彩虹猫病毒分析

在这里SetWindowsHookEx和UnhookWindowsHookEx用于给窗口下钩子,所做的操作在fn里面,if判断,code==3时创建目标窗口,IParam表示窗口基本信息(坐标,大小等),修改这些信息可以在窗口真正创建之前生效,下面的代码表示随机修改窗口的位置。

第一次逆向分析——彩虹猫病毒分析

函数的最后部分,分为两块,一块是使用LoadLibraryA调用ntdll库,GetProcAddress获取函数地址,这两个函数属于未公开的windows API,这种方式属于隐式调用。随后依次调用这两个函数,主动引发蓝屏。另一块先用OpenProcessToken等函数给当前进程提权,然后使用ExitWindowsEx函数主动关闭windows。至于提权是因为ExitWindowsEx关闭windows需要相应的权限。

第一次逆向分析——彩虹猫病毒分析

即sub_401021确实是一个强制关机的函数,先创建线程用于弹出大量位置和内容都随机的窗口,再使用蓝屏或退出windows的方式强制关闭计算机。

4、注册并创建窗口

watchdog的主体部分,在创建了sub_40114A后,调用RegisterClassExA注册了一个名为”hax”的用户自定义窗口类型,并用CreateWindowExA创建。


第一次逆向分析——彩虹猫病毒分析

一个小问题:传递给RegisterClassExA函数的结构体变量pExecInfo定义为了SHELLEXECUTEINFOW类型而不是该函数所需要的WNDCLASSEXA类型,属于IDA识别错误。

第一次逆向分析——彩虹猫病毒分析

5、函数sub_401000

在创建线程的位置使用CreateThread创建之后存在一个参数lpParameters,调用了sub_401000,跟过去看下,这里看到是个if判断,Msg=16对应窗口消息WM_CLOSE,Msg=22对应窗口消息WM_ENDSESSION(窗口消息列表 – WineHQ Wiki),如果消息为WM_CLOSE或者WM_ENDSESSION,则调用sub_401021强制关机,而WM_CLOSE或WM_ENDSESSION消息是在系关机时,由操作系统发送给各个窗口。如果不是这两个,则不做任何处理,转交给DefWindowProcW这个系统默认处理函数来处理消息。

第一次逆向分析——彩虹猫病毒分析

即sub_401021这个强制关机函数在两处被调用,一处是监测watchdog进程数量,如有减少就调用。一处是监测用户是否主动关机,如有也调用。

6、消息循环

接下来代码GetMessageW、TranslateMessage、DispatchMessageW三个函数通过查询MSDN得知都是为了实现消息的循环,完成消息的收取和派发。

第一次逆向分析——彩虹猫病毒分析

注:消息循环
关于消息循环的博客
https://www.cnblogs.com/zxjay/archive/2009/06/27/1512372.html
MSDN中关于创建消息循环的官方回答
https://docs.microsoft.com/en-us/windows/win32/winmsg/using-messages-and-message-queues

“/main”部分

1、主体

第一次逆向分析——彩虹猫病毒分析

在这里可以看到一个do while循环,以v8为计数器,循环内部使用CreateThread创建线程,循环跑10次(v8 < 0xA),一共创建10个线程。同时附带一个参数v9,赋予初始值off_405130,每次循环自增2,跟过去看下

第一次逆向分析——彩虹猫病毒分析

这里可以看到off_405130地址指向的是一块数据区,且十分规律。每组都是由一个dd类型的数据和4个db类型的数据组成,一共有10组。dd、db类型对应的数据大小,详细解释

db:data byte 1字节数据
dw:data word 1字数据
dd:data dword 双字数据
dq:data qword 四字数据
1字 = 2字节

这里的循环,v9被赋值off_405130并作为参数传入,sleep函数也用到了v9,将v9看作数组首地址,并每次取第1项(数组项从0开始)。每次循环v9都会自增2,由于v9的数据类型是DWORD,每次自增2就是自增两个DWORD的大小,即8个字节,随着循环的进行,v9和v9【1】的值会按如下所述变化:


第一次循环 第二次循环 第三次循环 第四次循环 ……
v9的值 0x00405130 0x00405138 0x00405140 0x00405148 ……
v9[1]的值 0x00405134 0x0040513c 0x00405144 0x0040514c ……

v9的值的指向都是不同的静态地址,v9[1]是Sleep函数的参数,指向是时间量(毫秒)。右键选择Double word解析长度,对所有时间量都进行操作

第一次逆向分析——彩虹猫病毒分析

然后选择10进制数据展示

第一次逆向分析——彩虹猫病毒分析

操作完之后ida显示这样

第一次逆向分析——彩虹猫病毒分析

简单查询可知,这种结构应该是结构体数组,构成如下:

struct tagFuncWithDelay
{
 DWORD pFunction;
 DWORD dwTimeDelay;
}
注:delay是c语言中的延时函数

10个结构体就都在这一个数组中被包含了

tagFuncWithDelay Array[9]

即这里创建了10个线程,并且每次创建都会有延时,这个延时和进程的函数放在一起,一共有10组,在一个大的数组off_405130里面。

2、子函数sub_401A2B

跟过来看一下,发现是一个while循环,但没看出来这里有什么用,看了各位大佬的分析都说的是这里利用函数和v9实现对那10个函数的调用(存疑)

第一次逆向分析——彩虹猫病毒分析

MBR部分

在这个样本中,最重要的部分MBR部分,完成了该样本的核心功能。

MBR全称是主引导记录(Master Boot Record),整个硬盘最开头的512字节就是MBR。计算机启动后会先运行MBR里的代码进行各种状态的检查和初始化工作,然后再把控制权交给操作系统(简单的说就是一个JMP指令跳到操作系统的起始代码),windows就加载好了。

第一次逆向分析——彩虹猫病毒分析

MEMZ病毒会直接覆盖整个MBR,让整个MBR变成了他自己的文件,破坏电脑的正常启动。

第一次逆向分析——彩虹猫病毒分析

MBR里面既有代码也有数据,开头的0-446字节是代码,紧接着就是数据,数据部分记录着硬盘的分区信息,结尾以固定的0x55 0xAA作为结束符。


第一次逆向分析——彩虹猫病毒分析

简单了解了MBR,我们来看下代码,先看/main为分析的部分

首先使用CreateFileA以文件形式打开主硬盘,也即PhysicalDrive0(“.PhysicalDrive0” 打开第一个物理驱动器)。紧接着用LocalAlloc分配了一段以0为初始值的内存空间,并拷贝两段数据到分配的内存空间。这两段数据第一段是byte_402118大小的304字节,第二段是byte_402248大小的1952字节,拷贝中间跳过了206字节。最后将内存空间的数据覆盖到主硬盘(PhysicalDrive0)的开头部分,原始MBR遭到破坏。由此判断第一段正好是覆盖了MBR的代码区域,所以这303字节是代码,第二段不属于MBR范围,而且高达1952字节,所以应该是用于显示动画的图像数据和音频数据。

第一次逆向分析——彩虹猫病毒分析

这里的0x12f和0x7A0通过进制转换就可以得到303和1952.

当这里将MBR进行覆盖之后,侵入也即宣告成功,同时作者写了一段话,这段话被写入note.txt文件中,并用windows自带的记事本打开。到这里整体的分析基本就完了,从头再整理下思路,写一下每段程序具体做了那些事情

第一次逆向分析——彩虹猫病毒分析

局分析

1、首先是导表中看到的dll

导入表名 作用
KERNEL32.dll 控制着系统的内存管理、数据的输入输出操作和中断处理
USER32.dll 创建窗口和发送消息,与用户界面相关
GDL32.dll 用来回值图像和显示文字
ADVAPI32.dll 负责对象的安全性,注册表的操控以及事件日志
SHELL32.dll 用于打开网页和文件,建立文件时的默认文件名的设置
WINMM.dll 用于低档的音频和游戏手柄
PSAPI.dll windows系统进程状态支持模块

2、函数流程图

第一次逆向分析——彩虹猫病毒分析

3、watchdog部分
1、主体

第一次逆向分析——彩虹猫病毒分析

2、子函数sub_40114A

第一次逆向分析——彩虹猫病毒分析

3、子函数sub_401021

第一次逆向分析——彩虹猫病毒分析

4、注册窗口

第一次逆向分析——彩虹猫病毒分析

5、消息循环
GetMessage、TranslateMessage、DispatchMessage这几个函数是为了实现消息循环,完成消息的收取和派发工作。
main部分
v2 = CreateFileA("\\.\PhysicalDrive0", 0xC0000000, 3u, 0, 3u, 0, 0);
// CreateFileA打开文件或I/O设备   //PhysicalDrive0表示本机的物理驱动器0
//首先打开PhysicalDrive0磁盘
    hObject = v2;     
    if ( v2 == (HANDLE)-1 )
    {
      v12 = 2  
    }
    else
    {
      v3 = 0;
      v4 = LocalAlloc(0x40u, 0x10000u);//从堆中分配0x10000个字节
      v5 = v4;
      do
      {
        ++v3;
        *v5 = v5[byte_402118 - v4];//循环303次写入303字节
        ++v5;
      }
      while ( v3 < 303 );
      //MBR的前446字节为启动代码,写入的303字节会覆盖MBR的启动代码部分。
      //此操作直接破坏了MBR,如此一来无法将控制权转交给操作系统,而是执行病毒写入数据
      v6 = 0;
      do
      {
        v4[v6 + 510] = byte_402248[v6];
        //循环1952次写入1952字节,从510偏移处开始向后写入,这次应该是病毒内容
        ++v6;
      }
      while ( v6 < 1952 );
      if ( !WriteFile(v2, v4, 0x10000u, &NumberOfBytesWritten, 0) )
        JUMPOUT(unk_40139D);
      CloseHandle(hObject);

第一次逆向分析——彩虹猫病毒分析

这里前两个字节,0x55AA是MBR的结束标志,表明这是有效的主引导扇区,然后是向note.txt中写入内容

 v7 = CreateFileA("\note.txt", 0xC0000000, 3u, 0, 2u, 0x80u, 0);
      if ( v7 != (HANDLE)-1
        && WriteFile(
             v7,
             "YOUR COMPUTER HAS BEEN FUCKED BY THE MEMZ TROJAN.rn"
             "rn"
             "Your computer won't boot up again,rn"
             "so use it as long as you can!rn"
             "rn"
             ":Drn"
             "rn"
             "Trying to kill MEMZ will cause your system to bern"
             "destroyed instantly, so don't try it :D",
             0xDAu,
             &NumberOfBytesWritten,
             0) )
      {
        CloseHandle(v7);                        // 关闭了一个线程句柄
        ShellExecuteA(0, 0, "notepad""\note.txt", 0, 10);// 打开外部程序notepad
        v8 = 0;
        v9 = (DWORD *)&off_405130;              // 存了十个有实际效果的函数
        do
        {
          Sleep(v9[1]);
          CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sub_401A2B, v9, 0, 0);
            // 调用上面的十个函数
          ++v8;
          v9 += 2;
        }
        while ( v8 < 10 );
        while ( 1 )
          Sleep(10000u);
      }
    }
    ExitProcess(v12);
  }

第一次逆向分析——彩虹猫病毒分析

off_405130里面存放的函数如下,里面有调用光标,有弹web窗口的… sub_401A2B实现函数调用

void __stdcall __noreturn sub_401A2B(LPVOID lpThreadParameter)
{
  int v1; // esi@1
  int v2; // ebx@1
  int v3; // edi@1
  int v4; // eax@2

  v1 = 0;
  v2 = 0;
  v3 = 0;
  while ( 1 )
  {
    v4 = v1--;
    if ( !v4 )
      v1 = (*(int (__cdecl **)(int, int))lpThreadParameter)(v2++, v3);
    ++v3;
    Sleep(0xAu);
  }
}

以上就是对memz样本的分析,由于对windows api、dll、c++语法不了解,所以写的时候是边查资料边写的,写的有点繁琐。

原文始发于微信公众号(安全小白):第一次逆向分析——彩虹猫病毒分析

版权声明:admin 发表于 2023年7月13日 下午9:07。
转载请注明:第一次逆向分析——彩虹猫病毒分析 | CTF导航

相关文章

暂无评论

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