您当前的位置:首页 > 电脑百科 > 安全防护 > 数据安全

r0下的进程保护

时间:2021-12-30 10:30:18  来源:  作者:安全客小安
r0下的进程保护

 

前言

进程保护是众多AV或者病毒都要所具备的基础功能,本文就0环下通过SSDT来对进程进行保护进行探究,SSDT也不是什么新技术,但作为学习,老的技术我们同样需要掌握。

什么是SSDT

SSDT 的全称是System Services Descriptor Table,系统服务描述符表。

首先要明确的是他是一张表,通过windbg查看这张表。

dd  KeServiceDescriptorTable
r0下的进程保护

 

这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来。

当我们在r 3调用一个API时,实际上调用的是一个接口,这里拿ReadProcessMemory举例。

ReadProcessMemory函数在kernel32.dll中导出,通过断点可以找到对应的反汇编代码。在汇编代码中,可以看到ReadProcessMemory调用了ntdll.dll中的ZwReadVirtualMemory函数。

r0下的进程保护

 

在ZwReadVirtualMemory函数开始的地方下断点。

bp ZwReadVirtualMemory

实际上功能代码也没有在ZwReadVirtualMemory函数中实现,只是拿着一个索引号并跳转到一个地址。

r0下的进程保护

 

这个索引号实际上就是SSDT表中的索引号,回到windbg,我们现在拿到索引号0xBA去SSDT表中找。

kd> dd  KeServiceDescriptorTable
80553fa0  80502b8c 00000000 0000011c 80503000
80553fb0  00000000 00000000 00000000 00000000
80553fc0  00000000 00000000 00000000 00000000
80553fd0  00000000 00000000 00000000 00000000
80553fe0  00002710 bf80c0b6 00000000 00000000
80553ff0  f8b67a80 f82e7b60 821bfa90 806e2f40
80554000  00000000 00000000 22bc349b 00000001
80554010  afa8a15b 01d7eb4f 00000000 00000000
kd> dd 80502b8c + 0xba*4
80502e74  805aa712 805c99e0 8060ea76 8060c43c
80502e84  8056f0d2 8063ab56 8061aca8 8061d332
80502e94  8059b804 8059c7cc 8059c1d4 8059baee
80502ea4  805bf456 80598d62 8059908e 805bf264
80502eb4  806064b6 8051ee82 8061cc3e 805cbd40
80502ec4  805cbc22 8061cd3a 8061ce20 8061cf48
80502ed4  8059a07c 8060db50 8060db50 805c892a
80502ee4  8063d80e 8060be28 80607fb8 8060882a
kd> u 805aa712
r0下的进程保护

 

可以看到在0环调用的是NtReadVirtualMemory,这实际上才是真正实现功能的地方。而SSDT将r 3和r 0联系到一起。

r0下的进程保护

 

SSDT结构

在 NT 4.0 以上的 windows 操作系统中,默认就存在两个系统服务描述表,这两个调度表对应了两类不同的系统服务,

这两个调度表为:KeServiceDescriptorTable 和 KeServiceDescriptorTableShadow,

其中 KeServiceDescriptorTable 主要是处理来自 Ring3 层 Kernel32.dll 中的系统调用,

而 KeServiceDescriptorTableShadow 则主要处理来自 User32.dll 和 GDI32.dll 中的系统调用,

并且 KeServiceDescriptorTable 在 ntoskrnl.exe(Windows 操作系统内核文件,包括内核和执行体层)是导出的,

而 KeServiceDescriptorTableShadow 则是没有被 Windows 操作系统所导出,

而关于 SSDT 的全部内容则都是通过 KeServiceDescriptorTable 来完成的。

r0下的进程保护

 

SSDT表的结构通过结构体表示为如下:

typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
    KSYSTEM_SERVICE_TABLE   ntoskrnl;  // ntoskrnl.exe 的服务函数
    KSYSTEM_SERVICE_TABLE   win32k;    // win32k.sys 的服务函数(GDI32.dll/User32.dll 的内核支持)
    KSYSTEM_SERVICE_TABLE   notUsed1;
    KSYSTEM_SERVICE_TABLE   notUsed2;
} KSERVICE_TABLE_DESCRIPTOR, * PKSERVICE_TABLE_DESCRIPTOR;

其中每一项又是一个结构体:KSYSTEM_SERVICE_TABLE。通过结构体表示为如下:

