Rootkit之HOOK小结
2012-05-19 15:16
267 查看
目前接触的HOOK总结,学习HOOK只是为了让我对内核更加熟悉,我对那些毛的病毒木马没毛兴趣。
Windows平台上HOOK:
应用层HOOK:
1.消息HOOK:局部钩子、全局钩子、全局低级键盘钩子之类
2.IAT HOOK:通过修改IAT(导入表)表中的地址
过程就是先取DOS头,再取PE头偏移,再获取导入信息,其中的FirstThunk就是IAT偏移,再遍历,这样就找到了IAT表
3.EAT HOOK:(这个没有实际去做,知道思路)
详见http://bbs.pediy.com/showthread.php?t=62574
内核级HOOK:
内核hook基本上大同小异,都是获取相关函数的地址后修改成自己函数的地址
1.IDT HOOK:通过修改IDT表中的ISR例程地址
IDT 详解 http://blog.csdn.net/fwqcuc/article/details/5855460 http://blog.csdn.net/fwqcuc/article/details/5855715
IDT 多核检测 http://hi.baidu.com/andriy_aolala/blog/item/e841c1cd72277f5b0eb34510.html
2.SSDT HOOK:通过修改SSDT表中函数地址
系统服务描述符表 在ntoskrnl.exe导出KeServiceDescriptorTable 这个表
3.Inline HOOK:通过修改ntoskrnl导出Nt函数的字节,加入JMP
像如果u nt!NtOpenProcess函数,JMP需要5字节,选择合适的地方插入JMP到自己定义的函数即可
4.Shadow SSDT HOOK
正常情况下,ETHREAD中的ServiceTable,要么指向KeServiceDescriptorTable,要么指向KeServiceDescriptorTableShadow,注意这句话啊
ETHREAD->ServiceTable从来不会直接接向GUI的那张表,而是指向整体的KeServiceDescriptorTableShadow,用windbg观察就知道了
系统中既有KeServiceDescriptorTable也有KeServiceDescriptorTableShadow,他们各司其职,非GUI线程使用KeServiceDescriptorTable,GUI线程使用KeServiceDescriptorTableShadow,这是Windows的设计。非GUI线程如果要调用GUI服务就会用PsConvertToGuiThread把ETHREAD->ServiceTable切换为KeServiceDescriptorTableShadow,而GUI线程调用普通的Win32服务时并不需要切换,因为KeServiceDescriptorTableShadow中已经有个这张表,所以KeServiceDescriptorTableShadow可以看成是KeServiceDescriptorTable的增强版
KeServiceDescriptorTable中第二张表之所以无效,是因为非GUI线程根本不需要这张表,所以没有填充
链接: http://bbs.pediy.com/showthread.php?t=56955 http://bbs.pediy.com/showthread.php?t=65931 http://bbs.pediy.com/showthread.php?t=82066 http://bbs.pediy.com/showthread.php?t=98909
5.IRP HOOK
1) 可用办法之一:hook IofCallDriver实现irp 拦截。
2) 可用办法之二:写一个过滤驱动,挂在你要hook其irp的那个驱动之上。
3) 可用办法之三:直接修改你要hook其irp的那个驱动的MajorFunction函数表。
http://bbs.pediy.com/showthread.php?t=60022 http://bbs.pediy.com/showthread.php?t=111559 http://bbs.pediy.com/showthread.php?t=96245
http://bbs.pediy.com/showthread.php?t=97821
6.Object HOOK
当你调用NtCreateFile->IoCreateFile->ObOpenObjectByName->ObpLookupObjectName->IopParseFile->IopParseDevice
IopParseFile最终也会调用IopParseDevice
ObjectHook其实就是比如你要HOOK 创建打开就是OBJECT_TYPE_INITIALIZER->ParseProcedure
http://bbs.pediy.com/showthread.php?t=128161 http://bbs.pediy.com/showthread.php?t=134415 http://www.xfocus.net/articles/200802/966.html http://forum.eviloctal.com/thread-33688-1-1.html
7.sysenter HOOK
通过修改MSR寄存器的值来达到hook的目的,一般的拦截方法就是通过rdmsr wrmsr 两个指令把原来的sysenter地址改成自己的sysenter地址来实现的
http://bbs.pediy.com/showthread.php?t=60247 http://bbs.pediy.com/showthread.php?t=42705
几个学习链接: http://bbs.pediy.com/showthread.php?t=81204 http://bbs.pediy.com/showthread.php?t=40832 http://bbs.pediy.com/showthread.php?t=142142 http://bbs.pediy.com/showthread.php?t=131397
http://bbs.pediy.com/showthread.php?t=98493 http://bbs.pediy.com/showthread.php?t=138620
Detours:Binary Interception of Win32 Functions
Load Your 32-bit DLL into Another Process's Address Space Using INJLIB http://blog.csdn.net/coding_hello http://www.cnblogs.com/me-sa/articles/671862.html
Hide your ssdt hook http://hi.baidu.com/sagittar_4d5a/blog/item/fe735660546f3143ebf8f8df.html
Linux平台上的HOOK:
很多Windows上的HOOK,Linux都可以做。
例如sys_call_table,还有IDT等等
在linux下主要的还是netfilter中的HOOK,这个才是Linux的重点。
包横穿netfilter系统示意图:
------ →[1]------ →[route]------ →[3]------ →[4]------ →
| ^
| |
| [route]
v |
[2] [5]
| ^
| |
v |
[1]:nf_ip_pre_routing:刚刚进入网络层的数据包通过此点(刚刚进行完版本号,校验和等检测), 源地址转换在此点进行;
[2]:nf_ip_local_in:经路由查找后,送往本机的通过此检查点,input包过滤在此点进行;
[3]:nf_ip_forward:要转发的包通过此检测点,forword包过滤在此点进行;
[4]:nf_ip_post_routing:所有马上便要通过网络设备出去的包通过此检测点,内置的目的地址转换功能(包括地址伪装)在此点进行;
[5]:nf_ip_local_out:本机进程发出的包通过此检测点,output包过滤在此点进行。
Linux下gdb检测rootkit:
http://os.51cto.com/art/201001/178676.htm http://linkboy.blog.51cto.com/821152/297549
Windows平台上HOOK:
应用层HOOK:
1.消息HOOK:局部钩子、全局钩子、全局低级键盘钩子之类
2.IAT HOOK:通过修改IAT(导入表)表中的地址
过程就是先取DOS头,再取PE头偏移,再获取导入信息,其中的FirstThunk就是IAT偏移,再遍历,这样就找到了IAT表
3.EAT HOOK:(这个没有实际去做,知道思路)
详见http://bbs.pediy.com/showthread.php?t=62574
内核级HOOK:
内核hook基本上大同小异,都是获取相关函数的地址后修改成自己函数的地址
1.IDT HOOK:通过修改IDT表中的ISR例程地址
#pragma pack(push) #pragma pack(1) // 1字节对齐 typedef struct _IDTR //IDT基址 { USHORT limit; //范围占位 ULONG base; //基地址占位_IDT_ENTRY类型指针 }IDTR,*PIDTR; typedef struct _IDT_ENTRY { USHORT offset_low; //中断处理函数地址低位 USHORT selector; UCHAR reserved; UCHAR type:4; //4位 UCHAR always0:1; //1位 UCHAR dpl:2; //2位 UCHAR present:1;//1位 USHORT offset_high;//中断处理函数地址低位 }IDT_ENTRY,*PIDT_ENTRY;//获取基址实际上是这个类型 #pragma pack(pop) //#pragma pack(pop)
IDT 详解 http://blog.csdn.net/fwqcuc/article/details/5855460 http://blog.csdn.net/fwqcuc/article/details/5855715
IDT 多核检测 http://hi.baidu.com/andriy_aolala/blog/item/e841c1cd72277f5b0eb34510.html
2.SSDT HOOK:通过修改SSDT表中函数地址
系统服务描述符表 在ntoskrnl.exe导出KeServiceDescriptorTable 这个表
typedef struct _ServiceDescriptorTable { PVOID ServiceTableBase; //System Service Dispatch Table 的基地址 PVOID ServiceCounterTable; //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。 PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 }*PServiceDescriptorTable; //由SSDT索引号获取当前函数地址 //NtOpenProcess [[KeServiceDescriptorTable]+0x7A*4] extern PServiceDescriptorTable KeServiceDescriptorTable;
3.Inline HOOK:通过修改ntoskrnl导出Nt函数的字节,加入JMP
像如果u nt!NtOpenProcess函数,JMP需要5字节,选择合适的地方插入JMP到自己定义的函数即可
4.Shadow SSDT HOOK
正常情况下,ETHREAD中的ServiceTable,要么指向KeServiceDescriptorTable,要么指向KeServiceDescriptorTableShadow,注意这句话啊
ETHREAD->ServiceTable从来不会直接接向GUI的那张表,而是指向整体的KeServiceDescriptorTableShadow,用windbg观察就知道了
系统中既有KeServiceDescriptorTable也有KeServiceDescriptorTableShadow,他们各司其职,非GUI线程使用KeServiceDescriptorTable,GUI线程使用KeServiceDescriptorTableShadow,这是Windows的设计。非GUI线程如果要调用GUI服务就会用PsConvertToGuiThread把ETHREAD->ServiceTable切换为KeServiceDescriptorTableShadow,而GUI线程调用普通的Win32服务时并不需要切换,因为KeServiceDescriptorTableShadow中已经有个这张表,所以KeServiceDescriptorTableShadow可以看成是KeServiceDescriptorTable的增强版
KeServiceDescriptorTable中第二张表之所以无效,是因为非GUI线程根本不需要这张表,所以没有填充
#pragma PAGECODE DWORD Get_KeServiceDescriptorTableShadow_Addr() { DWORD KeServiceDescriptorTableShadow=0; DWORD Version=GetVersion(); switch (Version ) { case VERSION_2K: KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable+0xE0; break; case VERSION_2K3: break; case VERSION_XP: KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable-0x40;//XP系统的影子描述表是-0X40 break; default: break; } return KeServiceDescriptorTableShadow; }
链接: http://bbs.pediy.com/showthread.php?t=56955 http://bbs.pediy.com/showthread.php?t=65931 http://bbs.pediy.com/showthread.php?t=82066 http://bbs.pediy.com/showthread.php?t=98909
5.IRP HOOK
1) 可用办法之一:hook IofCallDriver实现irp 拦截。
2) 可用办法之二:写一个过滤驱动,挂在你要hook其irp的那个驱动之上。
3) 可用办法之三:直接修改你要hook其irp的那个驱动的MajorFunction函数表。
http://bbs.pediy.com/showthread.php?t=60022 http://bbs.pediy.com/showthread.php?t=111559 http://bbs.pediy.com/showthread.php?t=96245
http://bbs.pediy.com/showthread.php?t=97821
6.Object HOOK
当你调用NtCreateFile->IoCreateFile->ObOpenObjectByName->ObpLookupObjectName->IopParseFile->IopParseDevice
IopParseFile最终也会调用IopParseDevice
ObjectHook其实就是比如你要HOOK 创建打开就是OBJECT_TYPE_INITIALIZER->ParseProcedure
http://bbs.pediy.com/showthread.php?t=128161 http://bbs.pediy.com/showthread.php?t=134415 http://www.xfocus.net/articles/200802/966.html http://forum.eviloctal.com/thread-33688-1-1.html
7.sysenter HOOK
通过修改MSR寄存器的值来达到hook的目的,一般的拦截方法就是通过rdmsr wrmsr 两个指令把原来的sysenter地址改成自己的sysenter地址来实现的
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ) { theDriverObject->DriverUnload = OnUnload; __asm { mov ecx, 0x176 rdmsr // read the value of the IA32_SYSENTER_EIP register mov d_origKiFastCallEntry, eax mov eax, MyKiFastCallEntry // Hook function address wrmsr // Write to the IA32_SYSENTER_EIP register } return STATUS_SUCCESS; }
http://bbs.pediy.com/showthread.php?t=60247 http://bbs.pediy.com/showthread.php?t=42705
几个学习链接: http://bbs.pediy.com/showthread.php?t=81204 http://bbs.pediy.com/showthread.php?t=40832 http://bbs.pediy.com/showthread.php?t=142142 http://bbs.pediy.com/showthread.php?t=131397
http://bbs.pediy.com/showthread.php?t=98493 http://bbs.pediy.com/showthread.php?t=138620
Detours:Binary Interception of Win32 Functions
Load Your 32-bit DLL into Another Process's Address Space Using INJLIB http://blog.csdn.net/coding_hello http://www.cnblogs.com/me-sa/articles/671862.html
Hide your ssdt hook http://hi.baidu.com/sagittar_4d5a/blog/item/fe735660546f3143ebf8f8df.html
Linux平台上的HOOK:
很多Windows上的HOOK,Linux都可以做。
例如sys_call_table,还有IDT等等
在linux下主要的还是netfilter中的HOOK,这个才是Linux的重点。
包横穿netfilter系统示意图:
------ →[1]------ →[route]------ →[3]------ →[4]------ →
| ^
| |
| [route]
v |
[2] [5]
| ^
| |
v |
[1]:nf_ip_pre_routing:刚刚进入网络层的数据包通过此点(刚刚进行完版本号,校验和等检测), 源地址转换在此点进行;
[2]:nf_ip_local_in:经路由查找后,送往本机的通过此检查点,input包过滤在此点进行;
[3]:nf_ip_forward:要转发的包通过此检测点,forword包过滤在此点进行;
[4]:nf_ip_post_routing:所有马上便要通过网络设备出去的包通过此检测点,内置的目的地址转换功能(包括地址伪装)在此点进行;
[5]:nf_ip_local_out:本机进程发出的包通过此检测点,output包过滤在此点进行。
Linux下gdb检测rootkit:
http://os.51cto.com/art/201001/178676.htm http://linkboy.blog.51cto.com/821152/297549
相关文章推荐
- rootkit hook之[四]-- IDT Hook
- RootKit hook之[一] Object Hook
- rootkit hook之[六] -- sysenter Hook
- rootkit hook之[六] -- sysenter Hook
- Rootkit hook之[三] Inline Hook
- 【原创】RootKit hook 之[一] object hook
- rootkit之[七]IAT Hook -- HybridHook之终极打造
- vxk的rootkit 技术小结
- rootkit hook之[六] -- sysenter Hook
- 另一种sysenter hook方法(绕过绝大多数的rootkit检测工具的检测)
- ARM inlinehook小结
- Hook小结
- Rootkit进程篇之进程隐藏 ( SSDT Hook QuerySystemInformation )
- Rootkit之SSDT hook(通过CR0)
- Hook学习小结
- hook小结
- Rootkit之SSDT hook(通过CR0)
- 另一种sysenter hook方法(绕过绝大多数的rootkit检测工具的检测)
- RootKit hook 之[一] object hook
- hook小结