与疯狂的肆虐趋势相对应的,是“隐魂”木马超高的反侦察能力和极其复杂的制作技术:
从感染方式上来说,不同于恶意程序直接写入MBR的木马,“隐魂”入侵后选择了关机回调的方式伺机启动。电脑关闭前一刻是不少安全软件的监管盲区,“隐魂”就是趁这个空挡植入磁盘底层。同时,它还启动了多达5个白利用文件,以此与安全软件进行对抗。
从攻击手段上来说,“隐魂”木马使用了多个漏洞组合,这是在以往MBR木马中前所未见的。其中,于2015年曝光的老版本Adobe提权漏洞威力格外惊人,它能绕过不少安全软件直接在内核中执行任意代码,是黑客攻击的一个大杀器。
从反侦察能力上来说,“隐魂”可以说是迄今为止的集大成者,它的写入过程完全依靠驱动,不会留下任何落地驱动文件;它会通过RPC远程调用的方式创建进程,木马源头很难被追溯。更值得一提的是,“隐魂”的执行过程十分复杂,在每次写入动作之前,都会小心翼翼地检测电脑上是否存在网络抓包工具、进程监控工具、调试器、反汇编工具、虚拟机等,如果存在上述情况之一,就会即刻停止感染执行,很大程度上避免了被安全研究者逆向追踪。
“隐魂”的活跃量已经直逼暗云系列木马,复杂性和查杀难度则创造了史上新高。目前,360安全卫士已经率先拦截查杀了该木马,反病毒专家经过紧急分析,终于抓到了“隐魂”的狐狸尾巴,以下是对该木马的详细技术分析。
2感染分析
2.1加载图片
该安装包为一个播放器,带有一定播放功能,可能为二次打包的。
在运行该安装包后,会调用加载读取 释放出来的JPG图片。
验证图片完整性:
图1
然后将图片末尾数据拷贝到内存
图2
解密前数据为:
图3
判断进程调试信息后 异或0x93解密出代码:
图4
判断调试器信息代码为:
图5
2.2 ShellCode1
为异或 0x93后代码 代码大小为0x2d4。
异或后代码为:
图6
对应代码为:
图7
找Kernel32基地址
图8
而后申请内存 准备执行第二块ShellCode 大小为0x5800。
图9
调用第二块ShellCode:
图10
2.3 ShellCode2
入口处代码为:
图11
填充导入表 并检测内核调试器是否开启:
图12
检测内核调试:
图12(1)
对应结构体为:
图13
然后查找导入表中unzGetCurrentFileInfo64 挂钩:
图14
挂钩:
图15
等安装包后续 解压文件时候触发获取执行机会。
图16
获取额外数据 为第三块ShellCode并比对hash值是否一致,
然后调用自身函数解密数据 并拷贝ShellCode3到内存:
图17
而后设置安装CID环境变量值 并 IAT挂钩CreateProcessW。
图18
当安装进程创建时候 CreateProcessW IATHook被执行,恢复钩子 并执行第三块
ShellCode。
图19
创建线程执行,并且对调试器隐藏线程创建,并将下载地址传入。
图20
执行入口点函数
图21
2.4 ShellCode3
ShellCode3为自定义的文件格式 类似于PE 自身实现文件导入表 重定位修正。
执行入口点:
图22
修正导入表:
图23
检测调试工具信息:
图24
其中 IsKdDebuggerEnabled 依然为 KUSER_SHARED_DATA 结构标志KdDebuggerEnabled是否为0。
检测常用工具软件:
图25
常用工具集合为 一旦发现便不再感染。
图26
接着检查下是否已经被感染 防止再次感染,并且读取之前设置的CID环境变量信息
图27
调用网络相关函数下载之前的URL网址感染包
图28
而后准备执行下载下来的第四块ShellCode。
申请执行内存:
图29
执行函数
图30
2.5 ShellCode4
执行:
图31
然后解压里面带的相关资源:
图32
解压执行先对文件进行校验:
图33
通过节点名查找资源信息:
图34
而后申请执行空间。尽可能申请高端地址, 将第一块执行文件(ShellCode5) 大小为 0x23810拷贝入内存准备执行 :
图35
执行
图36
2.6 ShellCode5
ShellCode5 为公共部分代码 用于加载NE文件 和修正导入表 ,并设置好参数
参数通过共享内存设置的。
获取Kernel32基地址 并且获取LoadLibraryA,GetProcAddress,VirtualAlloc,VirtualFree函数地址。
图37
获取函数地址:
图38
Hash算法:
图39
而后申请执行内存 高端地址 为第六块Shellcode准备空间.
图40
而后设置调用参数
图41
而后将NE文件入口点设置在堆栈上 等函数返回后就执行第六块ShellCode
图42
2.7 ShellCode6
该部分模块主要为释放白利用模块 根据不同参数执行不同代码,
会检测调试器 对抗虚拟机,并且利用字体加载漏洞来加载驱动。
入口点函数为:
图43
在入口点会检测SMEP是否启用 为后续执行代码做准备
图44
Win7以下系统忽略该标志
图45
然后进入白利用相关文件释放 函数,该函数会读取SessionId 获取调试标志
一旦检测到被调试就退出。
图46
而后会读取系统信息,
配置文件是否忽略虚拟机标志。
图47
判断虚拟机方法为:
图48
具体实现为:
图49
图50
然后判断CPUID信息
是否为这几类虚拟机。
图51
获取BIOS信息判断虚拟机
图52
如果不是 则释放五个白利用中一个,
将文件写到Appdata目录。
图53
而后调用 COM IShellWindows接口运行该白利用:
图54
启用该进程后 会加载白利用的DLL 该白利用DLL 又会创建线程以不同参数(参数还是通过共享内存设置)执行 ShellCode6:
图55
再次运行自身(该白利用文件):
图56
执行后将ShellCode6 的NE代码共享到新创建的白利用进程:
图57
而后通过APC方式 执行该部分代码:
图58
然后创建rundll32进程 依然是执行ShellCode6,
Rundll32命令行为:
图59
依然通过 NtMapViewOfSection将Shellcode6执行代码共享到Rundll32
图60
直接通过 SetThreadContext修改EIP实现自身代码运行
图61
执行是ShellCode6
这次函数为:
图62
首先找到Null驱动的 FastIo 派遣函数表:
图63
找到NULL驱动入口点后
通过特征搜到 FastIoDispatch 而后作为参数传入。
图64
而后执行 执行第七块ShellCode
图65
2.8 ShellCode7
入口点创建线程并执行:
图66
线程函数为获取漏洞溢出资源信息 加载带有漏洞的 atmfd.dll 驱动 文件
图67
而后调用 AddFontMemResourceEx 调用 加载 atmfd.dll 驱动文件:
图68
触发漏洞函数为:
图69
覆盖前函数表:
图70
下写断点:
图71
而后函数表为:
图72
0x7ff6079b 该处函数为:
图73
而后触调用读取函数直接发该ShellCode内核执行 为ShellCode8:
图74
2.9 ShellCode8
功能主要负责加载后面的 NE执行文件
获取Nt基地址:
图75
而后获取相关函数地址 修正导入表 重定位:
图76
将入口点作为参数传入 ExQueueWorkItem 执行。
2.10 ShellCode9
为驱动函数入口点 主要作用是接受应用层来的写磁盘驱动,加载并执行该驱动
获取NTLdr信息。
图77
而后创建设备名跟应用层交互:
图78
当应用层传来 0x220004 IO控制码时候。
图79
QueueWorkItem加载该驱动:
图80
加载
图81
修正 并加载篡改MBR驱动执行
图82
2.11 ShellCode10
创建设备名
图83
注册DPC 注册关机回调 在最后一次关机回调中写入MBR:
图84
关机回调中直接发给磁盘底层设备:
图85
设备信息为
图86
3 尾声
“隐魂”就像一个幽灵,所过之处不留任何痕迹。近段时间,MBR顽固木马的活跃性增高,它的查杀难度本就很高,如果配合多种反侦察和对抗技术,随时有可能形成爆发局势,危害将不亚于勒索病毒。