typedef struct _KSYSTEM_SERVICE_TABLE
{
    PULONG  ServiceTableBase;          // SSDT (System Service Dispatch Table)的基地址
    PULONG  ServiceCounterTableBase;   // 用于 checked builds, 包含 SSDT 中每个服务被调用的次数
    ULONG   NumberOfService;           // 服务函数的个数, NumberOfService * 4 就是整个地址表的大小
    ULONG   ParamTableBase;            // SSPT(System Service Parameter Table)的基地址
} KSYSTEM_SERVICE_TABLE, * PKSYSTEM_SERVICE_TABLE;

通过看图形化界面可以更加直观,下图是ntoskrnl.exe和win32k.sys的服务函数结构。

r0下的进程保护

 

HOOK SSDT

有了上面的知识储备,理解SSDT HOOK就很容易了。

当3环程序执行后,操作系统拿着索引去SSDT表中找对应的0环程序,这时我们就可以在SSDT表中做点手脚,将某一个api函数的指针改成我们自己函数的指针,这样执行的将会是我们自己的代码。

首先需要定义我们自己的函数

ULONG g_Pid = 568;
NTSTATUS NTAPI MyOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId)
{
    NTSTATUS status;
    status = STATUS_SUCCESS;
    //当此进程为要保护的进程时
    if (ClientId->UniqueProcess == (HANDLE)g_Pid)
    {
        //设为拒绝访问
        DesiredAccess = 0;
    }
    return NtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}

g_Pid定义为全局的,我们想保护哪个进程就将该进程的pid赋值给g_Pid。

比如这里就保护Dbgview.exe。

r0下的进程保护

 

这里函数准备好以后,就要将该函数的指针覆盖原来NtOpenProcess的指针。但是需要注意的是:我们自己改自己的代码是不用管权限的,改别人的代码很有可能这块内存是只读的,并不可写。

那么本质上就是SSDT对应的物理页是只读的,这里有两种办法,我们都知道物理页的内存R/W位的属性是由PDE和PTE相与而来的,那么我们就可以改变SSDT对应的PDE和PTE的R/W属性,将物理页设置为可读可写的。通过CR4寄存器判断是2-9-9-12分页还是10-10-12分页。

if(RCR4 & 0x00000020)
{//说明是2-9-9-12分页
    KdPrint(("2-9-9-12分页 %pn",RCR4));
    KdPrint(("PTE1 %pn",*(Dword*)(0xC0000000 + ((HookFunAddr >> 9) & 0x007FFFF8))));
    *(DWORD64*)(0xC0000000 + ((HookFunAddr >> 9) & 0x007FFFF8)) |= 0x02; 
    KdPrint(("PTE1 %pn",*(DWORD*)(0xC0000000 + ((HookFunAddr >> 9) & 0x007FFFF8))));
}
else
{//说明是10-10-12分页
    KdPrint(("10-10-12分页n"));
    KdPrint(("PTE1 %pn",*(DWORD*)(0xC0000000 + ((HookFunAddr >> 10) & 0x003FFFFC))));
    *(DWORD*)(0xC0000000 + ((HookFunAddr >> 10) & 0x003FFFFC)) |= 0x02;
    KdPrint(("PTE2 %pn",*(DWORD*)(0xC0000000 + ((HookFunAddr >> 10) & 0x003FFFFC))));
}

还有一种方式就是通过Cr0寄存器。CR0寄存器的第16位叫做保护属性位,控制着页的读或写属性。

r0下的进程保护

 

WP为1 时, 不能修改只读的内存页 , WP为0 时, 可以修改只读的内存页。那么我们就可以将WP位置为0,暂时关闭可读属性。

VOID PageProtectOn()
{
    __try
    {
        _asm
        {
            mov eax, cr0
            or eax, 10000h
            mov cr0, eax
            sti
        }
    }
    __except (1)
    {
        DbgPrint("PageProtectOn执行失败!");
    }
}
VOID PageProtectOff()
{
    __try
    {
        _asm
        {
            cli
            mov eax, cr0
            and eax, not 10000h //and eax,0FFFEFFFFh
            mov cr0, eax
        }
    }
    __except (1)
    {
        DbgPrint("PageProtectOff执行失败!");
    }
}

可以修改SSDT表后,就要写函数来修改NtOpenProcess指针,也就是我们的HOOK函数。

