最适合新⼿的病毒分析——彩虹猫病毒
本⽂为看雪论坛精华⽂章
看雪论坛作者ID:谁的狗哥
前⾔
彩虹猫是⼀款很有意思的病毒,结构也很简单,适合⼩⽩分析练⼿。这篇分析也是我的⼀个练习项⽬,不但展⽰了分析结果,也重点阐述了分析过程中遇到问题时的解决思路,尽量做到详细、多图、⽆死⾓,希望能对同样是新⼿的读者⼀点帮助。
样本名称:
MD5:19DBEC50735B5F2A72D4199C4E184960
SHA1:6FED7732F7CB6F59743795B2AB154A3676F4C822
实验平台:Windows 7 Ultimate With Service Pack 1
分析⼯具:PEiD v0.95、StudyPE x64 v1.11、IDA x32 v7.4、Bochs v2.6.9、VMWare WorkStation v15.
56、Olly ICE v1.10
⼀、初步观察和信息收集
拿到样本不要⼀来就拖进IDA和OllyDbg,在没有任何参考信息的情况下很容易迷失⽅向,应该先做最基本的观察,为之后的分析提供思路。特别是这次的彩虹猫样本,有很明显的⽤户能直接观察的特征。让我们先把病毒在虚拟机中运⾏起来。
双击病毒样本后接连弹出两个警告弹窗,希望⽤户明⽩运⾏病毒的风险。点击确定后,桌⾯会慢慢出现⼀些诡异的现象,⽐如:
•
⾃动弹出多个浏览器搜索窗⼝
•
⿏标异常晃动
•
窗⼝颜⾊怪异
•
反复出现系统提⽰⾳
•
出现6个MEMZ进程
这6个名为MEMZ的进程,⽤户尝试关闭任意⼀个,或者⼿动关闭计算机,都会遭⾄⼤量弹窗随后蓝屏,接着Windows ⽆法正常启动,只会循环播放⼀只彩虹猫附带欢快的背景⾳乐,⽆论你重启多少次都是如此。运⾏观察结束后再⽤⼀些基本的可执⾏⽂件信息查看⼯具进⾏勘察。
⾸先上场的是PEiD,监测到该样本可能使⽤了ASProtect v1.32进⾏加壳或加密,可能会给本次分析带来⼀点⼩困难。
接着使⽤StudyPE+查看样本的导⼊表,发现了很多有意思的函数,这些导⼊函数能给我们提供⼤量的信息,我把这些函数⼤致分为三类:
第⼀类:很明显能和观察到的现象直接联系:
•
⾃动弹出多个浏览器搜索窗⼝----ShellExecute
•
⿏标异常晃动----SetCursorPos、GetCursorPos
•
桌⾯出现奇怪图标----DrawIcon
•
窗⼝颜⾊怪异----BitBlt、StretchBlt
•
反复出现系统提⽰⾳----PlaySoundA
•
出现6个MEMZ进程----ShellExecute
第⼆类:不能直接关联,但常成对出现完成某些功能:
•
OpenProcessToken、AdjustTokenPrivilege、LookUpPrivilegeValue 给进程提权
•
GetMessage、TranslateMessage、DispatchMessage 建⽴消息循环
•
CreateToolhelp32Snapshot、Process32First、Process32Next 遍历进程
•
SetWindowHookEx、UnhookWindowHookEx、CallNextHookEx 给窗⼝下钩⼦
•
LoadLibrary、GetProcAddress 加载库并导⼊函数
第三类:不确定⼲了什么事或者我根本不熟悉
•
SendInput、GetSystemMetrics、DefWindowProc……
对于复杂的样本,还可以使⽤监控类⼯具看看样本对⽂件、进程、注册表、⽹络进⾏了哪些操作,不过这次样本⽐较简
对于复杂的样本,还可以使⽤监控类⼯具看看样本对⽂件、进程、注册表、⽹络进⾏了哪些操作,不过这次样本⽐较简单,以上信息已经⾜够指导接下来的分析⼯作了。
⼆、⼊⼝部分
使⽤IDA载⼊样本,定位到⼊⼝函数Start并按下F5获得伪代码,该功能极⼤地提升了样本分析的效率,毕竟看⾼级语⾔⽐看汇编还是快得多。
但是这些伪代码只是IDA根据现有信息猜测出来的,并不能保证100%准确,有的时候甚⾄会对我们的分析⼯作产⽣误导,⼀会你就能看到。现在让我们继续回到IDA⽣成的伪代码。
暂时别着急深⼊细节,先从整体把握⾛向。在start函数的起始部分调⽤Get CommandLineW、CommandLineToArgvW 获取进程参数,之后整个Start函数就根据进程参数分成了⼏⼤块,整理后其结构如下:
注意,这段体现start函数结构的伪代码并不是直接照搬⾃IDA,⽽是为了整体逻辑清晰⽽特意整理修改过的。接下来就要依次分析这三⼤部分,为了⽅便表述,这三个部分我称为“watchdog部分”、“/main部分”和“⽆参数部分” 。
我们第⼀次双击样本时⾃然是不带参数的,所以我们先来看start函数的⽆参数部分。
三、⽆参数部分
此处先是⽤MessagexBox依次弹出两个警告信息提⽰框,这也正是我们运⾏病毒时所看到的。若两个弹窗都被⽤户确认,使⽤GetModuleFileNameW获取当前进程的路径并保存,当然所保存的空间由LocalAlloc提前申请。
接着⽤do while执⾏5次循环,每次循环都调⽤⼀次ShellExecuteW,参数正是刚才得到的样本进程路径,以及字符串"/watchdog",即以“/watchdog”为参数,⽣成5个进程。
在最后调⽤了ShellExecuteExW以“/main”为参数⽣成了⼀个进程,⼀般带Ex后缀是加强版
函数,表⽰在普通版函数基础上进⾏了功能的扩展,这⾥特意⽤了⼀个功能更强的函数⼀定有特别的⽬的。
该函数接收⼀个SHELLEXECUTEINFOA结构体,结构体中设定了进程路径和执⾏参数,跟前⾯普通版函数传递的参数其实没什么区别。
关键是紧接着调⽤了SetPriorityClass,当中对hProcess成员复制为0x80,查看MSDN得知该值意味着创建的进程将拥有最⾼的响应优先级,最后调⽤ExitProcess使当前进程结束。如果你不会使⽤MSDN我在⽂末备注有介绍。
现在我们知道在观察阶段看到的6个进程是怎么来的了:最开始双击⽣成了⼀个原始进程,原始进程⽣成了5个watchdog进程和1个/main进程,然后原始进程迅速结束了⾃⼰,等我们打开任务管理器查看时,还存在6个。
IDA全称是交互式反汇编器(Interactive Disassembler),重点在于“交互式”,我们可以把⼿动分析后的任何想法和有⽤的信息都记录在IDA⾥,⽐如给IDA⾃动⽣成的变量和函数起⼀个有意义的名字,这些名字会在所有⽤到该变量或函数的地⽅⽣效。完成后应该像下图这样。
在后⾯的分析中,请⼤家⾃⾏完成注释的添加,为了后⾯的⽂章不剧透,我贴出来的图⼤部分还是未注释的状态。⾄此⽆参数部分分析完毕。
四、"watchdog"部分
1. 主体
该部分的主体代码量很少,我⼀张图就全展⽰清楚了,但⾥⾯的坑可⼀点都不少。
⾸先是CreateThread创建⼀个线程,IDA给⾃动命名为sub_40114A。在这⾥给⼤家提⼀个醒,以watchdog为参数运⾏的进程是有5个的,也就是说这⾥看到的创建⼀个线程是“某个进程“的⾏为,5个进程⼀共应该创建了5个线程,在后⾯的分析中⼤家也要注意这⼀点。我们进⼊sub_40114A看看这个线程⼲了些什么事。
2. ⼦函数sub_40114A
同样代码很少⼀张图概括完。前三个函数⽤来获取当前进程路径,顺便说⼀下这种多个函数配合起来做事的情况有很多,常常是最后⼀个函数完成关键功能,前⾯⼏个都是为它提供必要的参数,⽐如LocalAlloc申请空间⽤来存路径字符串,GetCurrentProcess获取当前进程句柄,这都是第三个函数要⽤到的。
接着⼀个⼤的while循环把后⾯的代码都包了进去,注意该while循环的条件永远为真,说明是个死循环。在循环内部使⽤CreateToolhelp32Snapshot给进程拍快照,再⽤Process32FirstW和Process32N
extW进⾏遍历,这都是⾮常常见的操作,我们在观察阶段查看导⼊表时也发现了这三个函数,这⾥就⽤上了。
当然光做进程遍历是没意义的,肯定要⼲点活。每当遍历到⼀个进程时都要获取它的路径,并和我们之前获取的路径对⽐,如果相同就让计数器加1,很明显这就是在看当前有多少个的进程。
当遍历完所有进程后,我们就统计出了的进程个数。然后最关键的地⽅来了,由于Sleep函数的存在,死循环每隔⼀段时间就能统计出当前进程的个数并存放在v4变量中,然后先判断v4和v7的⼤⼩,再让v7保存v4的值。
如此就形成了⼀个监测机制,v7永远只保存v4最⼤的值,⼀旦v4的值⼩于了v7就会被if语句监测到,并进⼊
sub_401021⼦函数。这不正好和我们观察阶段的发现⼀致吗?只要进程数量减少,系统就会蓝屏重启,这就是它的监测原理。反过来我们可以推测sub_401021就是完成系统蓝屏重启功能的。
3. ⼦函数sub_401021
前⾯进展得很顺利,到这⾥就碰到⿇烦了。在这个⼦函数的开头是⼀个do while循环,循环次数为20次,⽤CreateThread创建线程,这没什么特别的,像往常⼀样我们双击StartAddress准备去看这个线
程做了什么事,但是双击过后却没有任何反应,这其实是IDA的代码识别出现错误,相关问题我在第七节“IDA的⼀些问题”中做详细解释。
在这⾥为了不影响我们的分析主线,直接键盘按G输⼊地址4010FE就可以跳到StartAddress的代码。该处的MessageBoxA⽤于弹出消息,有26条消息保存在lpText所指向的地址中。使⽤sub_401A55获取随机数保存在v3,v3对0x1A取余以实现在26条消息中随机选取⼀条并显⽰。
⽽ SetWindowsHookEx和UnhookWindowsHookEx⽤于给窗⼝下钩⼦,⼲了什么事要到回调函数fn⾥去看。code==3表明⽬标窗⼝即将被创建,此时lParam表⽰该窗⼝的基本信息(坐标、⼤⼩等),修改这些信息可以在窗⼝真正创建之前⽣效,下⽅正是在随机修改窗⼝的位置。这些信息都可以在MSDN中查到。
sub_401021的后半部分是两种关机的⽅式:先主动诱发蓝屏关机,如果不成功则主动退出Windows。
前⼀种⽅式使⽤LoadLibrary加载ntdll库,再连续两次调⽤GetProcAddress获取两个函数地址,这两个函数是未公开的Windows API,只能⽤这种⽅式来隐式调⽤。随后依次调⽤这两个函数,主动引发蓝屏。
顺便提⼀下,很多恶意程序在隐式调⽤时会对函数名字符串先加密,要⽤的时候再解密,或者⼲脆不使⽤函数名⽽⽤函数编号,显然我们分析的样本没有做这种“隐蔽处理”。
后⼀种⽅式先⽤⼀系列函数给当前进程提权,然后调⽤ExitWindowsEx主动关闭Windows。为什么要先提权?调⽤ExitWindowsEx关闭Windows需要相应的权限,详情见MSDN。
总结⼀下,我们确认了之前的猜想,sub_401021确实是⼀个强制关机的函数,先创建线程⽤于弹出⼤量位置和内容都随机的窗⼝,再使⽤蓝屏或退出Windows的⽅式强制关闭计算机。
4. 注册并创建窗⼝
我们依次分析了函数开头->sub_40114A->sub_401021,已经陷⼊了太多细节,是时候回到watchdog的主体部分。这张图之前出现过,为了⼤家⽅便看我再次贴出来。在创建sub_40114A后,调⽤RegisterClassExA注册了⼀个名
为“hax”的⽤户⾃定义窗⼝类型,并⽤CreateWindowExA将其创建。
此处有个⼩问题,传递给RegisterClassExA函数的结构体变量pExecInfo定义为了SHELLEXECUTEINFOW类型,⽽不是该函数所需要的WNDCLASSEXA类型,这是IDA的识别出现了错误,为了不⼲扰主线分析,其讲解安排在了第七节”IDA的⼀些问题“。
5. 回调函数sub_401000
创建的窗⼝有⼀个回调函数sub_401000。经查询MSDN,常量值16和22分别对应窗⼝消息WM_CLOSE和
WM_ENDSESSION,那么整体含义就很明了了:该窗⼝回调函数会对窗⼝消息进⾏过滤,若消息为WM_CLOSE或者WM_ENDSESSION,则调⽤sub_401021强制关机(这个函数前⾯刚分析过)。⽽WM_CLOSE或
WM_ENDSESSION消息是在系统关机时,由操作系统发送给各个窗⼝。
text函数什么意思若是其他消息,则并不做任何处理,丢给系统默认处理函数DefWindowProcW。
如此⼀来,sub_401021这个强制关机函数在两处被调⽤。第⼀个是监测watchdog进程数量,如有减少就调⽤。第⼆个是监测⽤户是否主动关机,如有也调⽤。这和我们观察阶段看到的完全⼀致。
6. 消息循环
紧接着的代码 GetMessage、TranslateMessage、DispatchMessage被包进⼀个⼤的while循环,这是常见的操作,叫做“消息循环”。
由于在前⾯创建了窗⼝,并且还对发送给窗⼝的消息进⾏了过滤,意味着我们必须⾃⼰写消息循环完
成收取消息和派发消息的⼯作,否则创建的窗⼝是收不到消息的。Windows并不会⾃动帮我们完成消息循环,这在MSDN⾥有明确解释,给出两条参考链接:
⼀篇关于消息循环的博客:
MSDN中关于创建消息循环的官⽅回答:
五、"/main"部分
1. 主体
由于开头部分代码和MBR有极强的联系,我索性把它划到MBR章节了,到时候再⼀块说。让我们把窗⼝往下拉⼀拉,这⾥有⼀个do while 循环,/main部分的分析就从这⼉开始。
此处的do while循环以v8为计数器,内部⽤CreateThread创建线程,循环跑10次(v8 < 0xA),⼀共创建10个线程。这不由地让⼈好奇,创建这么多线程是要做什么?先别慌跳进去看,它还附带⼀个参数v9,并被赋予初始值off_405130,每次循环⾃增2。以off开头表明是某个静态地址,我们双击过去看看。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论