欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

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

来源:本站整理 作者:佚名 时间:2018-08-26 TAG: 我要投稿


该病毒是一个可以结束大多数杀毒软件的恶意程序,病毒通过微软一个漏洞来加载驱动程序,该漏洞是内核的函数发生栈溢出导致,使得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存在栈溢出漏洞,病毒利用自己构造的一串数据写入注册表SYSTEM\CurrentControlSet\Control\TimeZoneInformation的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:\windows\system32\cmd.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%\MSDN\LHL13.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]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载