NTSTATUS _hook()
{
    NTSTATUS status;
    status = STATUS_SUCCESS;
    PageProtectOff();

    PoldAddress = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x7a];
    KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x7a] = (ULONG)MyOpenProcess;

    PageProtectOn();
    return status;
}

在修改SSDT表前先关闭物理页保护,修改完后要开启物理页保护,保证其他任务能够顺利完成。这里的索引可以通过ida或者debug工具去看。

r0下的进程保护

 

然后就是卸载钩子,用于驱动卸载的时候使用。

NTSTATUS _unhook()
{
    NTSTATUS status;
    status = STATUS_SUCCESS;
    PageProtectOff();
    KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x7a] = PoldAddress;
    PageProtectOn();
    return status;
}

最后是入口和卸载函数

VOID DriverUnload(PDRIVER_OBJECT driver)
{
    _unhook();
    DbgPrint("卸载了。。。。。n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
    _hook();
    DbgPrint("跑起来了。。。n");

    driver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}

最后编译,加载驱动,当我们尝试用任务管理器杀死Dbgview时会被拒绝。

r0下的进程保护

 

如果通过taskkill同样不行。

r0下的进程保护

 

后记

在SSDT上写钩子,在0环是最低级的方式,可以看到编写代码十分简单,但是也是非常容易被检测的,比如我们通过PChunter这样的内核工具去看一下。

r0下的进程保护

 

可以看到NtOpenProcess赫然在列。实际上SSDT已作为基础需要被了解。

本文由SD原创发布
转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/262577
安全客 - 有思想的安全新媒体



Tags:进程   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
前言进程保护是众多AV或者病毒都要所具备的基础功能,本文就0环下通过SSDT来对进程进行保护进行探究,SSDT也不是什么新技术,但作为学习,老的技术我们同样需要掌握。什么是SSDTSS...【详细内容】
2021-12-30  Tags: 进程  点击:(0)  评论:(0)  加入收藏
一般的docker镜像为了节省空间,通常是没有安装systemd或者sysvint这类初始化系统的进程。一旦容器的起始进程不稳定将会产生大量的僵尸进程,影响宿主系统的运行。 缺少init的...【详细内容】
2021-12-23  Tags: 进程  点击:(9)  评论:(0)  加入收藏
在使用Linux的时候,进程管理是必须要掌握的技能,下面从几个方面介绍下进程管理相关知识点。进程分类 前台进程:该程序运行行,就占据了命令提示符; 后台进程:启动之后,释放命令提示...【详细内容】
2021-12-07  Tags: 进程  点击:(26)  评论:(0)  加入收藏
Linux下查看某一个进程所占用的内存,首先可以通过ps命令找到进程id,比如ps -ef | grep kafka ,可以看到kafka这个程序的进程id 可以看到是2913,现在可以使用如下命令查看内存:top...【详细内容】
2021-12-07  Tags: 进程  点击:(38)  评论:(0)  加入收藏
相关概念 并发和并行 并发:指一个时间段内,在一个CPU(CPU核心)能运行的程序的数量。 并行:指在同一时刻,在多个CPU上运行多个程序,跟CPU(CPU核心)数量有关。因为计算机CPU(CPU核心)在同...【详细内容】
2021-11-30  Tags: 进程  点击:(19)  评论:(0)  加入收藏
Jarboot本身是一个启动Java进程的工具,同时它还附带了一些调试命令。本文介绍下当Java的服务占用了过高的CPU资源时,该如何进行排查。如果不借助工具,使用Linux和jdk自带命令的...【详细内容】
2021-08-20  Tags: 进程  点击:(153)  评论:(0)  加入收藏
姐妹们,带娃出门一定都干过这事儿。看到和自家孩子年龄相仿的娃,一定会聊(bi)上(jiao)几(一)句(fan)。“哇,你们家才五个月就会坐了,还挺稳的,我们这个才刚会翻身。”“我家这个10个月了...【详细内容】
2021-08-18  Tags: 进程  点击:(65)  评论:(0)  加入收藏
Linux进程通信实现机制有很多,也有各自优缺点和适用场景,关于它们之间的对比,等各种通信机制一一介绍后,再来一个汇总,俗话说“没有对比就没有伤害”,通过“伤害”让大家彻底了解...【详细内容】
2021-08-13  Tags: 进程  点击:(62)  评论:(0)  加入收藏
netsh http show servicestate 找到进程ID,任务管理器停止相关服务昨天刚更新了Windows10,总体上来说效果还是蛮不错的,然而今天在开启Apache服务器的时候却发现,Apache莫名其妙...【详细内容】
2021-08-02  Tags: 进程  点击:(123)  评论:(0)  加入收藏
进程的分类在 CPU 的角度看进程行为的话,可以分为两类: CPU 消耗型:此类进程就是一直占用 CPU 计算,CPU 利用率很高 IO 消耗型:此类进程会涉及到 IO,需要和用户交互,比如键盘输入,占...【详细内容】
2021-07-13  Tags: 进程  点击:(91)  评论:(0)  加入收藏
▌简易百科推荐
前言进程保护是众多AV或者病毒都要所具备的基础功能,本文就0环下通过SSDT来对进程进行保护进行探究,SSDT也不是什么新技术,但作为学习,老的技术我们同样需要掌握。什么是SSDTSS...【详细内容】
2021-12-30  安全客小安    Tags:进程   点击:(0)  评论:(0)  加入收藏
众所周知,Windows系统流氓软件众多,其中不乏出身大厂的产品。这些带有流氓性质的软件,很多都会偷偷扫描系统数据,读取用户文件,造成电脑卡顿拖慢不说,还严重侵害了个人隐私,造成巨...【详细内容】
2021-12-06  趣玩APPS    Tags:流氓软件   点击:(17)  评论:(0)  加入收藏
前言目标是一大学,在一次挖洞过程中遇到个sql注入,尝试进一步利用扩大危害,漏洞已报送平台进行了修复私信我获取网络安全学习资料 1.2000多本网络安全系列电子书 2.网络安全标...【详细内容】
2021-11-26  IT野涵    Tags:sql注入   点击:(29)  评论:(0)  加入收藏
互联网时代,不论是个人还是组织,都将数据视为一项重要的资产。为了便于存储、管理,企业常常会为各项数据建立一个数据库,如果没有做好安全风险防护,一旦数据库被攻占,企业将迎来很...【详细内容】
2021-10-28  快快网络   企鹅号  Tags:数据库   点击:(51)  评论:(0)  加入收藏
前言(可能思路狭隘,有缺有错,师傅们多带带)【查看资料】Author: 0ne本篇文章数据来源于18+省市级别HVV,90+单位失陷报告。(一部分是笔者的参与,一部分是薅的公司其他师傅的报告...【详细内容】
2021-10-28  IT野涵    Tags:缺口   点击:(47)  评论:(0)  加入收藏
本人也是小白一枚,大佬请绕过,这个其实是六月份的时候做的,那时候想多点实战经验,就直接用谷歌搜索找了一些网站,这个是其中一个1、目标网站 2、发现有WAF防护 3、判断存在注入...【详细内容】
2021-10-19    博客园  Tags:SQL注入   点击:(53)  评论:(0)  加入收藏
一 前言本文将针对开发过程中依旧经常出现的SQL编码缺陷,讲解其背后原理及形成原因。并以几个常见漏洞存在形式,提醒技术同学注意相关问题。最后会根据原理,提供解决或缓解方案...【详细内容】
2021-09-17  woaker    Tags:SQL注入漏洞   点击:(68)  评论:(0)  加入收藏
前言本人ctf选手一名,在最近做练习时遇到了一些sql注入的题目,但是sql注入一直是我的弱项之一,所以写一篇总结记录一下最近学到的一些sql注入漏洞的利用。可回显注入联合注入在...【详细内容】
2021-08-26  合天网安实验室    Tags:sql注入   点击:(61)  评论:(0)  加入收藏
“放纵自己的欲望是最大的祸害,窥探别人的隐私是最大的罪恶,不知自己的过失是最大的病痛”。 上文咱们知道了目前互联网的数据安全存在隐患,数据安全的问题,每天都在发生,只不过...【详细内容】
2021-08-13  小陶子矿工    Tags:IPFS   点击:(80)  评论:(0)  加入收藏
前言最近挖edusrc的时候遇到有注入点但是有waf绕不过,头疼。 可以看到还是phpstudy建站的,太熟悉了这个,不知道这个什么waf各位师傅知道的可以评论一下,所以写这篇文章是供各位...【详细内容】
2021-08-13  IT影子    Tags:sql注入   点击:(67)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条