首页
社区
课程
招聘
[原创]Windows注入篇之内核APC注入[高清有码]
发表于: 2017-3-18 16:36 30933

[原创]Windows注入篇之内核APC注入[高清有码]

2017-3-18 16:36
30933

0x01 进程启动过程简介

   最近正在研习毛德操那本《Windows内核情景分析》上卷,看的真是难受呀,菜鸟还是表示有压力...老大跟我说要先

过一遍然后再深入研究,慢慢啃吧。总之言归正传,在看的懂本文附源代码之前,先看看第五章 进程管理 这章吧。我这里简要概括下:

    ReactOS中描述的进程启动过程如下:

    1. CreateProcess打开文件创建出Section然后调用进入系统调用

    2. NtCreateProcess初始化进程资源(进程内存空间,句柄表,Peb,设备描述表等等),但是进程只是一个空壳需要线程作为其执行体,所以进程在初始化的时候必须为自己创建一个线程(即我们通常说的主线程)

    3. 主线程由KeInitThread函数进行初始化,并规定其受到调度时内核的启动点是PspUserThreadStartup

    4. PspUserThreadStartup为主线程的Ring3执行机会创造一些环境,进程需要加载动态链接库,这个函数是家喻户晓的ntdll!LdrInitializeThunk,ReactOS并不是将TrapFrame.EIP直接修改为ntdll!LdrInitializeThunk,而是采用UserApc的方式,在内核线程受到调度回到Ring3层时,此Apc得到执行机会。

    5. 一般的线程的Ring3层入口,ReactOS中描述是BaseProcessStartup(主线程)/BaseThreadStartup(非主线程),现在XP往后我们可能再也看不到这个函数了,现在我们更多看到的是ntdll!RtlUserThreadStart,这个函数同样也是修改TrapFrame.EIP的方式得到执行的,不幸的是,只要存在用户Apc那么BaseProcessStartup/BaseThreadStartup就不要想执行起来,由于每次内核返回Ring3的过程每次都会修改TrapFrame.EIP,修改为KiUserApcDispatch直到没有用户层Apc。

    6. APC描述:2E中断KiSystemService退出时KiSystemServiceExit会调用KiDeliverApc,这个函数检查当前线程体(KTHREAD)的两个Apc队列,KernelMode队列的与UserMode队列的。前者调用一个循环全给执行了,后者就有些麻烦,因为涉及到Ring0->Ring3->Ring0->Ring3...重复检查的过程(详细的LZ就不多bb了,大家可以看书学习...)


0x02 进程回调的限制

   1. Apc注入离不开系统回调,而Apc是线程相关的,那么就肯定要在回调中由线程Id去查找线程体(ETHREAD),我们看2000的进程回调与线程回调的调用位置,两者都是在PspCreateThread中得到执行的(进程在前线程在后):

    

2000在初始化线程的时候才会将EProcess.UniqueProcessId置为其句柄表的索引,后续线程创建时将不再通知进程回调。而这个时候PspCreateThread还未将当前线程体初始化完毕,特别的是EThread.GrantedAccess没被初始化,那么在进/线程中 不管是Ring3的OpenThread或者是Ring0的PsLookupThreadByThreadId都将Fail,这个算是微软的一个小bug,但是到Vista之后,也就是Win7~Win10都不存这个问题了。


    2. Win7及之后的系统版本动态库加载点ntdll!LdrInitializeThunk不再使用Apc的方式启动,而是直接将TrapFrame.EIP修改为ntdll!LdrInitializeThunk,这样UserMode Apc的执行机会就自然被延迟了,那么延迟到什么时候呢? (这是64位ntdll,不过跟32也没什么差别):

ntdll!LdrInitializeThunk会调入_LdrpInitialize,在加载完导入表的一系列模块依赖之后会调用ZwTestAlert,这个函数内核情景分析也有介绍,他会将当前线程的Apc队列的UserPending重新置位,让已存在队列里的UserMode Apc得到执行(就在此次系统调用返回用户层之后),Win7以及之后的UserApc不再像2000那样,UserApc执行时机有了明确的几个点,具体大家可以深入研究


0x03 XP~Win10 APC注入方案实现

   XP之前由于进程回调的限制,所以与Win7后续要分两种情况处理,看到某款安全软件的做法是采用A盾劫持KiFastCallEntry,在进程初始化加载动态链接库的过程会调用NtQuerySection询问系统模块,以这个点作为Apc注入时机,LZ只想说哪有那么麻烦,直接在模块回调通知exe加载时就可以了,而且又可以避免Apc插入到LdrInitializeThunk的UserApc之前,因为Image回调在通知exe加载的时候在这里:


b1c88c08 80644526 nt!PsCallImageNotifyRoutines+0x36 

b1c88d0c 805d0e6b nt!DbgkCreateThread+0xa2

b1c88d50 805470de nt!PspUserThreadStartup+0x9d

00000000 00000000 nt!KiThreadStartup+0x16


这里正好是待创建进程的主线程刚得到调度的时候,这里线程体什么的都已初始化完毕,可以无忧进行插入。

     Win7及之后由于没有那么多限制,可以直接在进程回调完成。


     LZ用Insert Kernel Apc再Insert User Apc的原因在于:

       1. 得到线程已经开始执行或者调度没多久的时机,这能服从先后的原则;

       2. 申请ShellCode时可以不用考虑EProcess的地址空间锁的问题,32一般不会遇到,64的LoadImage可是一调用Zw*VirtualMemory就GG;

       3. 避免XP或者XP之前的Apc插入过早,插到LdrInitializeThunk的UserApc之前,这样所有动态链接库都没有加载就直接LdrLoadDll 基本上必crash。


注:

    1. 测试用的动态库放入C:\下,导出AiQ3Helper001函数,自己附上调试信息可以看到结果撒

    2. 书写代码时基本上用的都是32/64兼容变量,没有做64位测试,如果有蓝屏现象可能也就几处小问题,大家可以自行修改哈

    3. 支持XP ~ Win10,win10(BuildNumber<=14393),不要在最新版本上测试,微软出了保护...



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 2
支持
分享
最新回复 (32)
雪    币: 3255
活跃值: (4404)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主图片挂了 win10(BuildNumber<=14393),不要在最新版本上测试,微软出了保护 另外这个保护指的是?
2017-3-18 17:00
0
雪    币: 3700
活跃值: (3817)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
学习学习。
2017-3-18 18:29
0
雪    币: 5039
活跃值: (2591)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
4

数字签名校验,没有MS数字签名模块的进不去

2017-3-20 08:46
0
雪    币: 2
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5

我来顶一个~~~~~猜猜我是谁

2017-3-20 14:28
0
雪    币: 5039
活跃值: (2591)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
6
流总 也忙里偷闲一把。
2017-3-20 15:50
0
雪    币: 17
活跃值: (308)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
360几亿的用户量在此,人家这么做,自然有它道理。
2017-3-23 09:29
0
雪    币: 5039
活跃值: (2591)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
8




叁毛

360几亿的用户量在此,人家这么做,自然有它道理。
2017-3-23 17:41
0
雪    币: 221
活跃值: (2256)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9

经测试Xp,win7 32位可以插入,win7 64位不能插入

2017-3-24 19:19
0
雪    币: 5039
活跃值: (2591)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
10
lhglhg 经测试Xp,win7 32位可以插入,win7 64位不能插入
64还有很多事的,64位进程/WOW64位进程,x64 ntdll/ WOW64 ntdll,LZ是为了给大家留一点学习空间
2017-3-24 20:31
0
雪    币: 221
活跃值: (2256)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
win7 64系统下,dll 和 EXE都是 32位 还要做啥事情?
2017-3-24 21:25
0
雪    币: 190
活跃值: (84)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
2017-3-25 01:31
0
雪    币: 9662
活跃值: (4588)
能力值: ( LV15,RANK:800 )
在线值:
发帖
回帖
粉丝
13
leeqwind [em_41]
2017-3-25 11:39
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
大神好牛逼。。。。。。
2017-3-26 21:33
0
雪    币: 7
活跃值: (185)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
15
shinemiser 大神好牛逼。。。。。。
哥 是你不
2017-3-30 09:31
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
哈哈。还是传统 的内核 NtCreateThread 稳定。
2017-3-30 14:12
0
雪    币: 12
活跃值: (767)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
收藏
2017-3-31 09:53
0
雪    币: 27
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
楼主快出第二版,介绍下64位系统下32位进程注入呀
2017-7-30 15:55
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
我最近也在看这本书,楼主加个好友  一起来学习下呗,
2017-7-30 17:29
0
雪    币: 1264
活跃值: (1850)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
apc正确执行wow64格式  ((LONG_PTR)pMappedAddress  *  (-4)),设置事件直接警醒执行shellcode,不用看了。
2017-10-27 18:35
0
雪    币: 6
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
FaEry 64还有很多事的,64位进程/WOW64位进程,x64 ntdll/ WOW64 ntdll,LZ是为了给大家留一点学习空间
64下apc注入会导致系统重启
2018-3-30 20:03
0
雪    币: 5039
活跃值: (2591)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
22
彪哥大大 64下apc注入会导致系统重启
老哥,你姿势不对,改天我给你们呈上~
2018-3-30 21:04
0
雪    币: 687
活跃值: (97)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
23
大佬膜拜,我学习一波
2018-3-30 22:27
0
雪    币: 41
活跃值: (86)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
24

最后于 2018-8-5 17:23 被Crimilals编辑 ,原因:
2018-8-5 17:16
0
雪    币: 310
活跃值: (2227)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
mark
2018-8-9 09:15
0
游客
登录 | 注册 方可回帖
返回
//