距离我最开始接触Equation Group的样本已经有3,4年了吧,分析这些样本在很大程度上促进了我对windows系统的了解;虽然我还是无法完成类似的作品,但是现在至少可以‘欣赏’一下。
加载
这个样本前前后后分析了好久(大概一两年),中间有很长时间没有看,一直搁置着。打开ida后,马上就可以确定这是一个内核模块,最开始分析也没有得到什么有用的信息;直到前段时间,突然开了窍似的,有了一些发现。虽然这是一个内核驱动模块,但是从其入口函数来判断,它更像是一个内核的payload。其入口函数反汇编代码如下图所示:
不难看出,start函数并不像正常的DriverEntry一样,处理DriverObject和RegistryPath两个函数。结合start内部实现可以知道,该模块是被外部程序加载进入内核然后调用的。可惜这个外部程序没有被放出来,这个就更厉害了。start函数根据第二个参数进行分发,前面两种大同小异,第一种多一个进程管理器;第三种类似于通过服务(service)的方式启动驱动程序。
start函数中可以看出来它的加载程序在整个系统中执行的时机是非常早的,差不多可以算bootkit了吧。在上面的三种方案中,都会进行刺探来确定自己所处在的加载阶段,因为如果自己过早进入到内核中,而猎物(mup.sys,见参考2)还没有进场就不好了;这个时候通过注册回调来等待出场的机会,IoRegisterBootDriverReinitialization函数会类型为(Boot start)的驱动都加载完毕后,通知我登场。
start函数中的ReflectiveLoadSelf的实现也是非常的细致的,代码量有点大,当时在这个地方一直没有整明白。其ReflectiveLoadSelf是支持seh的,具体实现类似参考1。
初始化
进入内核后,start函数会根据参数2进行不同处理。重点看一下前面的两种,反射式加载完成自身镜像在内存中的迁移;之后开始模拟ZwLoadDriver的部分工作,创建DriverObejct并将其上报给驱动管理器。最后,等待系统通知Boot start类型的驱动加载完毕。
工作
这个阶段的分析没有完整分析,逆向分析有点吃力。下面列出比较重要的信息:
1,将数据地址寄生在mup.sys镜像的dos头中,多处修改。
2,自身线程管理
3,ndis protocol/miniport 管理,hook 各种Ndis****函数,接管整个网络接口
4,设置镜像加载回调,拦截特定模块
5,创建DeviceObject,设置MajorFunction,支持大量应用层接口
6,很多地方都是没有文档化的,正向没有开发经验,分析起来太慢了,
7,劫持第三方网卡驱动的接口,例如e1i65x64.sys(intel),
8,这个工程应该就是天花板了。
9,继续呢
样本下载地址:https://github.com/adamcaudill/EquationGroupLeak/blob/master/equation_drug/ntevtx64.sysc
参考1:https://github.com/9176324/Shark/blob/master/Projects/Shark/Shark.c
参考2: