-
-
[原创]彩虹猫样本分析记录
-
发表于: 2021-1-28 23:29 3585
-
0x01 基本信息
Name:MEMZ.exe
MD5:19dbec50735b5f2a72d4199c4e184960
SHA1:6FED7732F7CB6F59743795B2AB154A3676F4C822
样本运行后,效果可见ANYRUN,重启后,会出现如下彩虹猫动画:
首先使用PEiD查壳:
接下来查看其导入表及导入函数:
如下各函数与程序运行后效果相关联,播放提示音:
画面反色:
控制鼠标:
借由Procmon对该样本行为进行监控,发现其存在注册表相关操作:
0x02 静态分析
首先可以于Strings窗口看到如下字符串:
由start
函数进入,首先调用GetCommandLine
和CommandLineToArgv
两个函数获取命令行参数,之后进入if
判断有无参数:
知道整体逻辑后,笔者将分析划分为有参部分和无参部分。
0x02.1 有参部分——watchdog
程序对参数的判断有两个:一为"watchdog",一为"main"(详见后文)。本节分析watchdog
参数,main
参数将与MBR部分一起分析。
判断获取的参数是否为watchdog
,是则向下执行:
调用CreateThread
创建线程:
sub_40114A函数
在该函数中,首先调用GetCurrentProcess
及GetProcessImageFileName
函数获取此执行文件路径,之后进入一死循环。在此循环中, CreateToolhelp32Snapshot
用于拍摄进程快照, Process32First
、Process32Next
用于遍历进程,GetProcessImageFileName
用于获取进程路径:
此循环中包含一do-while
——对本次获得的进程路径与代码段开头获得的路径进行比较,若相同,则计数器加一,在最后会令v7
的值等于计数器v4
的值。当再次进入外层循环,若计数器v4的值小于v7(也就是上一次循环的计数器的值),程序会跳转进入到sub_401021
。
sub_401021函数
首先程序循环20次创建线程,该线程名为StartAddress。
然后通过GetProcAddress
获取ntdll.DLL
中RtlAdjustPrivilege
和NtRaiseHardError
函数地址。其中RtlAdjustPrivilege
用于快速关机(不保存,通知内核驱动后直接关电源)的提权,NtRaiseHardError
制造蓝屏。
GetCurrentProcess
、OpenProcessToken
用于打开进程Token,LookupPrivilegeValue
查找系统权限的特权值然后用AdjustTokenPrivileges
调整令牌特权。最后该函数返回ExitWindowsEx
,用于关闭系统。
如此可以推断,于sub_40114A
函数中调用sub_401021
函数就是为了在判断进程减少后(比如用户强行停止程序运行),控制系统蓝屏。
StartAddress
在20次循环中创建的StartAddress
线程,IDA于此处存在报错:
该错误是IDA反编译时栈不平衡造成的,IDA遇到ret指令后判断栈指针的值在函数开头和结尾不一致,因此报错:
StartAddress
功能是:获取当前线程的唯一标识符,然后对窗口下钩子,参数是fn
:
而这里的回调函数fn
的主要作用是生成窗口,且窗口大小随机:
接着调用sub_401A55
函数,该函数主要作用为调用CryptGenRandom
生成一随机数,并将其与0x1A进行除法运算:
将得到的数作为lpText
下标取字符串传递给MessageBox
函数弹出对话框:
回到主程序继续分析,创建一个新的窗口,lpParameters
参数为sub_401000
:
如此可以推断StartAddress
线程功能为生成大小随机且内容随机的窗口。
sub_401000函数
这个函数对Msg
的值做了一个判断:Msg
值为16,对应WM_CLOSE
;22对应WM_ENDSESSION
。当取值符合时,将跳转sub_401021
函数触发蓝屏关机,否则交由DefWindowProc
这个默认的窗口处理函数(即不处理):
0x02.2 无参部分
当程序无参数时,使用MessageBox()
函数弹出两个名为MEMZ弹窗——刚执行时出现的两个确认窗口:
两次弹窗确认后,获取进程路径并保存至v10
中,接下来五次循环的每一循环中,都会调用ShellExecute
——即生成五个相同的进程,参数为watchdog
:
参照watchdog
部分,这五个进程分别创建了一个线程。
五次循环结束后,用ShellExecute
函数生成一参数为main
的进程。而接下来的SetPriorityClass
函数用于设定当前进程的优先级——HIGH_PRIORITY_CLASS
(0x80,即最高):
最后程序退出:
0x02.3 main
首先打开磁盘驱动器(此处\\\\.\\PhysicalDrive0
为0号磁盘),若失败则结束进程。然后用LocalAlloc
函数从堆中分配0x1000个字节:
其后do-while
循环,一共循环303次,每次都向分配空间中写入数据,共写入303字节。而MBR的前446字节为启动代码,写入的303字节会覆盖MBR的启动代码部分。此操作直接破坏了MBR,如此一来无法将控制权转交给操作系统,而是执行病毒写入数据:
下一个do-while
循环写入了1952个字节,从510偏移处开始向后写入:
需要注意的是,这里前两个字节是0x55AA
——MBR结束标志,表明这是一个有效的主引导扇区:
写入完成:
向note.txt中写入如下内容,运行的时候会用记事本打开该文件:
如下do-while
共循环10次,每次循环令一个进程陷入休眠,然后再创建一个线程sub_401A2B
:
每次循环v9值加2,由下图可以看出其对应函数地址:
一共十个函数,能发现样本运行后的各种奇怪行为就是通过这些函数实现的:
sub_401A2B
配合传递参数v9实现图中函数调用:
0x02.4 程序流程图
0x03 MBR动调分析
方法是利用IDA的Remote GDB Debugger连接到虚拟机进行调试:
配置Hostname及Port:
Attach:
因为计算机启动后,会将主引导程序加载到物理内存地址0x7C00
处,故在此处下断点,让程序运行至此处再继续调试:
内存窗口查看:
0x7C12
处是int 13h中断,由寄存器传递参数如下:
从0柱面0磁头2扇区开始读,共4个扇区,写入地址经计算为0x7E00
:
执行至0x7C12
,各寄存器值如图:
因此当执行到0x7C14
时,剩余的字符已经加载到内存0x7E00
处,下图是加载后的内存:
从0x7c22
开始至0x7c5b
是一个循环,由si值的变化中可以判断,通过lodsb
读入的字符为MBR之后的1950个字符:
该循环主要通过lodsb
及stosb
向ES:DI指向的存储单元中写入字符,下图为写入后内存的变化:
当循环结束,可以观察到内存:
由此可以判断写入的字符将用于实现界面的字符、动画及音频。
0x7C67
处是int 10h中断。AH=0x10——颜色中断,触发了闪烁。
其寄存器的值如图:
在此之前,AL的值被写入端口43h(42h、43h端口均为音频程序的端口号)。这里的作用是将电路初始化,用于接收之后控制音频的计数值:
从61h端口读取一个字节数据到AL,将AL进行或运算后的值写入61h端口,此时值为00110011,作用是允许扬声器数据,定时器通道3会被启动:
之后的int 15h中断用于等待:
运行到0x7cb0
处,这里的42h端口接受AL的值作为控制字,使定时器准备接收计数初值。之后装入AH(计数值)用于建立将要产生的声音频率。此时61h端口的0/1bit均为1,因此当这段程序运行完后,虚拟机发出特定频率的声音。
动画出现前的字符则是依靠0x7C8A
处的一段程序完成的。
当运行至0x7CA2
时,只有当bl的值为0,才会往下执行至0x7CB0
并发出特定频率的声音,否则将跳转回0x7C8A
继续将字符打印在屏幕上:
这段则是依次输出不同颜色的可见字符,形成彩虹猫动画的初始画面:
当判断di的值为0xFA0
时,程序跳转至0x7CF0
,运行到0x7D03
时因不满足判断会再次跳转回0x7CDC
处,并再次依序输出字符形成下一个画面:
当判断成立继续向下运行则通过端口42h输出音频,并在最后跳转至0x7CDC
继续之前的循环。如此循环往复就能形成彩虹猫的动画及音频:
0x04 Notes
0x04.1 MSG
MSG
是Windows程序中的结构体。在Windows程序中,消息是由MSG
结构体来表示的。其定义为:
1 2 3 4 5 6 7 8 9 | typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; DWORD lPrivate; } MSG, * PMSG, * NPMSG, * LPMSG; |
第一个成员变量hwnd
表示消息所属的窗口;第二个成员变量message
指定了消息的标识符。第三、第四个成员变量wParam
和lParam
,用于指定消息的附加信息。最后两个变量分别表示消息投递到消息队列中的时间和鼠标的当前位置。
本次样本对Msg的取值判断为:Msg
值为16,对应WM_CLOSE
(一个窗口或者应用程序应该被关闭时发出WM_CLOSE
消息);值为22则对应WM_ENDSESSION
(WM_ENDSESSION
消息表示Windows即将关闭)。
0x04.2 42h,43h,61h三个端口号
早期的PC系列机中有一个专门用于定时的集成电路,型号是8253/8254。它有三个通道,第一个通道用于控制系统时钟正常运转;第二个通道用于存储器刷新;第三个通道通过一组电路与喇叭相联。
若将61H端口的bit0、bit1位都置成1,则相当于既打开了定时器又打开了开关,此时定时器产生的声音信号就会送到放大器推动喇叭发声。
打开扬声器的指令为:
1 2 3 | IN AL, 61H OR AL, 3 OUT 61H ,AL |
关闭扬声器的指令为:
1 2 | AND AL, 0FCH OUT 61H ,AL |
初始化8253的指令为:
1 2 | MOV AL, 0B6H OUT 43H ,AL |
0x04.3 BIOS中断
10H中断是BIOS对显示器和屏幕所提供的服务程序。
本次调用功能编号为:AH=0x10。当AL=03H,其作用为触发闪烁/亮显位。
13H中断是低端磁盘服务。
本次调用功能编号为:AH=0x02。当AL=0x4,CH=0x0,CL=0x2,DH=0x0,ES:BX=0x7E00,其作用为从0柱面0磁头的2扇区开始读4个扇区至0x7E00
,
15H中断
本次调用功能编号为:AH=86H。其作用为等待。
0x05 参考链接
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
- [原创]MS12-027及利用样本分析 16624
- [原创]Lab03-03样本分析记录 4215
- [原创]彩虹猫样本分析记录 3586