您的位置:首页 > 其它

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例程地址

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: