内核层注入的N种方法

内核注入 ,技术古老但很实用。现在部分RK趋向无进程,玩的是 SYS+DLL ,有的无文件,全部存在于内存中。可能有部分人会说:“都进内核了.什么不能干?”。是啊,要是内核中可以做包括R3上所有能做的事,软件开发商们也没必要做应用程序了。有时,我们确实需要R3程序去干驱动做起来很困难或者没必要驱动中去做的事,进程 /  DLL是不错的选择,但进程目标太大,所以更多的同学趋向于注DLL。 
    若要开发安全软件、小型工具,可借鉴其思路,Anti Rootkits时,在某些极端情况下,可使用同样的技术发现、清除RK,保证用户电脑的正常使用。在此,我将探讨几种内核注入DLL的思路及实现原理。 
(1) APC技术  
    给一个Alertbale的用户态线程插APC,让其执行其中的ShellCode,来执行我们的代码。这个方法简单易行,但是不够稳定,兼容性不好。测试中发现经常出现Explorer.exe等插崩溃的情况,而且有杀软在的情况下,插入有时会被拦截,起不到应有的效果。(可参考我以前逆过的一个驱动: 逆向fuck.sys--编译通过--源码
(2) 内核Patch  [url=file://KnownDLLs/Kernel32.dll]//KnownDLLs//Kernel32.dll[/url] CreateThread  
    [url=file://KnownDLLs/] //KnownDLLs [/url]是系统加载时对象管理器加载最新磁盘DLL到内存的,当其他进程想调用某个DLL时,就不用重复从磁盘加载了,而会从这里映射一份到自己的进程空间中去。这样给我们做全局Patch提供了一个很好的机会: 
        ZwOpenSection打开 [url=file://KnownDlls/kernel32.dll] //KnownDlls//kernel32.dll [/url],调用ZwMapViewOfSection映射一份到自己进程空间,然后寻找kernel32.dll在内存中代码节的空隙,选择这里作为我们fake函数的存储Buffer。修改CreateThread函数的开头5字节跳转到这个间隙,当系统任何一个线程创建时,会走到CreateThread函数,然后执行空隙中的ShellCode,其负责调用LoadLibrary加载我们的DLL。DLL一经加载,会发IOCTL通知本驱动,让驱动卸载HOOK。这样就完成了内核注DLL的过程。测试时发现 Svchost.exe 进程调用CreateThread函数很频繁,所以触发也会很快,基本1秒不到就能将DLL加载进去,而我们的HOOK也卸掉了。所以稳定性提高不少。示意图如下: 
 
(3) 内核 HOOK ZwMapViewOfSection  
    有部分模块加载时会调用 ZwMapViewOfSection ,比如进程创建时映射N份DLL到自己的虚拟空间中去.我们替换SSDT中的这个函数,过滤出是加载 Kernel32.dll 的情况,从参数中取得其基址,Inline Hook其EAT中的 CreateThread 函数,跳转到在这个进程虚拟地址空间中申请的Buffer,在其中完成DLL的加载过程. 
关键API: 
ZwAllocateVirtualMemory  ---- 在此进程空间中分配内存,存放Shellcode 
ZwProtectVirtualMemory  ---- 使当前内存块具有可读可写属性 
IoAllocateMdl  ---- 创建MDL 
关键Code如下: 
 
 
    同方法2相比,原理类似。但修改时机不同,效果差不多,只是注入DLL的时间会慢一些。至于Shellcode的编写,就大同小异了.萝卜白菜各有所爱,主要看个人发挥。要是闲写shellcode麻烦,请到看雪学院去查资料,模板很多,在这里就不YY了。 
【看雪读书月】学习ShellCode编写  
[note]一个简单的Shellcode  
shellcode之小小琢磨  
Add_Section  
(4)  内核 HOOK 
NtCreateThread
 
    跟踪 进程创建的流程 ,会很明晰的发现有多点可以patch来实现DLL的注入。 
    进程创建完时是一个 空水壶 ,里面没有沸腾的热水(threads),于是系统调用NtCreateThread创建其主线程(给空水壶注水 –  凉水 ),在这个暂停的线程里面折腾了一阵后完事了也厌倦了,于是系统跳了出来,回到进程空间中,调用Kernel32.dll去通知CSRSS.EXE,对它说:“这里有一个新进程出生了,你在你的表里标记一下”。然后就开始加载DLL啦,把系统KnownDLLs中的自己需要的DLL都Map一份到这个大水壶中。接着KiThreadStartup加热水壶中的凉水,于是水就开始 沸腾 了,此时主线程开始工作。。。 
    拦截NtCreateThread,取得 当前线程上下文 ,保存它要返回的地址(会回到空水壶中去),劫持为我们自己分配的地址,在其中填充ShellCode来加载目的DLL。至于选择Buffer,思路很多。这里可简单的Attach到当前进程,在充足的虚拟2GB进程地址空间中分配属于你自己的一块小内存,够放ShellCode足矣。示意图如下: 
 
(5)  内核感染常用模块,让感染模块帮我们Load DLL  
    这个方法就有点绕远了,开始了最本质最原始的感染,可增加新节,可插空隙,总之,让别人的模块Load进内存时顺路的帮我们加载下DLL,DLL一旦加载就可以恢复感染,清除痕迹。至于感染代码,网上一堆。只要不是驱动感染驱动(多了个校验和),其他性质都一样,看自己发挥啦。 
(6) 拦截NtCreateUserProcess、NtCreateSymbolicLinkObject  
    前者在Vista下才有. 拦截后通过 PsLookupProcessThreadByCid 得到ETHREAD / EPROCESS,判断是否是 CSRSS.EXE 引起的,若是则在此进程空间内分配一块内存,调用 NtGetContextThread 得到当前的线程上下文,调用ZwWriteVirtualMemory填充Shellcode区域,取得 LdrUnloadDll LdrGetDllHandle 等函数地址,通过他们加载DLL。然后调用 NtSetContextThread 恢复原始的Context。关于这种方法,可参考DriverDevelop上某人发的BIN。 
[” 内核实现DLL注入.可以完美绕过KAV瑞星等杀毒软件 ”] 
(7) 内核拦截NtResumeThread  
(8)NtUserSetWindowsHookEx 注入  
顺便提下R3上DLL的注入: 
1. CreateRemoteThread  (or  NtCreateThreadEx  (Used in Vista)) 
  2. SetThreadContext  (change the EIP) 
  3. NtQueueAPCThread  
  4. RtlCreateUserThread  
  5.  SetWindowHookEx  
小结:  
    纵观进程启动的全过程,可patch的地方很多,只要保证进程、线程上下文不被破坏,注入的手法可多种多样。只要保证我们的DLL注入时间足够短,稳定性足够高即可。当我们迫不得已要从内核注入DLL到用户进程去时,系统已经中毒很深,此时运用类似上面提到的技术来加载DLL,让DLL做我们驱动无法完成的任务,是可以接受的。 
    上面提到的思路是我暂时想到并且已经实现了的,详细过程可参见代码。欢迎积极探讨更好更稳定而且 不邪恶 的方法。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows APC(Asynchronous Procedure Call)注入是一常见的注入技术,它利用了 Windows 操作系统中的异步过程调用机制来实现注入。具体原理如下: 1. 创建目标进程 首先,攻击者需要创建一个目标进程,该进程将作为注入目标。一般情况下,攻击者会选择一个易受攻击的进程,例如 Windows Explorer。 2. 分配内存空间 攻击者需要在目标进程中分配一块内存空间,用于存放要注入的代码。可以使用 VirtualAllocEx 等函数来实现。 3. 编写注入代码 接下来,攻击者需要编写注入代码,并将其写入到之前分配的内存空间中。注入代码通常是一个 DLL 文件,其中包含了攻击者想要执行的恶意代码。同时,在注入代码中还需要将恶意代码的入口点指向一个 APC 回调函数。 4. 调用 QueueUserAPC 函数 接下来,攻击者需要在目标进程中的某个线程上调用 QueueUserAPC 函数,并将之前分配的内存空间中的 APC 回调函数作为参数。这样,当目标进程的线程下一次进入 Alertable 状态时,它将执行注入代码中的 APC 回调函数。 5. 触发注入 最后,攻击者需要触发目标进程中的线程进入 Alertable 状态。可以使用 Sleep、WaitForSingleObject 等函数来实现。 总之,APC 注入技术是一高级的注入技术,攻击者可以通过它将恶意代码注入到目标进程中,并在其中执行。然而,这技术也有一定的局限性,例如无法注入到特权级较高的进程中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值