ssdthook:简单说说SSDT



By:云舒

论技术我还差得远而且网上有关SSDT文章也多不胜数但是还是想自己写我想试试我能不能用最简单语言来描述SSDT——这个对般来人来说比较神秘属于内核地带引用EVA说句话“以为写个驱动就是内核还远着了”——大概是这么个意思记得不是很清楚

有关SSDT描述得最清楚应该算SSDT Hook妙用-对抗ring0 inline hook文了作者是堕落天才这里引用下他写开头部分略有个别修改:

内核中有两个系统服务描述符表个是KeServiceDescriptorTable由ntoskrnl.exe导出个是 KeServieDescriptorTableShadow没有导出这两者都是个结构体结构下面会给出他们区别是 KeServiceDescriptorTable仅有 ntoskrnel而KeServieDescriptorTableShadow则包含了ntoskrnel和win32kNative API服务地址由KeServiceDescriptorTable分派而gdi.dll和
user.dll内核API服务地址由 KeServieDescriptorTableShadow分派还有要清楚是win32k.sys只有在GUI线程中才加载般情况下是不加载

他们结构如下:
代码:
typedef struct _SYSTEM_SERVICE_TABLE
{
PVOID ServiceTableBase; //这个指向系统服务地址表
PULONG ServiceCounterTableBase;
ULONG NumberOfService; //服务个数,NumberOfService*4 就是整个地址表大小
ULONG ParamTableBase;
}SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;

typedef struct _SERVICE_DESCRIPTOR_TABLE
{
SYSTEM_SERVICE_TABLE ntoskrnel; //ntoskrnl.exe服务
SYSTEM_SERVICE_TABLE win32k; //win32k.sys服务,(gdi.dll/user.dll内核支持)
SYSTEM_SERVICE_TABLE NotUsed1;
SYSTEM_SERVICE_TABLE NotUsed2;
}SYSTEM_DESCRIPTOR_TABLE,*PSYSTEM_DESCRIPTOR_TABLE;

当系统需要使用个本机API时候就会去查找SYSTEM_DESCRIPTOR_TABLE这个表也就是由ntoskrnl.exe导出KeServiceDescriptorTable:

代码:
nt!RtlpBreakWithStatusInstruction:
80527fc8 cc 3
kd> dd KeServiceDescriptorTable
80553380 805021fc 00000000 0000011c 80502670
80553390 00000000 00000000 00000000 00000000
805533a0 00000000 00000000 00000000 00000000
805533b0 00000000 00000000 00000000 00000000
805533c0 00002710 bf80c227 00000000 00000000
805533d0 f9e6da80 f963a9e0 816850f0 806e0f40
805533e0 00000000 00000000 00000000 00000000
805533f0 97c5ac40 01c7abf5 00000000 00000000

可以看到KeServiceDescriptorTable地址是80553380现在看看这个地址保存是什么这个地址值就是 SYSTEM_SERVICE_TABLE起始地址好了我们看到这个地址保存是805021fc那么也就是说系统服务地址表起始地址为 805021fc了看看这个表是些什么鬼东西:
代码:
kd> dd 805021fc
805021fc 80599746 805e6914 805ea15a 805e6946
8050220c 805ea194 805e697c 805ea1d8 805ea21c
8050221c 8060b880 8060c5d2 805e1cac 805e1904
8050222c 805ca928 805ca8d8 8060bea6 805ab334
8050223c 8060b4be 8059dbbc 805a5786 805cc406
8050224c 804ffed0 8060c5c4 8056be64 805353f2
8050225c 80604b90 805b19c0 805ea694 80619a56
8050226c 805eeb86 80599e34 80619caa 805996e6

这个过程是这样最开始是SYSTEM_DESCRIPTOR_TABLE(80553380)保存了SYSTEM_SERVICE_TABLE地址(805021fc)SYSTEM_SERVICE_TABLE地址(805021fc)又保存了很多地址这个地址就是系统服务地址了类似 NtOpenProcess这样ring0地址这样系统就可以方便找到每个ring0

我们先看看第个地址80599746是个什么反汇编下:
代码:
kd> u 80599746
nt!NtAcceptConnectPort:
80599746 689c000000 push 9Ch
8059974b 6820a14d80 push off nt!_real+0x128 (804da120)
80599750 e8abebf9ff call nt!_SEH_prolog (80538300)
80599755 64a124010000 mov eax,dword ptr fs:[00000124h]
8059975b 8a8040010000 mov al, ptr [eax+140h]
80599761 884590 mov ptr [ebp-70h],al
80599764 84c0 test al,al
80599766 0f84b9010000 je nt!NtAcceptConnectPort+0x1df (80599925)

原来是NtAcceptConnectPort第 2个805e6914呢?我们也看
代码:
kd> u 805e6914
nt!NtAccessCheck:
805e6914 8bff mov edi,edi
805e6916 55 push ebp
805e6917 8bec mov ebp,esp
805e6919 33c0 xor eax,eax
805e691b 50 push eax
805e691c ff7524 push dword ptr [ebp+24h]
805e691f ff7520 push dword ptr [ebp+20h]
805e6922 ff751c push dword ptr [ebp+1Ch]

原来是NtAccessCheck

这样我们可以清楚看到在这个起始地址为0x805021fc表中保存了各个ring0地址下面我来做个简单比喻

从前有个很大帮派名字叫做Windows功能很多并且很强大这些各方面能力由各个专人负责他们个人做件事情随着人员增多帮主发现联系起来越来越困了天帮主要找竟然NtOpenProcess来调查下他个手下是不是别帮派派来间谍但是他发现 NtOpenProcess跑不见了

于是军师就想出了个好办法来解决这个问题:先建立个封闭密室这个密室只有 8袋长老以上人才能进去密室中间有张纸条上面写着个地址——温家堡还有这个地址放着多少人联系信息等内容这个密室就是Ntdll.dll这个纸条就是SYSTEM_DESCRIPTOR_TABLE上写地址就是SYSTEM_SERVICE_TABLE也就是温家堡了这个温家堡是个有很多大房间地方每个房子有个房间号
房间里面又放着张纸条上面写着各个手下住所比如说编号为7A房间里面放是NtOpenProcess家庭住址

这样帮主要找人就容易了先去密室找到纸条看看上面写是温家堡还是白云城那个地方有多少个人联系信息等如果是温家堡就跑到那里去看看要找谁找NtOpenProcess就去7A房间在这个房间里里面写着NtOpenProcess现在就住在密室旁边……搞定

这里就有个新问题帮主假设这个里面写东西都是正确没有被人改过于是就有了别派间谍发现了偷偷溜进密室然后根据纸条内容又跑到温家堡进到7A房间神不知鬼不觉把里面记录NtOpenProcess地址改成了自己于是帮主再找人发现找到对头家里去了这个就是传说中SSDT Hook了

攻击者进入ring0的后找到KeServiceDescriptorTable地址即SYSTEM_SERVICE_TABLE地址(进入密室找到纸条写地址——温家堡)然后改写SYSTEM_SERVICE_TABLE中个特定地址为自己定义入口处截获了系统(来到温家堡改掉7A房间里面写住所改成自己家)次HOOK就完成了

下面我给段简单代码演示如何样让个特定PID不会被杀死这段代码基本和SSDT Hook妙用-对抗ring0 inline hook我只是注释了下而已另外在MyNtOpenProcess处加了个判断是不是某个特定PID功能
代码: /*
演示HOOK系统服务表中NtOpenProcess保护需要保护进程被防止被杀掉
*/

#<ntddk.h>

/*
KeServiceDescriptorTable仅有ntoskrnel没有包含win32k而且后面两个字段都没有使用

以为了简便直接把ServiceDescriptorTable定义成SYSTEM_SERVICE_TABLE免得访问多个结构体

字段麻烦这里明白就行了
*/
typedef struct _ServiceDescriptorTable
{
 PVOID ServiceTableBase;
 PULONG ServiceCounterTableBase;
 ULONG NumberOfService;
 ULONG ParamTableBase;
}ServiceDescriptorTable,*PServiceDescriptorTable;

// KeServiceDescriptorTable为ntoskrnl.exe导出
extern PServiceDescriptorTable KeServiceDescriptorTable;

// 定义下NtOpenProcess原型下面如果用汇编就不用定义了但是我想尽量不用汇编
typedef NTSTATUS (__stdcall *NTOPENPROCESS)( OUT PHANDLE ProcessHandle,
 




  • 篇文章: 推荐:网站WebSite中SQL注入脚本漏洞挖掘和防护

  • 篇文章: 没有了
  • Tags:  ssdt是什么 shadowssdt ssdt工具 ssdthook

    延伸阅读

    最新评论

    发表评论