首先解释下标题,为什么说是觉醒呢,因为逆向需要200%的集中力,而且中途不能中断,否则思路一断就全盘崩溃。
这个注入是我阅读无数代码中,见过比较骚气的实现。这个作者有一定功力,大家拿到代码可以赏析一下,哈哈。
一般我们在驱动中做注入的时候无外乎是找一个时机,完成诸如下面的操作:
1. HOOK ntdll导出函数,甚至未导出函数
2. 申请ShellCode,填写必要的函数地址,路径,UNICODE_STRING结构
3. 修改导入表/ShimEngine(sdb)等等
基本上也就一次执行机会,而且因为用到的函数由于模块基址不固定,多数只用ntdll这个固定模块基址的模块里面的函数,或者自己实现一些基本的函数查找,获取模块基地址这类的基本功能。那么下面看看这个模块如何分段进行资源的填充。
APC的ShellCode很简单,x86/x64用到的也仅仅只有ntdll!LdrLoadDll,从节表位置来看,x86肯定用的是硬编码的静态变量,x64是嵌在代码段里的。
熟悉APC的人大多都知道,apc在插入后是可以被立即触发的,因为微软的一些API就是干这些事情的,比如:
细看反汇编代码,真的是漏洞百出,实在不忍心吐槽了,反正需要改的地方我能帮他改的都改了。。
不知道你们有没有升级到Win10 RS4
正式版,这个Device Guard跟vmware冲突,搞死我了,还好看了vmware官网的解决办法关了DeviceGuard。
所以必须先有觉悟,进入觉醒状态,方可持续战斗,突破一切艰难险阻。。。
本篇选择的是HW(一个云桌面,具体我也不知道干什么的)软件的一个驱动模块,做注入用的。刚开始小瞧了一下,这个模块主要是64位的APC注入
我之前发过一个x86的,x64虽然也有干货但是因为一些限制因素没办法放出来,这个在手痒的时候用来练练手,历时1天左右,资源在最下方,有写的不好的地方还请指出来。
x86:
.rdata:0000000180004570 55 push rbp
.rdata:0000000180004571 8B EC mov ebp, esp
.rdata:0000000180004573 51 push rcx
.rdata:0000000180004574 8B 4D 08 mov ecx, [rbp+8]
.rdata:0000000180004577 8D 45 FC lea eax, [rbp+var_4]
.rdata:000000018000457A 50 push rax
.rdata:000000018000457B 8B 45 0C mov eax, [rbp+0Ch]
.rdata:000000018000457E 33 D2 xor edx, edx
.rdata:0000000180004580 89 55 FC mov [rbp+var_4], edx
.rdata:0000000180004583 8D 04 C1 lea eax, [rcx+rax*8]
.rdata:0000000180004586 50 push rax
.rdata:0000000180004587 52 push rdx
.rdata:0000000180004588 52 push rdx
.rdata:0000000180004589 FF 91 20 08 00 00 call qword ptr [rcx+820h] ; ntdll!LdrLoadDll
.rdata:000000018000458F 8B E5 mov esp, ebp
.rdata:0000000180004591 5D pop rbp
.rdata:0000000180004592 C2 0C 00 retn 0Ch
x64:
.text:00000001800023AC 48 83 EC 28 sub rsp, 28h
.text:00000001800023B0 48 83 64 24 30 00 and [rsp+28h+arg_0], 0
.text:00000001800023B6 4C 63 C2 movsxd r8, edx
.text:00000001800023B9 48 8B C1 mov rax, rcx
.text:00000001800023BC 49 C1 E0 04 shl r8, 4
.text:00000001800023C0 4C 8D 4C 24 30 lea r9, [rsp+28h+arg_0]
.text:00000001800023C5 33 D2 xor edx, edx
.text:00000001800023C7 4C 03 C1 add r8, rcx
.text:00000001800023CA 33 C9 xor ecx, ecx
.text:00000001800023CC FF 90 40 08 00 00 call qword ptr [rax+840h] ; ntdll!LdrLoadDll
.text:00000001800023D2 48 83 C4 28 add rsp, 28h
.text:00000001800023D6 C3 retn
分阶段填充的显然不是ShellCode用到的资源,其实从代码细节上看也有,只不过都是一些UNICODE_STRING还有字符串的填充是分段的;
分阶段
主要是为了64位系统下的x86进程。WOW64的执行原理也有很多人解释过了,这里我着重说下: 从内核返回时一切都是从x64执行层开始(因为CPU在内核时是64位模式,到应用层要经过wow64的转化才能到x86模式的CPU)
因此x86进程其实也可以加载64位模块,但是必须要在CPU处于64模式时使用64位ntdll。但是就注入来说肯定是要在x86进程中注入32位模块,那么就必须到x86执行层去做这些事情。驱动无论何时往哪个进程中的哪个线程插入APC那都是64位模式的APC,所以这里需要做个中转。
调试过64位ntdll!KiUserApcDispatcher的都应该知道,32位模式的APC地址经过混淆计算,并通过wow64!wow64ApcRoutinue转化为x86执行层的APC。所以知道这个就可以直接在驱动中插入一个NormalRoutinue为 wow64!wow64ApcRoutinue 的64位模式APC,将x86 APC地址逆着混淆计算一遍,作为
wow64!
wow64ApcRoutinue 的NormalContext传入即可。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2018-6-16 20:24
被FaEry编辑
,原因: