当前位置:首页 > 数码 > Hook原理及思绪-绕过用户形式EDR (frida hook原理)

Hook原理及思绪-绕过用户形式EDR (frida hook原理)

admin8个月前 (04-24)数码44

1.什么是系统调用

系统调用是从用户形式过渡到内核形式的规范方式。它们是现代版的软件终止,速度更快。

系统调用接口极端复杂,但由于大局部内容与咱们的上班有关,我只想做一个较上档次的总结。在大少数状况下,你并不须要深化了解它是如何上班的,就可以经常使用这些技术,但了解一下还是有协助的。

在中,内核有一张准许从用户形式调用的函数表。这些函数有时被称为系统服务、本地函数或Nt函数。它们是以Nt或Zw扫尾的函数,位于ntoskrnl.exe中。系统服务表称为系统服务形容符表,简称SSDT。

要从用户形式调用系统服务,必定口头系统调用,经过syscall指令成功。运行程序将系统服务ID保管在eax寄存器中,以此通知内核要调用哪个系统服务。系统服务ID(通常称为系统服务号、系统调用号或简称SSN)是该函数在SSDT中的索引项。因此,将eax设置为0将调用SSDT中的第一个函数,1将调用第二个函数,2将调用第三个函数,依此类推...

查问结果如下:entry=nt!KiServiceTable+(SSN*4)。

syscall指令会使CPU切换到内核形式并调用系统调用途理程序,该程序会从eax寄存器中失掉SSN并调用相应的SSDT函数。

假定一个运行程序调用kernel32.dll中的OpenProcess()函数来关上一个进程的句柄。

图片

正如你所看到的,该函数的真正作用是调用位于ntdll.dll中的NtOpenProcess()。如今,让咱们来看看NtOpenProcess()的逻辑。

图片

在NtOpenProcess()中,简直没有任何代码。这是由于与一切以Nt或Zw扫尾的函数一样,NtOpenProcess()实践上位于内核中。这些函数的ntdll(用户形式)版本只是口头系统调用来调用其内核形式对应函数,这就是为什么它们经常被称为系统调用存根。

在咱们的例子中,NtOpenProcess的SSN是0x26,但这个数字会随着Windows版本的变动而变动,所以不要指望它对你来说也是一样的。从简化的上层视图来看,调用流程大抵如下:

图片

上方是关于x86系统调用流程的更具体概述:

图片

留意:在用户形式下,函数的Nt和Zw版本齐全相反。在内核形式下,Zw函数的运转门路略有不同。这是由于Nt函数是为从用户形式调用而设计的,因此要对函数参数启动更宽泛的验证。

2.EDR和用户形式钩子

自2005年微软推出内核补丁包全(又称PatchGuard)以来,许多对内核的修正如今都被阻止了。以前,安保产品经过挂钩SSDT从内核外部监控用户形式调用。由于一切Nt/Zw配置都是在内核中成功的,因此一切用户形式调用都必定经过SSDT,并因此遭到SSDT挂钩的影响。补丁防护使SSDT钩子成为禁区,因此许多EDR钩子转向挂钩ntdll。

图片

由于SSDT存在于内核中,因此用户形式运行程序不可在不加载内核驱动程序的状况下搅扰这些钩子。如今,钩子被搁置在用户形式下,与运行程序并存。

那么,用户形式钩子是什么样的呢?

图片

要挂接ntdll.dll中的函数,大少数EDR只有用jmp指令笼罩函数代码的前5个字节。jmp指令会将代码口头重定向到EDR自身DLL(会智能加载到每个进程中)中的某些代码。CPU被重定向到EDR的DLL后,EDR可以经过审核函数参数和前往地址来口头安保审核。一旦EDR成功审核,它就可以经过口头笼罩指令复原ntdll调用,而后跳转到钩子(jmp指令)之后的ntdll位置。

图片

在上例中,NtWriteFile被挂钩。绿色指令是NtWriteFile的原始指令。NtWriteFile的前3条指令已被EDR的钩子(将口头重定向到edr.dll中名为NtWriteFile的函数的jmp)笼罩。每当EDR想要调用真正的NtWriteFile时,它会口头3条被笼罩的指令,而后跳转到挂钩函数的第4条指令,成功系统调用。

虽然不同厂商的EDR挂钩或许略有不同,但原理依然相反,而且都有一个独特的弱点:它们都位于用户形式下。由于钩子和EDR的DLL都必定放在每个进程的地址空间内,因此恶意进程可以窜改它们。

3.绕过EDR钩子

绕过EDR钩子的方法有很多,我只引见关键的几种。

卸载EDR钩子

由于挂钩的ntdll位于咱们自己进程的内存中,因此咱们可以经常使用VirtualProtect()使内存可写,而后用原始函数代码笼罩EDR的jmp指令。为了交流钩子,咱们当然须要知道原来的汇编指令是什么。最经常出现的方法是从磁盘读取ntdll.dll文件,而后将内存版本与磁盘版本启动比拟。前提是EDR不会检测或阻止从磁盘手动读取ntdll.dll。

这种方法的关键缺陷是,EDR可以活期审核ntdll的内存,检查其钩子能否已被删除。假设EDR检测到其钩子已被移除,它或许会将钩子写回,更有甚者会终止进程并触发检测事情。虽然钩子或许须要放在用户形式下,但审核钩子可以在内核形式下启动,因此咱们也没有什么方法来防止这种状况出现。

手动映射DLL

与其从磁盘中读取ntdll的污浊拷贝来解锁原始ntdll,咱们还不如直接将污浊拷贝加载到进程内存中,而后经常使用它来替代原始ntdll。由于LoadLibrary()和LdrLoadDll()等函数不准许系统两次加载同一个DLL,所以咱们必定手动加载。手动映射DLL的代码或许会很冗杂,而且容易出错或被检测到。

DLL通常也会调用其余DLL,因此咱们要么只能经常使用手动加载的ntdll中的函数,要么为咱们须要的每个DLL加载第二个正本,并修补它们,使其只能经常使用其余手动加载的DLL,这或许会变得十分凌乱。假设杀毒软件在启动内存扫描时,发现每个DLL都有多个正本加载到内存中,那么也很有或许被发现。

直接系统调用

正如前面探讨的那样,用户形式下的Nt/Zw函数实践上除了口头系统调用之外并不口头其余任何操作。因此,咱们实践上不须要映射整个新的ntdll正原本口头一些系统调用。相反,咱们可以直接将系统调用逻辑成功到咱们自己的代码中。咱们只有将要调用的函数的SSN(函数号)移动到eax寄存器中,而后口头syscall指令。

__asm{movr10,rcxmoveax,0x123syscallret}

可怜的是,由于EDR的钩子通常会笼罩设置eax寄存器的指令,咱们不能便捷地从被挂钩的函数中提取它。但是...有一些方法咱们可以找出它是什么。

从ntdll读取一个洁净的拷贝

你或许曾经对这个想法感到厌倦了,但咱们可以从磁盘上读取一个洁净的ntdll正本,而后从中提取SSN。由于SSN一直被放入eax寄存器,咱们只有扫描咱们想要调用的函数以找到"moveax,imm32"指令即可。但是,假设咱们想要一种不只仅是从磁盘读取ntdll的变体呢?别担忧!

依据函数顺序计算系统调用号

系统调用ID是索引,因此是顺序的。假设咱们想要调用的函数的SSN是0x18,那么直接在它之前的或许是0x17,直接在它之后的或许是0x19。由于EDR并不挂钩每个Nt函数,咱们可以便捷地从最近的未被挂钩的函数中失掉SSN,而后经过减少或减去在它和咱们目的函数之间有多少个函数来计算咱们想要的函数的SSN。

图片

这种方法确实有一个缺陷:咱们不可百分之百地保障系统调用号将永远坚持延续,或许DLL不会跳过一些。

硬编码

最便捷的方法就是直接硬编码系统调用号。虽然它们在不同版本之间会有所扭转,但在过去它们的变动并不是很大。检测操作系统版本并加载正确的SSN集并不是太难的上班。理想上,j00ru友好地颁布了每个Windows版本的每个系统调用号的列表。这种方法惟一的缺陷是,假设系统调用号出现变动,代码或许在新的Windows版本上不可智能运转。

直接系统调用的疑问

在过去的十多年里,直接系统调用不时是绕过用户形式钩子的首选方法。实践上,我自己在2012年首次尝试了这种方法。可怜的是,为了防止这种绕过方式,曾经启动了很多上班。最经常出现的检测方法是让EDR的内核形式驱动程序审核调用堆栈。

EDR

虽然EDR不能再在内核中挂钩很多中央,但它可以应用操作系统提供的监督配置,比如:

假设咱们行入手动系统调用,而在调用的内核函数经过以上马何一种状况时,EDR可以应用时机审核咱们线程的调用堆栈。经过开展调用堆栈并审核前往地址,EDR可以看到造成此系统调用的整个函数调用链。

假设咱们口头对kernel32!VirtualAlloc()的反常调用,调用堆栈或许如下所示:

图片

在这种状况下,对VirtualAlloc()的调用是由ManualSyscall!mn+0x53启动的。依照调用的顺序,调用堆栈的关系局部如下:

这通知咱们(或许EDR)可口头文件(ManualSyscall.exe)调用了VirtualAlloc(),这个函数调用了NtAllocateVirtualMemory(),而后口头了一个系统调用以切换到内核形式。

如今让咱们看看启动直接系统调用时的调用堆栈:

图片

调用堆栈的关系局部按顺序如下:

在这里,很显著内核转换是由ManualSyscall.exe外部的代码触发的,而不是ntdll。但是,这有什么疑问吗?

嗯,在像这样的系统上,运行程序直接动员系统调用是齐全反常的。但请记住我提到过Windows版本之间系统调用号会出现变动吗?结果,编写依赖于直接系统调用的Windows软件是十分不实际践的。由于ntdll曾经为您成功了每个系统调用,简直没有理由启入手动系统调用。除非你正在编写绕过EDR钩子的恶意软件。你是在写用于绕过EDR钩子的恶意软件吗?

由于直接系统调用是恶意优惠的强有力目的,更复杂的EDR系统将记载源自于ntdll之外的系统调用的检测状况。说瞎话,你依然可以在很多时刻逃脱检测,但这有什么乐趣呢?

4.直接系统调用

大少数EDR在Nt函数的扫尾写入它们的钩子,笼罩SSN但保管系统调用指令不变。这使咱们能够应用ntdll曾经提供的系统调用指令,而不是引入咱们自己的。咱们只有自己设置r10和eax寄存器,而后跳转到被挂钩的ntdll函数内的系统调用指令(位于EDR钩子之后)。

图片

留意:咱们并不严厉须要test或jnz指令,它们只是为了向后兼容。一些新鲜的CPU不支持syscall指令,而是经常使用int0x2e。test指令审核系统调用能否启用,假设没有启用,则回退到软终止。假设咱们宿愿支持这些系统,咱们可以自己口头审核,而后依据须要跳转到int0x2e指令(也位于Nt函数内)。

就像直接系统调用一样,咱们依然须要系统调用号放入eax寄存器,但咱们可以经常使用在直接系统调用局部具体引见的一切相反技术。

经过这种方式设置系统调用将给咱们一个相似以下的调用堆栈:

图片

正如你所看到的,调用堆栈如今看起来如同是来自ntdll!NtAllocateVirtualMemory()而不是咱们的可口头文件,由于从技术上讲确实是这样的。

咱们或许会遇到的一个疑问是,假设EDR钩子或笼罩了Nt调用中的syscall指令的局部。我从未见过这种状况出现,但实践上或许会出现。在这种状况下,咱们可以跳转到另一个未被挂钩的Nt函数内的syscall指令。这依然可以绕过仅验证调用称号能否来自ntdll的EDR,但关于审核内核函数能否与来自ntdll的函数相婚配的这种审核通常都会失败。

更大的疑问是,假设EDR审核的不只仅是第一个前往地址。不只仅是系统调用的起源,还有口头系统调用的函数是谁调用的。假设咱们正在从位于灵活调配内存中的某个shellcode启动直接系统调用,那么EDR将会发觉到。来自于有效PE节(exe或DLL内存)之外的调用是相当可疑的。

此外,由于函数被EDR挂钩,EDR的钩子预期会出如今调用堆栈中。实践上,我并不确定哪些EDR,假设有的话,会审核这一点。但是,正如你在这里看到的,从调用堆栈中很显著咱们绕过了EDR的钩子。

图片

理想状况下,咱们宿愿伪造的不只仅是系统调用的前往地址。对此的一个幽默处置打算是调用堆栈诈骗,我或许会在另一篇文章中具体引见。经常使用调用堆栈诈骗,可以伪造整个调用堆栈,但要坚持调用堆栈稳固不解体或许会遇到一些应战。


C:\windows\system32\hook.dll木马是什么

_是灰鸽子病毒~~~手工清除灰鸽子并不难,重要的是我们必须懂得它的运行原理。 灰鸽子的运行原理灰鸽子远程监控软件分两部分:客户端和服务端。 黑客(姑且这么称呼吧)操纵着客户端,利用客户端配置生成出一个服务端程序。 服务端文件的名字默认为G_,然后黑客通过各种渠道传播这个服务端(俗称种木马)。 种木马的手段有很多,比如,黑客可以将它与一张图片绑定,然后假冒成一个羞涩的MM通过QQ把木马传给你,诱骗你运行;也可以建立一个个人网页,诱骗你点击,利用IE漏洞把木马下载到你的机器上并运行;还可以将文件上传到某个软件下载站点,冒充成一个有趣的软件诱骗用户下载……,这正违背了我们开发灰鸽子的目的,所以本文适用于那些让人非法安装灰鸽子服务端的用户,帮助用户删除灰鸽子 Vip 2005 的服务端程序。 本文大部分内容摘自互联网。 如果你没有兴趣读下面的文章,请直接下载我们提供的清除器使用:点击这里下载G_运行后将自己拷贝到Windows目录下(98/xp下为系统盘的windows目录,2k/NT下为系统盘的Winnt目录),然后再从体内释放G_和G_Server_到windows目录下。 G_、G_和G_Server_三个文件相互配合组成了灰鸽子服务端,有些灰鸽子会多释放出一个名为G_的文件用来记录键盘操作。 注意,G_这个名称并不固定,它是可以定制的,比如当定制服务端文件名为时,生成的文件就是、和A_。 Windows目录下的G_文件将自己注册成服务(9X系统写注册表启动项),每次开机都能自动运行,运行后启动G_和G_Server_并自动退出。 G_文件实现后门功能,与控制端客户端进行通信;G_Server_则通过拦截API调用来隐藏病毒。 因此,中毒后,我们看不到病毒文件,也看不到病毒注册的服务项。 随着灰鸽子服务端文件的设置不同,G_Server_有时候附在的进程空间中,有时候则是附在所有进程中。 灰鸽子的手工检测由于灰鸽子拦截了API调用,在正常模式下服务端程序文件和它注册的服务项均被隐藏,也就是说你即使设置了“显示所有隐藏文件”也看不到它们。 此外,灰鸽子服务端的文件名也是可以自定义的,这都给手工检测带来了一定的困难。 但是,通过仔细观察我们发现,对于灰鸽子的检测仍然是有规律可循的。 从上面的运行原理分析可以看出,无论自定义的服务器端文件名是什么,一般都会在操作系统的安装目录下生成一个以“_”结尾的文件。 通过这一点,我们可以较为准确手工检测出灰鸽子 服务端。 由于正常模式下灰鸽子会隐藏自身,因此检测灰鸽子的操作一定要在安全模式下进行。 进入安全模式的方法是:启动计算机,在系统进入Windows启动画面前,按下F8键(或者在启动计算机时按住Ctrl键不放),在出现的启动选项菜单中,选择“Safe Mode”或“安全模式”。 1、由于灰鸽子的文件本身具有隐藏属性,因此要设置Windows显示所有文件。 打开“我的电脑”,选择菜单“工具”—》“文件夹选项”,点击“查看”,取消“隐藏受保护的操作系统文件”前的对勾,并在“隐藏文件和文件夹”项中选择“显示所有文件和文件夹”,然后点击“确定”。 2、打开Windows的“搜索文件”,文件名称输入“_”,搜索位置选择Windows的安装目录(默认98/xp为C:\windows,2k/NT为C:\Winnt)。 3、经过搜索,我们在Windows目录(不包含子目录)下发现了一个名为Game_的文件。 4、根据灰鸽子原理分析我们知道,如果Game_是灰鸽子的文件,则在操作系统安装目录下还会有和文件。 打开Windows目录,果然有这两个文件,同时还有一个用于记录键盘操作的文件。 经过这几步操作我们基本就可以确定这些文件是灰鸽子 服务端了,下面就可以进行手动清除。 灰鸽子的手工清除经过上面的分析,清除灰鸽子就很容易了。 清除灰鸽子仍然要在安全模式下操作,主要有两步:1、清除灰鸽子的服务;2删除灰鸽子程序文件。 注意:为防止误操作,清除前一定要做好备份。 一、清除灰鸽子的服务2000/XP系统:1、打开注册表编辑器(点击“开始”-》“运行”,输入“”,确定。 ),打开 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services注册表项。 2、点击菜单“编辑”-》“查找”,“查找目标”输入“”,点击确定,我们就可以找到灰鸽子的服务项(此例为Game_Server)。 3、删除整个Game_Server项。 98/me系统:在9X下,灰鸽子启动项只有一个,因此清除更为简单。 运行注册表编辑器,打开HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run项,我们立即看到名为的一项,将项删除即可。 二、删除灰鸽子程序文件删除灰鸽子程序文件非常简单,只需要在安全模式下删除Windows目录下的、、Game_以及文件,然后重新启动计算机。 至此,灰鸽子VIP 2005 服务端已经被清除干净。

如何利用APIHook实现IE的重定向

让我们先来了解一下用户/搜索引擎和网站一开始的交互流程。 当用户或搜索引擎向一个网站服务器发出网页浏览请求时,该服务器将:1.通过域名服务器(DNS)将域名转换为网站的IP地址,然后返回给客户2.打开一个该IP套接口连接3.记下通过该套接口的一个HTTP数据流4.从WEB服务器接收一个响应请求的HTTP数据流。 该数据流包含状态码,状态码的值由HTTP协议所决定。 这里所说的“HTTP数据流”信息也叫“头信息(Header)”。 头信息中包括了日期,服务器类型,通常还会有一条“200 OK”信息。 如果一切良好,那么网络服务器就会将“200 OK”信息以及请求页面发送出去。 如果网站在这时候已经建立了重定向,那么服务器就会在头信息中包含一个“302 Moved Temporarily”或“301 Moved Permanent”之类的响应信息。 搜索引擎会根据服务器头信息中的内容作出决定。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: EDRHook