一款本地提权木马利用原理分析 可实现3环突破到0环

该病毒是一个可以停止大年夜多半杀毒软件的恶意法度榜样,病毒经由过程微软一个破绽来加载驱动法度榜样,该破绽是内核的函数发生栈溢出导致,使得R3法度榜样可以在0环履行随意率性代码,驱动加载后停止反病毒软件,并经由过程向Atapi发送IRP感染userinit.exe实现自启动,下载并履行其它恶意法度榜样。

EXE部分

病毒主体履行后会在系统目录Program FilesMSDN目录下天生文件000000000,qwegier.exe,LHL13.sys,PciDisk.sys,在C盘根目录下天生sysLoad文件,解密自身带的一部分数据并拷贝到申请的一块内存中,然后在这里天生一个新的线程,竣事PciDevice的办事,加载PciDisk.sys驱动,并打开PciDisk创建的符号链接.PciFtDisk,并经由过程DeviceIoControl发送两个Io节制码0x2200180和0x22001C。

破绽概述

WINDOWS系统的内核函数RtlQueryRegistryValues存在栈溢出漏洞,病毒使用自己构造的一串数据写入注册表SYSTEMCurrentControlSetControlTimeZoneInformation的ActiveTimeBias键值下,当设置系统光阴时,内核会调用RtlQueryRegistryValues去读这个值,导致发生栈溢出,若读取的数据放在栈里面,会覆盖调用RtlQueryRegistryValues的函数的返回地址,触发破绽。正常环境下,ActiveTimeBias是一个DWORD类型的键值,病毒履行时,会改成REG_BINARY类型,并写入自己构造的数据。履历证,WinXP,VISTA以及Win7上都存在该破绽。

构造SHELLCODE的主要线程

病毒运行时,动态解密一块数据,拷贝到申请的内存中,然后在这里创建线程,文件threaddata为DUMP出来的代码,线程进口位于A61DD0,主要义务是完成SHELLCODE调用的内核函数的动态定位,改动注册表,筹备破绽发的需要前提,启动CMD进程,把SHELLCODE拷贝到CMD进程空间中去触发破绽,主要流程是:

在系统盘Program Filesmsdn目录下天生LHL3.sys文件

取得系统信息,获得ntoskrnl模块的加载地址,从磁盘上调用LoadLibraryEx从磁盘上把内核模块加载到用户空间中,取得SHELLCODE调用顶用到的内核函数地址,取得相对你猜并加上内核加载的虚拟地址,这样获得当前内核模式中函数地址并放入SHELLCODE响应位置,天生病毒的SHELLCODE

以“C:windowssystem32cmd.exe /c time %.2d:%.2d:%.2d”敕令行启动CMD进程,此中的光阴被款式化成当前光阴,在CMD进程中申请一块0x640大年夜小的内存并把SHELLCODE拷贝进去,删除原本的ActiveTimeBias,从新写一个REG_BINARY类型,长度为14H的串,款式如下(以双字形式):

+0:00000000+4:00000000+8:00000000+C:在CMD进程中申请的地址,也便是SHELLCODE所在的地址(XP系统)+10:在CMD进程中申请的地址,也便是SHELLCODE所在的地址(VISTA,Win7系统)

到这里,触发破绽的前提已经具备了,把挂起的CMD主线程规复运行,然后等待CMD进程停止后删除ActiveTimeBias键值。CMD进程运行之后,会设置光阴,破绽触发,其函数调用关系如下图:

Shellcode

破绽在CMD进程空间中被触发, ShellCode也在CMD进程空间获得履行,文件Shellcode中是DUMP出来的代码,进口点是150000,主要事情是解析PE文件,把驱动加载到内核地址空间中,流程如下 :

打开%Program Files%MSDNLHL13.sys ,获得大年夜小,在分页池中申请响应大年夜小的内存,然后把文件读进来

以PE头中SizeOfImage大年夜小申请非散播内存,从新按内存中对齐要领定位每一个节,拷贝到非分页内存中,修复导入地址表,指向内核函数地址,修复重定位表,完成驱动加载

自己调用驱动进口DriverEntry,返回后开释之前申请的分页内存

从破绽触发时的一个上层函数搜索到那个没有正常返回的函数的返回地址,设置EAX=STATUS_SUCCESS,然后转到那个地址去履行。

破绽触发及正常返回

在XP系统上,破绽触发时,内核中函数调用的流程是:NtSetSystemTime -> ExpSetSystemTime -> ExpRefreshTimeZoneInformation -> RtlSetActiveTimeBias -> RtlQueryRegistryValues -> RtlpCallQueryRegistryRoutine -> RtlpQueryRegistryDirect

在RtlSetActiveTimeBias中会调用RtlQueryRegistryValues去读注册表键值ActiveTimeBias,RtlSetActiveTimeBias函数的栈散播环境及调用RtlQueryRegistryValues的代码如下:

此中Context位于[ebp-8],其地址被放在一个布局中传给RtlQueryRegistryValues,这个地址颠末RtlpCallQueryRegistryRoutine终极被传给RtlpQueryRegistryDirect,RtlpQueryRegistryDirect函数是真正把栈中RtlSetActiveTimeBias的返回地址给覆盖的函数。

栈溢出

进入RtlSetActiveTimeBias时的栈散播如下:

终极有破绽的函数把从注册表中读出的0x14个字节写入从Context开始的位置,XP系统上偏移+0C的位置恰恰覆盖到RtlSetActiveTimeBias的返回地址(Vista系统上Context在[ebp-0c]的位置,以是写到注册表中的Shellcode的地址为偏移+10)。返回地址被覆盖时的栈如图:

[1] [2]下一页

此时RtlSetActiveTimeBias的返回地址已经被覆盖,值为在CMD进程中的SHELLCODE的地址150000。

履行SHELLCODE后安然返回

先列出调用关系:NtSetSystemTime -> ExpSetSystemTime -> ExpRefreshTimeZoneInformation -> RtlSetActiveTimeBias -> RtlQueryRegistryValues -> RtlpCallQueryRegistryRoutine -> RtlpQueryRegistryDirect

RtlSetActiveTimeBias返回时,就回到病毒的SHELLCODE中,此时的ESP指向上图中最上边的那个位置,EBP = 0,RtlSetActiveTimeBias的返回地址因为已经被覆盖,以是只能经由过程ESP获得RtlSetActiveTimeBias的上层函数ExpRefreshTimeZoneInformation的返回地址,这个地址在函数ExpSetSystemTime中,掏出这个地址,它的前四字节便是调用的相对偏移量,加上本身的地址,又获得函数ExpRefreshTimeZoneInformation的地址,在从这个地址搜索获得RtlSetActiveTimeBias原本的返回时的地址,设置返回值EAX为成功,然后转到这里去履行,如图:

第8行中的add ebp, 0FCh,FC是ExpRefreshTimeZoneInformation局部变量的大年夜小加上在栈中保存的三个寄存器所占的空间,现在EBP指向的是ExpRefreshTimeZoneInformation函数的栈帧。

掏出[ebp+4]是ExpRefreshTimeZoneInformation的返回地址,在函数ExpSetSystemTime中,函数find_return_addr如下图:

从ExpSetSystemTime函数中调用ExpRefreshTimeZoneInformation函数的地方,加上相对调用的偏移,也便是图中add ecx, [eax-4],取得函数ExpRefreshTimeZoneInformation的地址,然后在里面暴搜RtlSetActiveTimeBias正常环境下的返回地址。然后由上页图中的push eax; ret转以前,此时此次的调用返回正常的履行流程。

PciDisk.sys

PciDisk驱动主要经由过程向atapi.sys驱动法度榜样发送IRP来感染userinit.exe文件。驱动进口处创建一个设备DevicePciFtDisk和一个符号链接DosDevicesPciFtDisk。从磁盘打开atapi.sys文件,并从INIT节搜索到IRP_MJ_DEVICE_CONTROL和IRP_MJ_SCSI处置惩罚例程的地址。从系统目录打开文件userinit.exe并读入数据,由FileHandle获得FileObject,进一步经由过程FileObject与与之关联的Vpb获得文件系统所创建的卷设备工具,便是userinit.exe文件所在的卷设备工具,然后构造一个主功能号为IRP_MJ_FILE_SYSTEM_CONTROL的IRP,IoControlCode为FSCTL_GET_RETRIEVAL_POINTERS,发往文件系统的卷设备工具,如下图:

等IRP完成后,获得文件userinit.exe的VCN和LCN对应关系表。然后取得atapi驱动类型为FILE_DISK类型的设备,获得DR0设备工具。当驱动收到利用层发过来的DeviceIoControl哀求时,会把传入的数据经由过程写入磁盘,完成对文件的Hook操作,这里主如果自己构造SRB哀求包,向Atapi发送IRP_MJ_SCSI类型的IRP实现的。如图:

别处,代码中还有对atapi.sys分发例程的挂钩规复操作以及反调试代码,若发明在存在ntice.sys和syser.sys驱动,会向当火线程ETHREAD写入一块垃圾数据。

LHL3.sys

该驱动主要实现SSDT的规复,杀掉落大年夜部分的安然软件。驱动进口取得内核模块的基址和大年夜小,并暴搜找到函数PspTerminateThreadByPointer的地址。若搜不到,则从寻出表找到PsTerminateSystemThread函数的地址,并从该地址向后搜索取到PspTerminateThreadByPointer的地址,然后规复该函数的前8个字节,然后经由过程ZwQuerySystemInformation遍历系统中的进程表,并杀掉落病毒中定义的进程,包括:

这里杀进程的主要流程是:经由过程罗列获得的进程ID,获得进程工具EPROCESS,对进程工具中的链表头ThreadListHead遍历找到的每一个线程调用PspTerminateThreadByPointer。

然后分两种环境对SSDT进行规复:

若系统中不存在江夷易近软件,掏出系统中SSDT表的位置,换算并取到在磁盘文件中的偏移,从磁盘文件中读取原始的SSDT数据落后行重定位并规复。

若系统中存在江夷易近软件,先读取原始SSDT数据,同上步,然后申请两块内存,先把当前正在应用的SSDT表拷贝以前,把原始SSDT也拷贝到紧后面,参数个数表同理,然后给SSDT布局赋值指向新的函数地址表和个数表,并把函数个数乘以2放入Count。

这样构造的SSDT,原本的函数地址(Hook的或是没Hook的)没有改变,而后半部分新加入的都是被规复的函数地址。

然后病毒经由过程wrmsr改变MSR的IA32_SYSENTER_EIP,指向自己的代码,在这段代码中,把系统办事调用号加华夏本的SSDT函数数量放入EAX后就调用原本的系统办事进口。这样,系统办事函数的地址就被重定向到了SSDT的后半部分。

着末,病毒开一个系统线程,轮回调用杀进程的函数来停止杀软。

上一页[1] [2]

赞(0) 打赏
分享到: 更多 (0)
免责申明:本站所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,不保证真实性,并不承担任何法律责任

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

阿里云优惠网 更专业 更优惠

阿里云优惠券阿里云大礼包