导语:前段时间360安全卫士发表了一篇对双枪2感染释放驱动行为的分析报告,相比于双枪一代,它增加了HIVE文件保护,新增了WFP网络功能拦截,还有保护了自身的系统回调不被修改,并且针对部分查杀驱动摘除了所有的关机回调,该驱动木马从一代后
前言
前段时间360安全卫士发表了一篇对双枪2感染释放驱动行为的分析报告,相比于双枪一代,它增加了HIVE文件保护,新增了WFP网络功能拦截,还有保护了自身的系统回调不被修改,并且针对部分查杀驱动摘除了所有的关机回调,该驱动木马从一代后一直在更新活跃。接下来我们将对该驱动进行再一次全面的分析,揭露它难以查杀的详细原因。
1.驱动初始化部分
1.1驱动入口函数
主要为判断初始化一些变量,然后开启初始化线程工作。
入口函数所有代码:
图1
先获取Nt基地址,后续生成设备名,随机化线程地址和获取注册表操作函数用:
图2
然后初始化一些必要函数后续用于注入DLL模块:
图3
从Ntdll函数中取出SSDTIndex,在KeServiceDescriptorTable取得函数地址 :
图4
获取完成后判断下加载时机,由于该驱动重启后为Boot0驱动,判断下Ntfs文件系统驱动是否加载,:
图5
创建设备名和符号链接跟应用层交互:
图6
设备名是通过随机Nt基地址数字生成:
图7
生成随机设备名,并使用这个随机设备注册关机回调,然后开启初始化线程:
图8
1.2初始化线程
线程入口开始就调用KeEnterCriticalRegion
而该函数作用为禁止内核APC,暂停线程操作调用的就是内核APC
调用这个函数后线程就无法被暂停,然后再隐藏自身线程起地址,将其设置为ntos里面的一个随机地址。
图9
然后开始挂钩模块加载回调初始化获取一些注册表函数地址并且重新创建随机文件名将自己驱动拷贝过去:
图10
然后创建三个工作队列并且将模块注入到系统进程:
图11
然后进入死循环,一直往系统中放置工作队列用于后续感染BootKit等一系列操作:
图12
1.3注册表函数初始化
在初始化线程中调用了KeyHelperStartup,该函数主要为获取CmSetValueKey更底层的操作函数,函数内容为:
图13
GetCellRoutineOffset 函数里面主要为获得一些硬编码偏移。
然后挂钩函数GetCellRoutine:
图14
开启线程触发调用,触发完成后恢复钩子:
图15
触发调用函数为:
图16
在挂钩函数中使用RtlWalkFrameChain栈回溯来找到CmSetValueKey等函数调用。
并且校验线程是否为触发的线程,根据调用类型CallType来查找,
图17
初始化代码完成后,接下来我们开始从网络阻断,文件保护,注册表保护,模块加载禁止,改首页模块注入,BootKit感染,自身回调防护几个部分的详细分析。
2.网络阻断
开启线程主要是分系统挂钩网络组件Xp系统为挂钩TCPIP Win7以上 注册WFP相关例程:
图18
入口点先隐藏自身,将自身设置为
\\SystemRoot\\system32\\drivers\\volmgr.sys 驱动。
图19
然后根据系统不同挂钩不同系统网络组件,对于XP系统:
图20
Win7系统:
图21
然后注册WFP回调:
图22
回调函数中判断进程名字,一旦有匹配的进程名,则阻断该进程网络操作:
图23
匹配是通过Hash计算进程名字:
图24
3.文件保护
先生成随机文件名驱动,并且将原来文件删除,删除前去除保护开关。
图25
保护开关函数为,注册表函数类似,该函数频繁被调用,我们看下具体内容:
图26
将当前线程设置为信任线程,注册表和文件挂钩就会放行该线程。
清理信任线程代码为:
图27
然后将一些要保护的文件设置上。
自身文件:
图28
Ntfs文件:
图29
FastFat文件:
图30
设置上保护后,挂钩Ntfs正式开启保护:
图31
该函数中首先获取ntfs驱动对象:
图32
备份并替换所有的Ntfs FsdDisptach:
图33
备份所有FastIo操作例程:
图34
替换:
图35
FastFat类似,这里我们就不看了。
挂钩函数中:
图36
CheckTheFileIsProtectAndCompleteTheRequest函数里面调用:
图37
该函数主要是否为之前初始化的保护文件列表,依然是通过文件名Hash比对的,并且查看当前线程是否为可以信任线程。
图38
如果不是则拒绝打开。
对于已经打开的文件对象,通过判断文件对象的FsContext来判断。
图39
之前会先获取Hive文件对象。
图40
判断是否一致:
图41
如果为保护的文件则返回 STATUS_INVALID_PARAMETER。
Hive文件特殊处理。
图42
图43
4.注册表保护
先设置自身开机顺序:
图44
获取优先启动组:
图45
然后将服务写入:
图46
写入函数为:
图47
优先使用更底层的CmSetValueKey函数,然后才使用系统调用:
图48
初始化保护列表:
图49
注册保护回调:
图50
回调保护中:
图51
Hash比对注册表键,检测是否为保护项目:
图52
如果是且不是可信进程则拒绝打开。
5模块加载禁止
先设置回调:
图53
分驱动和应用进程两种情况。
驱动文件判断是否需要Patch的模块:
图54
Hash跟 正则匹配aw***.sys等一些驱动。
图55
如果是则Patch入口点:
图56
对于应用层进程判断是否为浏览器,如果是则禁止网盾模块加载:
图57
6.改首页模块注入
先解密DLL,动态获取ntdll地址偏移.
图58
图59
解密文件并校验:
图60
然后分别向Services.exe Explorer.exe注入。
图61
分配内存:
图62
拷贝代码:
图63
然后注入执行:
图64
7.BootKit感染
7.1查找活动分区
目前有不少机器安装了多块硬盘,需要先找活动磁盘的活动分区。
图65
然后写入BooKit组件,分三步写入,先写入引导驱动BootImage,然后写VBR,最后写入MBR,只有当前面一步操作成功后才继续下一步写入。
图66
7.2 BootImage写入
写入BootImage前 先找磁盘末尾空余区域,如果没有空间则写入失败。
图67
获取磁盘参数:
图68
然后找到磁盘末尾写入位置:
图69
再将BootImage加密后写入:
图70
写入前先判断是否已经写入过了:
图71
写入成功后,再写入VBR部分。
7.3 VBR写入
判断分区参数和是否为NTFS磁盘,仅支持Ntfs磁盘。
图72
然后找下VBR跳转指令:
图73
查找函数为:
图74
判断下是否为ESLDRLoader,如果是则删除所有项目。
图75
删除所有:
图76
然后将病毒VBR压缩,合并写入:
图77
并且将位置大小的参数全部异或加密保存在磁盘末尾。
图78
7.4 MBR写入
获取磁盘信息:
图79
先将VBR写入磁盘最开始的第3个扇区后0xF个扇区,后续即使VBR被修复,MBR部分依旧可以感染VBR
图80
读取原始MBR:
图81
将分区表拷贝进来,然后比对是否已经写入,如果没有则写入0号扇区:
图82
7.4 保护BootKit
保护函数:
图83
先初始化正常的VBR MBR,用系统默认的。后续如果有应用程序读取则读到这份假的内容。
MBR部分:
图84
VBR部分:
图85
然后再安装磁盘底层钩子:
图86
挂钩中判断,写则返回拒绝.
图87
读取则返回假的数据:
图88
8.自身回调防护
LoadImage 函数保护,拷贝头部0x20个字节:
图89
比对是否一致,不一致则直接恢复:
图90
注册表回调,判断特定键值打开返回值:
图91
然后重新注册上:
图92
摘除关机回调则通过硬编码获取链表头部:
图93
获取:
图94
然后遍历整个链表,只要不是自身注册的随机设备就摘除该关机回调:
图95
摘除:
图96