样本信息
彩虹猫病毒是一个基本的恶搞病毒,没有采取隐藏或者免杀等技术,适合新手分析。该病毒会修改MBR主引导扇区,以此来破坏电脑的正常启动,属于MBR病毒。在修改MBR后,电脑蓝屏,Windows无法启动,一直播放一个彩虹猫的画面。

运行样本
双击加载病毒,会出现这样的2个提示框,告知你这是一个恶搞程序,是否要运行,

点击确认过后弹出记事本程序。

之后会出现:
- 6个MEMZ进程
- 多个浏览器窗口
- 鼠标不受控制
- 窗口颜色发生变化
- 弹出很多图标
- ...

任意关掉一个MEMZ进程,或者关闭计算机,系统就会崩溃蓝屏,重启电脑之后,会发现无法登陆系统,一只彩虹猫随着音乐在那儿跳。这说明MBR已经被修改,无法引导操作系统的启动。


静态分析
首先使用PEID和ExeInfoPE对样本进行查壳,查壳结果如下:

PEID查出有ASProtect壳,但是拖入ida似乎是没壳的,很奇怪。
StudyPE+查看导入表

导入函数中我们需要注意如下API函数:
功能 |
dll |
API |
改变窗口 |
GDI32 |
bitblt、stretchblt |
调用外部程序 |
SHELL32 |
ShellExecute |
播放音乐 |
WINMM |
PlaySoundA |
鼠标失控 |
USER32 |
SetCursorPos、GetCursorPos |
建立消息循环 |
USER32 |
GetMessage、TranslateMessage、DispatchMessage |
设置消息钩子 |
USER32 |
SetWindowHookEx、UnhookWindowHookEx、CallNextHookEx |
进程提权 |
ADVAPI32 |
OpenprocessToken、LookupPrivilegeValue、AdjustTokenPrivileges |
遍历进程 |
KERNEL32 |
CreateToolhelp32Snapshot、Process32First、Process32Next |
将样本载入ida,整体上看start()
函数,函数大体上是由两个if判断组成。
由于start()
函数大体上可以分成三个部分:启动部分、watchdog部分、main部分。
启动部分
在最开始,程序先获取窗口长、宽和命令行参数。

由于我们第一次双击样本时自然是不带参数的,于是程序流跳转到下面两个弹窗的if判断部分。
如果用户在这两个提示窗口都点击了确认,系统则会分配局部内存对象;
以"/watch2dog"为参数创建5个名为MEMZ的进程。

之后以"/main"为参数再生成一个MEMZ的进程。
到这里,样本创建了6个MEMZ的进程。
然后SetPriorityClass
函数把main进程的优先级设置为最高。

最后,用ExitProcess
函数结束自己的进程。至此,启动部分结束。
watchdog部分
首先判断是否为”/watchdog“为参数的MEMZ进程,如果不是,创建线程,注册窗口并进行消息循环

启动阶段创建的5个以“/watchdog”为参数的MEMZ进程。这5个进程一共应该创建了5个线程。我们进入sub_40114A看看这个线程具体干了些什么事。
sub_40114A
首先LocalAlloc
在堆中分配空间用来存路径字符串,然后GetCurrentProcess
获取当前进程句柄,然后GetProcessImageFileNameA
获取进程路径。
然后一个while死循环,其中大概可以分为两个部分:
CreateToolhelp32Snapshot
拍摄进程快照,再用Process32FirstW
和Process32NextW
进行遍历。do-while循环统计MEMZ进程的数量,将其存入v4变量。而sleep函数的存在也使得while死循环每隔一段时间统计当前MEMZ进程的个数并存放在v4变量中。
v4存放当前遍历到的MEMZ进程数量,而v7存放上一次遍历到的MEMZ的进程的数量,一旦V4的值小于v7,代表如果我们关闭了一个MEMZ进程,那么就会被if检测语句检测到,执行sub_401021函数内容。结合之前运行病毒我们可以推测sub_401021就是蓝屏关机。

sub_401021
这个函数就有意思了,
do-while循环20次创建了20个线程,每次sleep0.1秒;而紧接着RtlAdjustPrivilege
提权过后NtRaiseHardError
制造系统蓝屏;
之后OpenProcessToken
获取进程token,AdjustTokenPrivilege
利用得到的进程token提权过后ExitWindowsEx
强制注销系统。

StartAddress
线程函数指针StartAddress
点不开,我们直接查看汇编代码如下:

SetWindowsHookEx
和UnhookWindowsHookEx
用于给窗口下钩子,回调函数fn
中看具体操作。

code=等于3代表着窗口即将被创建,lParam表示该窗口的基本信息,创建窗口之前修改当前窗口的这些信息用于随机修改窗口的位置。
有26条消息保存在lpText所指向的地址中。使用sub_401A55
获取随机数,ds:dword_402AD0
存放的值为0x1A,随机数对0x1A取余,结果存放在edx寄存器,以实现在26条消息中随机选取一条MessageBoxA
弹出显示。


至此我们确认了sub_40114A函数的作用,正如我们上面的猜想,sub_40114A函数确实制造了蓝屏关机,先创建20个线程弹出大量位置和内容都随机的窗口,再蓝屏、强制关机。
sub_401000
sub_401000是个回调函数。16和22分别对应窗口消息WM_CLOSE
和WM_ENDSESSION
,而WM_CLOSE
或WM_ENDSESSION
消息是在系统关机时,由操作系统发送给各个窗口。
[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!